Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ a05c6409

History | View | Annotate | Download (274.3 kB)

1
/*
2
 *  Linux syscalls
3
 *
4
 *  Copyright (c) 2003 Fabrice Bellard
5
 *
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; either version 2 of the License, or
9
 *  (at your option) any later version.
10
 *
11
 *  This program is distributed in the hope that it will be useful,
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *  GNU General Public License for more details.
15
 *
16
 *  You should have received a copy of the GNU General Public License
17
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
18
 */
19
#define _ATFILE_SOURCE
20
#include <stdlib.h>
21
#include <stdio.h>
22
#include <stdarg.h>
23
#include <string.h>
24
#include <elf.h>
25
#include <endian.h>
26
#include <errno.h>
27
#include <unistd.h>
28
#include <fcntl.h>
29
#include <time.h>
30
#include <limits.h>
31
#include <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
static struct iovec *lock_iovec(int type, abi_ulong target_addr,
1748
                                int count, int copy)
1749
{
1750
    struct target_iovec *target_vec;
1751
    struct iovec *vec;
1752
    abi_ulong total_len, max_len;
1753
    int i;
1754

    
1755
    if (count == 0) {
1756
        errno = 0;
1757
        return NULL;
1758
    }
1759
    if (count > IOV_MAX) {
1760
        errno = EINVAL;
1761
        return NULL;
1762
    }
1763

    
1764
    vec = calloc(count, sizeof(struct iovec));
1765
    if (vec == NULL) {
1766
        errno = ENOMEM;
1767
        return NULL;
1768
    }
1769

    
1770
    target_vec = lock_user(VERIFY_READ, target_addr,
1771
                           count * sizeof(struct target_iovec), 1);
1772
    if (target_vec == NULL) {
1773
        errno = EFAULT;
1774
        goto fail2;
1775
    }
1776

    
1777
    /* ??? If host page size > target page size, this will result in a
1778
       value larger than what we can actually support.  */
1779
    max_len = 0x7fffffff & TARGET_PAGE_MASK;
1780
    total_len = 0;
1781

    
1782
    for (i = 0; i < count; i++) {
1783
        abi_ulong base = tswapal(target_vec[i].iov_base);
1784
        abi_long len = tswapal(target_vec[i].iov_len);
1785

    
1786
        if (len < 0) {
1787
            errno = EINVAL;
1788
            goto fail;
1789
        } else if (len == 0) {
1790
            /* Zero length pointer is ignored.  */
1791
            vec[i].iov_base = 0;
1792
        } else {
1793
            vec[i].iov_base = lock_user(type, base, len, copy);
1794
            if (!vec[i].iov_base) {
1795
                errno = EFAULT;
1796
                goto fail;
1797
            }
1798
            if (len > max_len - total_len) {
1799
                len = max_len - total_len;
1800
            }
1801
        }
1802
        vec[i].iov_len = len;
1803
        total_len += len;
1804
    }
1805

    
1806
    unlock_user(target_vec, target_addr, 0);
1807
    return vec;
1808

    
1809
 fail:
1810
    free(vec);
1811
 fail2:
1812
    unlock_user(target_vec, target_addr, 0);
1813
    return NULL;
1814
}
1815

    
1816
static void unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1817
                         int count, int copy)
1818
{
1819
    struct target_iovec *target_vec;
1820
    int i;
1821

    
1822
    target_vec = lock_user(VERIFY_READ, target_addr,
1823
                           count * sizeof(struct target_iovec), 1);
1824
    if (target_vec) {
1825
        for (i = 0; i < count; i++) {
1826
            abi_ulong base = tswapal(target_vec[i].iov_base);
1827
            abi_long len = tswapal(target_vec[i].iov_base);
1828
            if (len < 0) {
1829
                break;
1830
            }
1831
            unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1832
        }
1833
        unlock_user(target_vec, target_addr, 0);
1834
    }
1835

    
1836
    free(vec);
1837
}
1838

    
1839
/* do_socket() Must return target values and target errnos. */
1840
static abi_long do_socket(int domain, int type, int protocol)
1841
{
1842
#if defined(TARGET_MIPS)
1843
    switch(type) {
1844
    case TARGET_SOCK_DGRAM:
1845
        type = SOCK_DGRAM;
1846
        break;
1847
    case TARGET_SOCK_STREAM:
1848
        type = SOCK_STREAM;
1849
        break;
1850
    case TARGET_SOCK_RAW:
1851
        type = SOCK_RAW;
1852
        break;
1853
    case TARGET_SOCK_RDM:
1854
        type = SOCK_RDM;
1855
        break;
1856
    case TARGET_SOCK_SEQPACKET:
1857
        type = SOCK_SEQPACKET;
1858
        break;
1859
    case TARGET_SOCK_PACKET:
1860
        type = SOCK_PACKET;
1861
        break;
1862
    }
1863
#endif
1864
    if (domain == PF_NETLINK)
1865
        return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1866
    return get_errno(socket(domain, type, protocol));
1867
}
1868

    
1869
/* do_bind() Must return target values and target errnos. */
1870
static abi_long do_bind(int sockfd, abi_ulong target_addr,
1871
                        socklen_t addrlen)
1872
{
1873
    void *addr;
1874
    abi_long ret;
1875

    
1876
    if ((int)addrlen < 0) {
1877
        return -TARGET_EINVAL;
1878
    }
1879

    
1880
    addr = alloca(addrlen+1);
1881

    
1882
    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1883
    if (ret)
1884
        return ret;
1885

    
1886
    return get_errno(bind(sockfd, addr, addrlen));
1887
}
1888

    
1889
/* do_connect() Must return target values and target errnos. */
1890
static abi_long do_connect(int sockfd, abi_ulong target_addr,
1891
                           socklen_t addrlen)
1892
{
1893
    void *addr;
1894
    abi_long ret;
1895

    
1896
    if ((int)addrlen < 0) {
1897
        return -TARGET_EINVAL;
1898
    }
1899

    
1900
    addr = alloca(addrlen);
1901

    
1902
    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1903
    if (ret)
1904
        return ret;
1905

    
1906
    return get_errno(connect(sockfd, addr, addrlen));
1907
}
1908

    
1909
/* do_sendrecvmsg() Must return target values and target errnos. */
1910
static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1911
                               int flags, int send)
1912
{
1913
    abi_long ret, len;
1914
    struct target_msghdr *msgp;
1915
    struct msghdr msg;
1916
    int count;
1917
    struct iovec *vec;
1918
    abi_ulong target_vec;
1919

    
1920
    /* FIXME */
1921
    if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1922
                          msgp,
1923
                          target_msg,
1924
                          send ? 1 : 0))
1925
        return -TARGET_EFAULT;
1926
    if (msgp->msg_name) {
1927
        msg.msg_namelen = tswap32(msgp->msg_namelen);
1928
        msg.msg_name = alloca(msg.msg_namelen);
1929
        ret = target_to_host_sockaddr(msg.msg_name, tswapal(msgp->msg_name),
1930
                                msg.msg_namelen);
1931
        if (ret) {
1932
            goto out2;
1933
        }
1934
    } else {
1935
        msg.msg_name = NULL;
1936
        msg.msg_namelen = 0;
1937
    }
1938
    msg.msg_controllen = 2 * tswapal(msgp->msg_controllen);
1939
    msg.msg_control = alloca(msg.msg_controllen);
1940
    msg.msg_flags = tswap32(msgp->msg_flags);
1941

    
1942
    count = tswapal(msgp->msg_iovlen);
1943
    target_vec = tswapal(msgp->msg_iov);
1944
    vec = lock_iovec(send ? VERIFY_READ : VERIFY_WRITE,
1945
                     target_vec, count, send);
1946
    if (vec == NULL) {
1947
        ret = -host_to_target_errno(errno);
1948
        goto out2;
1949
    }
1950
    msg.msg_iovlen = count;
1951
    msg.msg_iov = vec;
1952

    
1953
    if (send) {
1954
        ret = target_to_host_cmsg(&msg, msgp);
1955
        if (ret == 0)
1956
            ret = get_errno(sendmsg(fd, &msg, flags));
1957
    } else {
1958
        ret = get_errno(recvmsg(fd, &msg, flags));
1959
        if (!is_error(ret)) {
1960
            len = ret;
1961
            ret = host_to_target_cmsg(msgp, &msg);
1962
            if (!is_error(ret)) {
1963
                msgp->msg_namelen = tswap32(msg.msg_namelen);
1964
                if (msg.msg_name != NULL) {
1965
                    ret = host_to_target_sockaddr(tswapal(msgp->msg_name),
1966
                                    msg.msg_name, msg.msg_namelen);
1967
                    if (ret) {
1968
                        goto out;
1969
                    }
1970
                }
1971

    
1972
                ret = len;
1973
            }
1974
        }
1975
    }
1976

    
1977
out:
1978
    unlock_iovec(vec, target_vec, count, !send);
1979
out2:
1980
    unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1981
    return ret;
1982
}
1983

    
1984
/* do_accept() Must return target values and target errnos. */
1985
static abi_long do_accept(int fd, abi_ulong target_addr,
1986
                          abi_ulong target_addrlen_addr)
1987
{
1988
    socklen_t addrlen;
1989
    void *addr;
1990
    abi_long ret;
1991

    
1992
    if (target_addr == 0)
1993
       return get_errno(accept(fd, NULL, NULL));
1994

    
1995
    /* linux returns EINVAL if addrlen pointer is invalid */
1996
    if (get_user_u32(addrlen, target_addrlen_addr))
1997
        return -TARGET_EINVAL;
1998

    
1999
    if ((int)addrlen < 0) {
2000
        return -TARGET_EINVAL;
2001
    }
2002

    
2003
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
2004
        return -TARGET_EINVAL;
2005

    
2006
    addr = alloca(addrlen);
2007

    
2008
    ret = get_errno(accept(fd, addr, &addrlen));
2009
    if (!is_error(ret)) {
2010
        host_to_target_sockaddr(target_addr, addr, addrlen);
2011
        if (put_user_u32(addrlen, target_addrlen_addr))
2012
            ret = -TARGET_EFAULT;
2013
    }
2014
    return ret;
2015
}
2016

    
2017
/* do_getpeername() Must return target values and target errnos. */
2018
static abi_long do_getpeername(int fd, abi_ulong target_addr,
2019
                               abi_ulong target_addrlen_addr)
2020
{
2021
    socklen_t addrlen;
2022
    void *addr;
2023
    abi_long ret;
2024

    
2025
    if (get_user_u32(addrlen, target_addrlen_addr))
2026
        return -TARGET_EFAULT;
2027

    
2028
    if ((int)addrlen < 0) {
2029
        return -TARGET_EINVAL;
2030
    }
2031

    
2032
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
2033
        return -TARGET_EFAULT;
2034

    
2035
    addr = alloca(addrlen);
2036

    
2037
    ret = get_errno(getpeername(fd, addr, &addrlen));
2038
    if (!is_error(ret)) {
2039
        host_to_target_sockaddr(target_addr, addr, addrlen);
2040
        if (put_user_u32(addrlen, target_addrlen_addr))
2041
            ret = -TARGET_EFAULT;
2042
    }
2043
    return ret;
2044
}
2045

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

    
2054
    if (get_user_u32(addrlen, target_addrlen_addr))
2055
        return -TARGET_EFAULT;
2056

    
2057
    if ((int)addrlen < 0) {
2058
        return -TARGET_EINVAL;
2059
    }
2060

    
2061
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
2062
        return -TARGET_EFAULT;
2063

    
2064
    addr = alloca(addrlen);
2065

    
2066
    ret = get_errno(getsockname(fd, addr, &addrlen));
2067
    if (!is_error(ret)) {
2068
        host_to_target_sockaddr(target_addr, addr, addrlen);
2069
        if (put_user_u32(addrlen, target_addrlen_addr))
2070
            ret = -TARGET_EFAULT;
2071
    }
2072
    return ret;
2073
}
2074

    
2075
/* do_socketpair() Must return target values and target errnos. */
2076
static abi_long do_socketpair(int domain, int type, int protocol,
2077
                              abi_ulong target_tab_addr)
2078
{
2079
    int tab[2];
2080
    abi_long ret;
2081

    
2082
    ret = get_errno(socketpair(domain, type, protocol, tab));
2083
    if (!is_error(ret)) {
2084
        if (put_user_s32(tab[0], target_tab_addr)
2085
            || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
2086
            ret = -TARGET_EFAULT;
2087
    }
2088
    return ret;
2089
}
2090

    
2091
/* do_sendto() Must return target values and target errnos. */
2092
static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
2093
                          abi_ulong target_addr, socklen_t addrlen)
2094
{
2095
    void *addr;
2096
    void *host_msg;
2097
    abi_long ret;
2098

    
2099
    if ((int)addrlen < 0) {
2100
        return -TARGET_EINVAL;
2101
    }
2102

    
2103
    host_msg = lock_user(VERIFY_READ, msg, len, 1);
2104
    if (!host_msg)
2105
        return -TARGET_EFAULT;
2106
    if (target_addr) {
2107
        addr = alloca(addrlen);
2108
        ret = target_to_host_sockaddr(addr, target_addr, addrlen);
2109
        if (ret) {
2110
            unlock_user(host_msg, msg, 0);
2111
            return ret;
2112
        }
2113
        ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
2114
    } else {
2115
        ret = get_errno(send(fd, host_msg, len, flags));
2116
    }
2117
    unlock_user(host_msg, msg, 0);
2118
    return ret;
2119
}
2120

    
2121
/* do_recvfrom() Must return target values and target errnos. */
2122
static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
2123
                            abi_ulong target_addr,
2124
                            abi_ulong target_addrlen)
2125
{
2126
    socklen_t addrlen;
2127
    void *addr;
2128
    void *host_msg;
2129
    abi_long ret;
2130

    
2131
    host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
2132
    if (!host_msg)
2133
        return -TARGET_EFAULT;
2134
    if (target_addr) {
2135
        if (get_user_u32(addrlen, target_addrlen)) {
2136
            ret = -TARGET_EFAULT;
2137
            goto fail;
2138
        }
2139
        if ((int)addrlen < 0) {
2140
            ret = -TARGET_EINVAL;
2141
            goto fail;
2142
        }
2143
        addr = alloca(addrlen);
2144
        ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
2145
    } else {
2146
        addr = NULL; /* To keep compiler quiet.  */
2147
        ret = get_errno(qemu_recv(fd, host_msg, len, flags));
2148
    }
2149
    if (!is_error(ret)) {
2150
        if (target_addr) {
2151
            host_to_target_sockaddr(target_addr, addr, addrlen);
2152
            if (put_user_u32(addrlen, target_addrlen)) {
2153
                ret = -TARGET_EFAULT;
2154
                goto fail;
2155
            }
2156
        }
2157
        unlock_user(host_msg, msg, len);
2158
    } else {
2159
fail:
2160
        unlock_user(host_msg, msg, 0);
2161
    }
2162
    return ret;
2163
}
2164

    
2165
#ifdef TARGET_NR_socketcall
2166
/* do_socketcall() Must return target values and target errnos. */
2167
static abi_long do_socketcall(int num, abi_ulong vptr)
2168
{
2169
    abi_long ret;
2170
    const int n = sizeof(abi_ulong);
2171

    
2172
    switch(num) {
2173
    case SOCKOP_socket:
2174
        {
2175
            abi_ulong domain, type, protocol;
2176

    
2177
            if (get_user_ual(domain, vptr)
2178
                || get_user_ual(type, vptr + n)
2179
                || get_user_ual(protocol, vptr + 2 * n))
2180
                return -TARGET_EFAULT;
2181

    
2182
            ret = do_socket(domain, type, protocol);
2183
        }
2184
        break;
2185
    case SOCKOP_bind:
2186
        {
2187
            abi_ulong sockfd;
2188
            abi_ulong target_addr;
2189
            socklen_t addrlen;
2190

    
2191
            if (get_user_ual(sockfd, vptr)
2192
                || get_user_ual(target_addr, vptr + n)
2193
                || get_user_ual(addrlen, vptr + 2 * n))
2194
                return -TARGET_EFAULT;
2195

    
2196
            ret = do_bind(sockfd, target_addr, addrlen);
2197
        }
2198
        break;
2199
    case SOCKOP_connect:
2200
        {
2201
            abi_ulong sockfd;
2202
            abi_ulong target_addr;
2203
            socklen_t addrlen;
2204

    
2205
            if (get_user_ual(sockfd, vptr)
2206
                || get_user_ual(target_addr, vptr + n)
2207
                || get_user_ual(addrlen, vptr + 2 * n))
2208
                return -TARGET_EFAULT;
2209

    
2210
            ret = do_connect(sockfd, target_addr, addrlen);
2211
        }
2212
        break;
2213
    case SOCKOP_listen:
2214
        {
2215
            abi_ulong sockfd, backlog;
2216

    
2217
            if (get_user_ual(sockfd, vptr)
2218
                || get_user_ual(backlog, vptr + n))
2219
                return -TARGET_EFAULT;
2220

    
2221
            ret = get_errno(listen(sockfd, backlog));
2222
        }
2223
        break;
2224
    case SOCKOP_accept:
2225
        {
2226
            abi_ulong sockfd;
2227
            abi_ulong target_addr, target_addrlen;
2228

    
2229
            if (get_user_ual(sockfd, vptr)
2230
                || get_user_ual(target_addr, vptr + n)
2231
                || get_user_ual(target_addrlen, vptr + 2 * n))
2232
                return -TARGET_EFAULT;
2233

    
2234
            ret = do_accept(sockfd, target_addr, target_addrlen);
2235
        }
2236
        break;
2237
    case SOCKOP_getsockname:
2238
        {
2239
            abi_ulong sockfd;
2240
            abi_ulong target_addr, target_addrlen;
2241

    
2242
            if (get_user_ual(sockfd, vptr)
2243
                || get_user_ual(target_addr, vptr + n)
2244
                || get_user_ual(target_addrlen, vptr + 2 * n))
2245
                return -TARGET_EFAULT;
2246

    
2247
            ret = do_getsockname(sockfd, target_addr, target_addrlen);
2248
        }
2249
        break;
2250
    case SOCKOP_getpeername:
2251
        {
2252
            abi_ulong sockfd;
2253
            abi_ulong target_addr, target_addrlen;
2254

    
2255
            if (get_user_ual(sockfd, vptr)
2256
                || get_user_ual(target_addr, vptr + n)
2257
                || get_user_ual(target_addrlen, vptr + 2 * n))
2258
                return -TARGET_EFAULT;
2259

    
2260
            ret = do_getpeername(sockfd, target_addr, target_addrlen);
2261
        }
2262
        break;
2263
    case SOCKOP_socketpair:
2264
        {
2265
            abi_ulong domain, type, protocol;
2266
            abi_ulong tab;
2267

    
2268
            if (get_user_ual(domain, vptr)
2269
                || get_user_ual(type, vptr + n)
2270
                || get_user_ual(protocol, vptr + 2 * n)
2271
                || get_user_ual(tab, vptr + 3 * n))
2272
                return -TARGET_EFAULT;
2273

    
2274
            ret = do_socketpair(domain, type, protocol, tab);
2275
        }
2276
        break;
2277
    case SOCKOP_send:
2278
        {
2279
            abi_ulong sockfd;
2280
            abi_ulong msg;
2281
            size_t len;
2282
            abi_ulong flags;
2283

    
2284
            if (get_user_ual(sockfd, vptr)
2285
                || get_user_ual(msg, vptr + n)
2286
                || get_user_ual(len, vptr + 2 * n)
2287
                || get_user_ual(flags, vptr + 3 * n))
2288
                return -TARGET_EFAULT;
2289

    
2290
            ret = do_sendto(sockfd, msg, len, flags, 0, 0);
2291
        }
2292
        break;
2293
    case SOCKOP_recv:
2294
        {
2295
            abi_ulong sockfd;
2296
            abi_ulong msg;
2297
            size_t len;
2298
            abi_ulong flags;
2299

    
2300
            if (get_user_ual(sockfd, vptr)
2301
                || get_user_ual(msg, vptr + n)
2302
                || get_user_ual(len, vptr + 2 * n)
2303
                || get_user_ual(flags, vptr + 3 * n))
2304
                return -TARGET_EFAULT;
2305

    
2306
            ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
2307
        }
2308
        break;
2309
    case SOCKOP_sendto:
2310
        {
2311
            abi_ulong sockfd;
2312
            abi_ulong msg;
2313
            size_t len;
2314
            abi_ulong flags;
2315
            abi_ulong addr;
2316
            socklen_t addrlen;
2317

    
2318
            if (get_user_ual(sockfd, vptr)
2319
                || get_user_ual(msg, vptr + n)
2320
                || get_user_ual(len, vptr + 2 * n)
2321
                || get_user_ual(flags, vptr + 3 * n)
2322
                || get_user_ual(addr, vptr + 4 * n)
2323
                || get_user_ual(addrlen, vptr + 5 * n))
2324
                return -TARGET_EFAULT;
2325

    
2326
            ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
2327
        }
2328
        break;
2329
    case SOCKOP_recvfrom:
2330
        {
2331
            abi_ulong sockfd;
2332
            abi_ulong msg;
2333
            size_t len;
2334
            abi_ulong flags;
2335
            abi_ulong addr;
2336
            socklen_t addrlen;
2337

    
2338
            if (get_user_ual(sockfd, vptr)
2339
                || get_user_ual(msg, vptr + n)
2340
                || get_user_ual(len, vptr + 2 * n)
2341
                || get_user_ual(flags, vptr + 3 * n)
2342
                || get_user_ual(addr, vptr + 4 * n)
2343
                || get_user_ual(addrlen, vptr + 5 * n))
2344
                return -TARGET_EFAULT;
2345

    
2346
            ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
2347
        }
2348
        break;
2349
    case SOCKOP_shutdown:
2350
        {
2351
            abi_ulong sockfd, how;
2352

    
2353
            if (get_user_ual(sockfd, vptr)
2354
                || get_user_ual(how, vptr + n))
2355
                return -TARGET_EFAULT;
2356

    
2357
            ret = get_errno(shutdown(sockfd, how));
2358
        }
2359
        break;
2360
    case SOCKOP_sendmsg:
2361
    case SOCKOP_recvmsg:
2362
        {
2363
            abi_ulong fd;
2364
            abi_ulong target_msg;
2365
            abi_ulong flags;
2366

    
2367
            if (get_user_ual(fd, vptr)
2368
                || get_user_ual(target_msg, vptr + n)
2369
                || get_user_ual(flags, vptr + 2 * n))
2370
                return -TARGET_EFAULT;
2371

    
2372
            ret = do_sendrecvmsg(fd, target_msg, flags,
2373
                                 (num == SOCKOP_sendmsg));
2374
        }
2375
        break;
2376
    case SOCKOP_setsockopt:
2377
        {
2378
            abi_ulong sockfd;
2379
            abi_ulong level;
2380
            abi_ulong optname;
2381
            abi_ulong optval;
2382
            socklen_t optlen;
2383

    
2384
            if (get_user_ual(sockfd, vptr)
2385
                || get_user_ual(level, vptr + n)
2386
                || get_user_ual(optname, vptr + 2 * n)
2387
                || get_user_ual(optval, vptr + 3 * n)
2388
                || get_user_ual(optlen, vptr + 4 * n))
2389
                return -TARGET_EFAULT;
2390

    
2391
            ret = do_setsockopt(sockfd, level, optname, optval, optlen);
2392
        }
2393
        break;
2394
    case SOCKOP_getsockopt:
2395
        {
2396
            abi_ulong sockfd;
2397
            abi_ulong level;
2398
            abi_ulong optname;
2399
            abi_ulong optval;
2400
            socklen_t optlen;
2401

    
2402
            if (get_user_ual(sockfd, vptr)
2403
                || get_user_ual(level, vptr + n)
2404
                || get_user_ual(optname, vptr + 2 * n)
2405
                || get_user_ual(optval, vptr + 3 * n)
2406
                || get_user_ual(optlen, vptr + 4 * n))
2407
                return -TARGET_EFAULT;
2408

    
2409
            ret = do_getsockopt(sockfd, level, optname, optval, optlen);
2410
        }
2411
        break;
2412
    default:
2413
        gemu_log("Unsupported socketcall: %d\n", num);
2414
        ret = -TARGET_ENOSYS;
2415
        break;
2416
    }
2417
    return ret;
2418
}
2419
#endif
2420

    
2421
#define N_SHM_REGIONS        32
2422

    
2423
static struct shm_region {
2424
    abi_ulong        start;
2425
    abi_ulong        size;
2426
} shm_regions[N_SHM_REGIONS];
2427

    
2428
struct target_ipc_perm
2429
{
2430
    abi_long __key;
2431
    abi_ulong uid;
2432
    abi_ulong gid;
2433
    abi_ulong cuid;
2434
    abi_ulong cgid;
2435
    unsigned short int mode;
2436
    unsigned short int __pad1;
2437
    unsigned short int __seq;
2438
    unsigned short int __pad2;
2439
    abi_ulong __unused1;
2440
    abi_ulong __unused2;
2441
};
2442

    
2443
struct target_semid_ds
2444
{
2445
  struct target_ipc_perm sem_perm;
2446
  abi_ulong sem_otime;
2447
  abi_ulong __unused1;
2448
  abi_ulong sem_ctime;
2449
  abi_ulong __unused2;
2450
  abi_ulong sem_nsems;
2451
  abi_ulong __unused3;
2452
  abi_ulong __unused4;
2453
};
2454

    
2455
static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
2456
                                               abi_ulong target_addr)
2457
{
2458
    struct target_ipc_perm *target_ip;
2459
    struct target_semid_ds *target_sd;
2460

    
2461
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2462
        return -TARGET_EFAULT;
2463
    target_ip = &(target_sd->sem_perm);
2464
    host_ip->__key = tswapal(target_ip->__key);
2465
    host_ip->uid = tswapal(target_ip->uid);
2466
    host_ip->gid = tswapal(target_ip->gid);
2467
    host_ip->cuid = tswapal(target_ip->cuid);
2468
    host_ip->cgid = tswapal(target_ip->cgid);
2469
    host_ip->mode = tswap16(target_ip->mode);
2470
    unlock_user_struct(target_sd, target_addr, 0);
2471
    return 0;
2472
}
2473

    
2474
static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
2475
                                               struct ipc_perm *host_ip)
2476
{
2477
    struct target_ipc_perm *target_ip;
2478
    struct target_semid_ds *target_sd;
2479

    
2480
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2481
        return -TARGET_EFAULT;
2482
    target_ip = &(target_sd->sem_perm);
2483
    target_ip->__key = tswapal(host_ip->__key);
2484
    target_ip->uid = tswapal(host_ip->uid);
2485
    target_ip->gid = tswapal(host_ip->gid);
2486
    target_ip->cuid = tswapal(host_ip->cuid);
2487
    target_ip->cgid = tswapal(host_ip->cgid);
2488
    target_ip->mode = tswap16(host_ip->mode);
2489
    unlock_user_struct(target_sd, target_addr, 1);
2490
    return 0;
2491
}
2492

    
2493
static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
2494
                                               abi_ulong target_addr)
2495
{
2496
    struct target_semid_ds *target_sd;
2497

    
2498
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2499
        return -TARGET_EFAULT;
2500
    if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr))
2501
        return -TARGET_EFAULT;
2502
    host_sd->sem_nsems = tswapal(target_sd->sem_nsems);
2503
    host_sd->sem_otime = tswapal(target_sd->sem_otime);
2504
    host_sd->sem_ctime = tswapal(target_sd->sem_ctime);
2505
    unlock_user_struct(target_sd, target_addr, 0);
2506
    return 0;
2507
}
2508

    
2509
static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
2510
                                               struct semid_ds *host_sd)
2511
{
2512
    struct target_semid_ds *target_sd;
2513

    
2514
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2515
        return -TARGET_EFAULT;
2516
    if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
2517
        return -TARGET_EFAULT;
2518
    target_sd->sem_nsems = tswapal(host_sd->sem_nsems);
2519
    target_sd->sem_otime = tswapal(host_sd->sem_otime);
2520
    target_sd->sem_ctime = tswapal(host_sd->sem_ctime);
2521
    unlock_user_struct(target_sd, target_addr, 1);
2522
    return 0;
2523
}
2524

    
2525
struct target_seminfo {
2526
    int semmap;
2527
    int semmni;
2528
    int semmns;
2529
    int semmnu;
2530
    int semmsl;
2531
    int semopm;
2532
    int semume;
2533
    int semusz;
2534
    int semvmx;
2535
    int semaem;
2536
};
2537

    
2538
static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
2539
                                              struct seminfo *host_seminfo)
2540
{
2541
    struct target_seminfo *target_seminfo;
2542
    if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
2543
        return -TARGET_EFAULT;
2544
    __put_user(host_seminfo->semmap, &target_seminfo->semmap);
2545
    __put_user(host_seminfo->semmni, &target_seminfo->semmni);
2546
    __put_user(host_seminfo->semmns, &target_seminfo->semmns);
2547
    __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
2548
    __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
2549
    __put_user(host_seminfo->semopm, &target_seminfo->semopm);
2550
    __put_user(host_seminfo->semume, &target_seminfo->semume);
2551
    __put_user(host_seminfo->semusz, &target_seminfo->semusz);
2552
    __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
2553
    __put_user(host_seminfo->semaem, &target_seminfo->semaem);
2554
    unlock_user_struct(target_seminfo, target_addr, 1);
2555
    return 0;
2556
}
2557

    
2558
union semun {
2559
        int val;
2560
        struct semid_ds *buf;
2561
        unsigned short *array;
2562
        struct seminfo *__buf;
2563
};
2564

    
2565
union target_semun {
2566
        int val;
2567
        abi_ulong buf;
2568
        abi_ulong array;
2569
        abi_ulong __buf;
2570
};
2571

    
2572
static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
2573
                                               abi_ulong target_addr)
2574
{
2575
    int nsems;
2576
    unsigned short *array;
2577
    union semun semun;
2578
    struct semid_ds semid_ds;
2579
    int i, ret;
2580

    
2581
    semun.buf = &semid_ds;
2582

    
2583
    ret = semctl(semid, 0, IPC_STAT, semun);
2584
    if (ret == -1)
2585
        return get_errno(ret);
2586

    
2587
    nsems = semid_ds.sem_nsems;
2588

    
2589
    *host_array = malloc(nsems*sizeof(unsigned short));
2590
    array = lock_user(VERIFY_READ, target_addr,
2591
                      nsems*sizeof(unsigned short), 1);
2592
    if (!array)
2593
        return -TARGET_EFAULT;
2594

    
2595
    for(i=0; i<nsems; i++) {
2596
        __get_user((*host_array)[i], &array[i]);
2597
    }
2598
    unlock_user(array, target_addr, 0);
2599

    
2600
    return 0;
2601
}
2602

    
2603
static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
2604
                                               unsigned short **host_array)
2605
{
2606
    int nsems;
2607
    unsigned short *array;
2608
    union semun semun;
2609
    struct semid_ds semid_ds;
2610
    int i, ret;
2611

    
2612
    semun.buf = &semid_ds;
2613

    
2614
    ret = semctl(semid, 0, IPC_STAT, semun);
2615
    if (ret == -1)
2616
        return get_errno(ret);
2617

    
2618
    nsems = semid_ds.sem_nsems;
2619

    
2620
    array = lock_user(VERIFY_WRITE, target_addr,
2621
                      nsems*sizeof(unsigned short), 0);
2622
    if (!array)
2623
        return -TARGET_EFAULT;
2624

    
2625
    for(i=0; i<nsems; i++) {
2626
        __put_user((*host_array)[i], &array[i]);
2627
    }
2628
    free(*host_array);
2629
    unlock_user(array, target_addr, 1);
2630

    
2631
    return 0;
2632
}
2633

    
2634
static inline abi_long do_semctl(int semid, int semnum, int cmd,
2635
                                 union target_semun target_su)
2636
{
2637
    union semun arg;
2638
    struct semid_ds dsarg;
2639
    unsigned short *array = NULL;
2640
    struct seminfo seminfo;
2641
    abi_long ret = -TARGET_EINVAL;
2642
    abi_long err;
2643
    cmd &= 0xff;
2644

    
2645
    switch( cmd ) {
2646
        case GETVAL:
2647
        case SETVAL:
2648
            arg.val = tswap32(target_su.val);
2649
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2650
            target_su.val = tswap32(arg.val);
2651
            break;
2652
        case GETALL:
2653
        case SETALL:
2654
            err = target_to_host_semarray(semid, &array, target_su.array);
2655
            if (err)
2656
                return err;
2657
            arg.array = array;
2658
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2659
            err = host_to_target_semarray(semid, target_su.array, &array);
2660
            if (err)
2661
                return err;
2662
            break;
2663
        case IPC_STAT:
2664
        case IPC_SET:
2665
        case SEM_STAT:
2666
            err = target_to_host_semid_ds(&dsarg, target_su.buf);
2667
            if (err)
2668
                return err;
2669
            arg.buf = &dsarg;
2670
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2671
            err = host_to_target_semid_ds(target_su.buf, &dsarg);
2672
            if (err)
2673
                return err;
2674
            break;
2675
        case IPC_INFO:
2676
        case SEM_INFO:
2677
            arg.__buf = &seminfo;
2678
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2679
            err = host_to_target_seminfo(target_su.__buf, &seminfo);
2680
            if (err)
2681
                return err;
2682
            break;
2683
        case IPC_RMID:
2684
        case GETPID:
2685
        case GETNCNT:
2686
        case GETZCNT:
2687
            ret = get_errno(semctl(semid, semnum, cmd, NULL));
2688
            break;
2689
    }
2690

    
2691
    return ret;
2692
}
2693

    
2694
struct target_sembuf {
2695
    unsigned short sem_num;
2696
    short sem_op;
2697
    short sem_flg;
2698
};
2699

    
2700
static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
2701
                                             abi_ulong target_addr,
2702
                                             unsigned nsops)
2703
{
2704
    struct target_sembuf *target_sembuf;
2705
    int i;
2706

    
2707
    target_sembuf = lock_user(VERIFY_READ, target_addr,
2708
                              nsops*sizeof(struct target_sembuf), 1);
2709
    if (!target_sembuf)
2710
        return -TARGET_EFAULT;
2711

    
2712
    for(i=0; i<nsops; i++) {
2713
        __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
2714
        __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
2715
        __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
2716
    }
2717

    
2718
    unlock_user(target_sembuf, target_addr, 0);
2719

    
2720
    return 0;
2721
}
2722

    
2723
static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
2724
{
2725
    struct sembuf sops[nsops];
2726

    
2727
    if (target_to_host_sembuf(sops, ptr, nsops))
2728
        return -TARGET_EFAULT;
2729

    
2730
    return semop(semid, sops, nsops);
2731
}
2732

    
2733
struct target_msqid_ds
2734
{
2735
    struct target_ipc_perm msg_perm;
2736
    abi_ulong msg_stime;
2737
#if TARGET_ABI_BITS == 32
2738
    abi_ulong __unused1;
2739
#endif
2740
    abi_ulong msg_rtime;
2741
#if TARGET_ABI_BITS == 32
2742
    abi_ulong __unused2;
2743
#endif
2744
    abi_ulong msg_ctime;
2745
#if TARGET_ABI_BITS == 32
2746
    abi_ulong __unused3;
2747
#endif
2748
    abi_ulong __msg_cbytes;
2749
    abi_ulong msg_qnum;
2750
    abi_ulong msg_qbytes;
2751
    abi_ulong msg_lspid;
2752
    abi_ulong msg_lrpid;
2753
    abi_ulong __unused4;
2754
    abi_ulong __unused5;
2755
};
2756

    
2757
static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
2758
                                               abi_ulong target_addr)
2759
{
2760
    struct target_msqid_ds *target_md;
2761

    
2762
    if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
2763
        return -TARGET_EFAULT;
2764
    if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
2765
        return -TARGET_EFAULT;
2766
    host_md->msg_stime = tswapal(target_md->msg_stime);
2767
    host_md->msg_rtime = tswapal(target_md->msg_rtime);
2768
    host_md->msg_ctime = tswapal(target_md->msg_ctime);
2769
    host_md->__msg_cbytes = tswapal(target_md->__msg_cbytes);
2770
    host_md->msg_qnum = tswapal(target_md->msg_qnum);
2771
    host_md->msg_qbytes = tswapal(target_md->msg_qbytes);
2772
    host_md->msg_lspid = tswapal(target_md->msg_lspid);
2773
    host_md->msg_lrpid = tswapal(target_md->msg_lrpid);
2774
    unlock_user_struct(target_md, target_addr, 0);
2775
    return 0;
2776
}
2777

    
2778
static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
2779
                                               struct msqid_ds *host_md)
2780
{
2781
    struct target_msqid_ds *target_md;
2782

    
2783
    if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
2784
        return -TARGET_EFAULT;
2785
    if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
2786
        return -TARGET_EFAULT;
2787
    target_md->msg_stime = tswapal(host_md->msg_stime);
2788
    target_md->msg_rtime = tswapal(host_md->msg_rtime);
2789
    target_md->msg_ctime = tswapal(host_md->msg_ctime);
2790
    target_md->__msg_cbytes = tswapal(host_md->__msg_cbytes);
2791
    target_md->msg_qnum = tswapal(host_md->msg_qnum);
2792
    target_md->msg_qbytes = tswapal(host_md->msg_qbytes);
2793
    target_md->msg_lspid = tswapal(host_md->msg_lspid);
2794
    target_md->msg_lrpid = tswapal(host_md->msg_lrpid);
2795
    unlock_user_struct(target_md, target_addr, 1);
2796
    return 0;
2797
}
2798

    
2799
struct target_msginfo {
2800
    int msgpool;
2801
    int msgmap;
2802
    int msgmax;
2803
    int msgmnb;
2804
    int msgmni;
2805
    int msgssz;
2806
    int msgtql;
2807
    unsigned short int msgseg;
2808
};
2809

    
2810
static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
2811
                                              struct msginfo *host_msginfo)
2812
{
2813
    struct target_msginfo *target_msginfo;
2814
    if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
2815
        return -TARGET_EFAULT;
2816
    __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
2817
    __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
2818
    __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
2819
    __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
2820
    __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
2821
    __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
2822
    __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
2823
    __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
2824
    unlock_user_struct(target_msginfo, target_addr, 1);
2825
    return 0;
2826
}
2827

    
2828
static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
2829
{
2830
    struct msqid_ds dsarg;
2831
    struct msginfo msginfo;
2832
    abi_long ret = -TARGET_EINVAL;
2833

    
2834
    cmd &= 0xff;
2835

    
2836
    switch (cmd) {
2837
    case IPC_STAT:
2838
    case IPC_SET:
2839
    case MSG_STAT:
2840
        if (target_to_host_msqid_ds(&dsarg,ptr))
2841
            return -TARGET_EFAULT;
2842
        ret = get_errno(msgctl(msgid, cmd, &dsarg));
2843
        if (host_to_target_msqid_ds(ptr,&dsarg))
2844
            return -TARGET_EFAULT;
2845
        break;
2846
    case IPC_RMID:
2847
        ret = get_errno(msgctl(msgid, cmd, NULL));
2848
        break;
2849
    case IPC_INFO:
2850
    case MSG_INFO:
2851
        ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
2852
        if (host_to_target_msginfo(ptr, &msginfo))
2853
            return -TARGET_EFAULT;
2854
        break;
2855
    }
2856

    
2857
    return ret;
2858
}
2859

    
2860
struct target_msgbuf {
2861
    abi_long mtype;
2862
    char        mtext[1];
2863
};
2864

    
2865
static inline abi_long do_msgsnd(int msqid, abi_long msgp,
2866
                                 unsigned int msgsz, int msgflg)
2867
{
2868
    struct target_msgbuf *target_mb;
2869
    struct msgbuf *host_mb;
2870
    abi_long ret = 0;
2871

    
2872
    if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
2873
        return -TARGET_EFAULT;
2874
    host_mb = malloc(msgsz+sizeof(long));
2875
    host_mb->mtype = (abi_long) tswapal(target_mb->mtype);
2876
    memcpy(host_mb->mtext, target_mb->mtext, msgsz);
2877
    ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
2878
    free(host_mb);
2879
    unlock_user_struct(target_mb, msgp, 0);
2880

    
2881
    return ret;
2882
}
2883

    
2884
static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2885
                                 unsigned int msgsz, abi_long msgtyp,
2886
                                 int msgflg)
2887
{
2888
    struct target_msgbuf *target_mb;
2889
    char *target_mtext;
2890
    struct msgbuf *host_mb;
2891
    abi_long ret = 0;
2892

    
2893
    if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2894
        return -TARGET_EFAULT;
2895

    
2896
    host_mb = g_malloc(msgsz+sizeof(long));
2897
    ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapal(msgtyp), msgflg));
2898

    
2899
    if (ret > 0) {
2900
        abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2901
        target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2902
        if (!target_mtext) {
2903
            ret = -TARGET_EFAULT;
2904
            goto end;
2905
        }
2906
        memcpy(target_mb->mtext, host_mb->mtext, ret);
2907
        unlock_user(target_mtext, target_mtext_addr, ret);
2908
    }
2909

    
2910
    target_mb->mtype = tswapal(host_mb->mtype);
2911

    
2912
end:
2913
    if (target_mb)
2914
        unlock_user_struct(target_mb, msgp, 1);
2915
    g_free(host_mb);
2916
    return ret;
2917
}
2918

    
2919
struct target_shmid_ds
2920
{
2921
    struct target_ipc_perm shm_perm;
2922
    abi_ulong shm_segsz;
2923
    abi_ulong shm_atime;
2924
#if TARGET_ABI_BITS == 32
2925
    abi_ulong __unused1;
2926
#endif
2927
    abi_ulong shm_dtime;
2928
#if TARGET_ABI_BITS == 32
2929
    abi_ulong __unused2;
2930
#endif
2931
    abi_ulong shm_ctime;
2932
#if TARGET_ABI_BITS == 32
2933
    abi_ulong __unused3;
2934
#endif
2935
    int shm_cpid;
2936
    int shm_lpid;
2937
    abi_ulong shm_nattch;
2938
    unsigned long int __unused4;
2939
    unsigned long int __unused5;
2940
};
2941

    
2942
static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
2943
                                               abi_ulong target_addr)
2944
{
2945
    struct target_shmid_ds *target_sd;
2946

    
2947
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2948
        return -TARGET_EFAULT;
2949
    if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr))
2950
        return -TARGET_EFAULT;
2951
    __get_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2952
    __get_user(host_sd->shm_atime, &target_sd->shm_atime);
2953
    __get_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2954
    __get_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2955
    __get_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2956
    __get_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2957
    __get_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2958
    unlock_user_struct(target_sd, target_addr, 0);
2959
    return 0;
2960
}
2961

    
2962
static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
2963
                                               struct shmid_ds *host_sd)
2964
{
2965
    struct target_shmid_ds *target_sd;
2966

    
2967
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2968
        return -TARGET_EFAULT;
2969
    if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm)))
2970
        return -TARGET_EFAULT;
2971
    __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2972
    __put_user(host_sd->shm_atime, &target_sd->shm_atime);
2973
    __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2974
    __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2975
    __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2976
    __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2977
    __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2978
    unlock_user_struct(target_sd, target_addr, 1);
2979
    return 0;
2980
}
2981

    
2982
struct  target_shminfo {
2983
    abi_ulong shmmax;
2984
    abi_ulong shmmin;
2985
    abi_ulong shmmni;
2986
    abi_ulong shmseg;
2987
    abi_ulong shmall;
2988
};
2989

    
2990
static inline abi_long host_to_target_shminfo(abi_ulong target_addr,
2991
                                              struct shminfo *host_shminfo)
2992
{
2993
    struct target_shminfo *target_shminfo;
2994
    if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0))
2995
        return -TARGET_EFAULT;
2996
    __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
2997
    __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
2998
    __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
2999
    __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
3000
    __put_user(host_shminfo->shmall, &target_shminfo->shmall);
3001
    unlock_user_struct(target_shminfo, target_addr, 1);
3002
    return 0;
3003
}
3004

    
3005
struct target_shm_info {
3006
    int used_ids;
3007
    abi_ulong shm_tot;
3008
    abi_ulong shm_rss;
3009
    abi_ulong shm_swp;
3010
    abi_ulong swap_attempts;
3011
    abi_ulong swap_successes;
3012
};
3013

    
3014
static inline abi_long host_to_target_shm_info(abi_ulong target_addr,
3015
                                               struct shm_info *host_shm_info)
3016
{
3017
    struct target_shm_info *target_shm_info;
3018
    if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0))
3019
        return -TARGET_EFAULT;
3020
    __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
3021
    __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
3022
    __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
3023
    __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
3024
    __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts);
3025
    __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes);
3026
    unlock_user_struct(target_shm_info, target_addr, 1);
3027
    return 0;
3028
}
3029

    
3030
static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
3031
{
3032
    struct shmid_ds dsarg;
3033
    struct shminfo shminfo;
3034
    struct shm_info shm_info;
3035
    abi_long ret = -TARGET_EINVAL;
3036

    
3037
    cmd &= 0xff;
3038

    
3039
    switch(cmd) {
3040
    case IPC_STAT:
3041
    case IPC_SET:
3042
    case SHM_STAT:
3043
        if (target_to_host_shmid_ds(&dsarg, buf))
3044
            return -TARGET_EFAULT;
3045
        ret = get_errno(shmctl(shmid, cmd, &dsarg));
3046
        if (host_to_target_shmid_ds(buf, &dsarg))
3047
            return -TARGET_EFAULT;
3048
        break;
3049
    case IPC_INFO:
3050
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
3051
        if (host_to_target_shminfo(buf, &shminfo))
3052
            return -TARGET_EFAULT;
3053
        break;
3054
    case SHM_INFO:
3055
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
3056
        if (host_to_target_shm_info(buf, &shm_info))
3057
            return -TARGET_EFAULT;
3058
        break;
3059
    case IPC_RMID:
3060
    case SHM_LOCK:
3061
    case SHM_UNLOCK:
3062
        ret = get_errno(shmctl(shmid, cmd, NULL));
3063
        break;
3064
    }
3065

    
3066
    return ret;
3067
}
3068

    
3069
static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
3070
{
3071
    abi_long raddr;
3072
    void *host_raddr;
3073
    struct shmid_ds shm_info;
3074
    int i,ret;
3075

    
3076
    /* find out the length of the shared memory segment */
3077
    ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
3078
    if (is_error(ret)) {
3079
        /* can't get length, bail out */
3080
        return ret;
3081
    }
3082

    
3083
    mmap_lock();
3084

    
3085
    if (shmaddr)
3086
        host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
3087
    else {
3088
        abi_ulong mmap_start;
3089

    
3090
        mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
3091

    
3092
        if (mmap_start == -1) {
3093
            errno = ENOMEM;
3094
            host_raddr = (void *)-1;
3095
        } else
3096
            host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);
3097
    }
3098

    
3099
    if (host_raddr == (void *)-1) {
3100
        mmap_unlock();
3101
        return get_errno((long)host_raddr);
3102
    }
3103
    raddr=h2g((unsigned long)host_raddr);
3104

    
3105
    page_set_flags(raddr, raddr + shm_info.shm_segsz,
3106
                   PAGE_VALID | PAGE_READ |
3107
                   ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
3108

    
3109
    for (i = 0; i < N_SHM_REGIONS; i++) {
3110
        if (shm_regions[i].start == 0) {
3111
            shm_regions[i].start = raddr;
3112
            shm_regions[i].size = shm_info.shm_segsz;
3113
            break;
3114
        }
3115
    }
3116

    
3117
    mmap_unlock();
3118
    return raddr;
3119

    
3120
}
3121

    
3122
static inline abi_long do_shmdt(abi_ulong shmaddr)
3123
{
3124
    int i;
3125

    
3126
    for (i = 0; i < N_SHM_REGIONS; ++i) {
3127
        if (shm_regions[i].start == shmaddr) {
3128
            shm_regions[i].start = 0;
3129
            page_set_flags(shmaddr, shmaddr + shm_regions[i].size, 0);
3130
            break;
3131
        }
3132
    }
3133

    
3134
    return get_errno(shmdt(g2h(shmaddr)));
3135
}
3136

    
3137
#ifdef TARGET_NR_ipc
3138
/* ??? This only works with linear mappings.  */
3139
/* do_ipc() must return target values and target errnos. */
3140
static abi_long do_ipc(unsigned int call, int first,
3141
                       int second, int third,
3142
                       abi_long ptr, abi_long fifth)
3143
{
3144
    int version;
3145
    abi_long ret = 0;
3146

    
3147
    version = call >> 16;
3148
    call &= 0xffff;
3149

    
3150
    switch (call) {
3151
    case IPCOP_semop:
3152
        ret = do_semop(first, ptr, second);
3153
        break;
3154

    
3155
    case IPCOP_semget:
3156
        ret = get_errno(semget(first, second, third));
3157
        break;
3158

    
3159
    case IPCOP_semctl:
3160
        ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr);
3161
        break;
3162

    
3163
    case IPCOP_msgget:
3164
        ret = get_errno(msgget(first, second));
3165
        break;
3166

    
3167
    case IPCOP_msgsnd:
3168
        ret = do_msgsnd(first, ptr, second, third);
3169
        break;
3170

    
3171
    case IPCOP_msgctl:
3172
        ret = do_msgctl(first, second, ptr);
3173
        break;
3174

    
3175
    case IPCOP_msgrcv:
3176
        switch (version) {
3177
        case 0:
3178
            {
3179
                struct target_ipc_kludge {
3180
                    abi_long msgp;
3181
                    abi_long msgtyp;
3182
                } *tmp;
3183

    
3184
                if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
3185
                    ret = -TARGET_EFAULT;
3186
                    break;
3187
                }
3188

    
3189
                ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
3190

    
3191
                unlock_user_struct(tmp, ptr, 0);
3192
                break;
3193
            }
3194
        default:
3195
            ret = do_msgrcv(first, ptr, second, fifth, third);
3196
        }
3197
        break;
3198

    
3199
    case IPCOP_shmat:
3200
        switch (version) {
3201
        default:
3202
        {
3203
            abi_ulong raddr;
3204
            raddr = do_shmat(first, ptr, second);
3205
            if (is_error(raddr))
3206
                return get_errno(raddr);
3207
            if (put_user_ual(raddr, third))
3208
                return -TARGET_EFAULT;
3209
            break;
3210
        }
3211
        case 1:
3212
            ret = -TARGET_EINVAL;
3213
            break;
3214
        }
3215
        break;
3216
    case IPCOP_shmdt:
3217
        ret = do_shmdt(ptr);
3218
        break;
3219

    
3220
    case IPCOP_shmget:
3221
        /* IPC_* flag values are the same on all linux platforms */
3222
        ret = get_errno(shmget(first, second, third));
3223
        break;
3224

    
3225
        /* IPC_* and SHM_* command values are the same on all linux platforms */
3226
    case IPCOP_shmctl:
3227
        ret = do_shmctl(first, second, third);
3228
        break;
3229
    default:
3230
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
3231
        ret = -TARGET_ENOSYS;
3232
        break;
3233
    }
3234
    return ret;
3235
}
3236
#endif
3237

    
3238
/* kernel structure types definitions */
3239

    
3240
#define STRUCT(name, ...) STRUCT_ ## name,
3241
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
3242
enum {
3243
#include "syscall_types.h"
3244
};
3245
#undef STRUCT
3246
#undef STRUCT_SPECIAL
3247

    
3248
#define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = {  __VA_ARGS__, TYPE_NULL };
3249
#define STRUCT_SPECIAL(name)
3250
#include "syscall_types.h"
3251
#undef STRUCT
3252
#undef STRUCT_SPECIAL
3253

    
3254
typedef struct IOCTLEntry IOCTLEntry;
3255

    
3256
typedef abi_long do_ioctl_fn(const IOCTLEntry *ie, uint8_t *buf_temp,
3257
                             int fd, abi_long cmd, abi_long arg);
3258

    
3259
struct IOCTLEntry {
3260
    unsigned int target_cmd;
3261
    unsigned int host_cmd;
3262
    const char *name;
3263
    int access;
3264
    do_ioctl_fn *do_ioctl;
3265
    const argtype arg_type[5];
3266
};
3267

    
3268
#define IOC_R 0x0001
3269
#define IOC_W 0x0002
3270
#define IOC_RW (IOC_R | IOC_W)
3271

    
3272
#define MAX_STRUCT_SIZE 4096
3273

    
3274
#ifdef CONFIG_FIEMAP
3275
/* So fiemap access checks don't overflow on 32 bit systems.
3276
 * This is very slightly smaller than the limit imposed by
3277
 * the underlying kernel.
3278
 */
3279
#define FIEMAP_MAX_EXTENTS ((UINT_MAX - sizeof(struct fiemap))  \
3280
                            / sizeof(struct fiemap_extent))
3281

    
3282
static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp,
3283
                                       int fd, abi_long cmd, abi_long arg)
3284
{
3285
    /* The parameter for this ioctl is a struct fiemap followed
3286
     * by an array of struct fiemap_extent whose size is set
3287
     * in fiemap->fm_extent_count. The array is filled in by the
3288
     * ioctl.
3289
     */
3290
    int target_size_in, target_size_out;
3291
    struct fiemap *fm;
3292
    const argtype *arg_type = ie->arg_type;
3293
    const argtype extent_arg_type[] = { MK_STRUCT(STRUCT_fiemap_extent) };
3294
    void *argptr, *p;
3295
    abi_long ret;
3296
    int i, extent_size = thunk_type_size(extent_arg_type, 0);
3297
    uint32_t outbufsz;
3298
    int free_fm = 0;
3299

    
3300
    assert(arg_type[0] == TYPE_PTR);
3301
    assert(ie->access == IOC_RW);
3302
    arg_type++;
3303
    target_size_in = thunk_type_size(arg_type, 0);
3304
    argptr = lock_user(VERIFY_READ, arg, target_size_in, 1);
3305
    if (!argptr) {
3306
        return -TARGET_EFAULT;
3307
    }
3308
    thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3309
    unlock_user(argptr, arg, 0);
3310
    fm = (struct fiemap *)buf_temp;
3311
    if (fm->fm_extent_count > FIEMAP_MAX_EXTENTS) {
3312
        return -TARGET_EINVAL;
3313
    }
3314

    
3315
    outbufsz = sizeof (*fm) +
3316
        (sizeof(struct fiemap_extent) * fm->fm_extent_count);
3317

    
3318
    if (outbufsz > MAX_STRUCT_SIZE) {
3319
        /* We can't fit all the extents into the fixed size buffer.
3320
         * Allocate one that is large enough and use it instead.
3321
         */
3322
        fm = malloc(outbufsz);
3323
        if (!fm) {
3324
            return -TARGET_ENOMEM;
3325
        }
3326
        memcpy(fm, buf_temp, sizeof(struct fiemap));
3327
        free_fm = 1;
3328
    }
3329
    ret = get_errno(ioctl(fd, ie->host_cmd, fm));
3330
    if (!is_error(ret)) {
3331
        target_size_out = target_size_in;
3332
        /* An extent_count of 0 means we were only counting the extents
3333
         * so there are no structs to copy
3334
         */
3335
        if (fm->fm_extent_count != 0) {
3336
            target_size_out += fm->fm_mapped_extents * extent_size;
3337
        }
3338
        argptr = lock_user(VERIFY_WRITE, arg, target_size_out, 0);
3339
        if (!argptr) {
3340
            ret = -TARGET_EFAULT;
3341
        } else {
3342
            /* Convert the struct fiemap */
3343
            thunk_convert(argptr, fm, arg_type, THUNK_TARGET);
3344
            if (fm->fm_extent_count != 0) {
3345
                p = argptr + target_size_in;
3346
                /* ...and then all the struct fiemap_extents */
3347
                for (i = 0; i < fm->fm_mapped_extents; i++) {
3348
                    thunk_convert(p, &fm->fm_extents[i], extent_arg_type,
3349
                                  THUNK_TARGET);
3350
                    p += extent_size;
3351
                }
3352
            }
3353
            unlock_user(argptr, arg, target_size_out);
3354
        }
3355
    }
3356
    if (free_fm) {
3357
        free(fm);
3358
    }
3359
    return ret;
3360
}
3361
#endif
3362

    
3363
static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp,
3364
                                int fd, abi_long cmd, abi_long arg)
3365
{
3366
    const argtype *arg_type = ie->arg_type;
3367
    int target_size;
3368
    void *argptr;
3369
    int ret;
3370
    struct ifconf *host_ifconf;
3371
    uint32_t outbufsz;
3372
    const argtype ifreq_arg_type[] = { MK_STRUCT(STRUCT_sockaddr_ifreq) };
3373
    int target_ifreq_size;
3374
    int nb_ifreq;
3375
    int free_buf = 0;
3376
    int i;
3377
    int target_ifc_len;
3378
    abi_long target_ifc_buf;
3379
    int host_ifc_len;
3380
    char *host_ifc_buf;
3381

    
3382
    assert(arg_type[0] == TYPE_PTR);
3383
    assert(ie->access == IOC_RW);
3384

    
3385
    arg_type++;
3386
    target_size = thunk_type_size(arg_type, 0);
3387

    
3388
    argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3389
    if (!argptr)
3390
        return -TARGET_EFAULT;
3391
    thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3392
    unlock_user(argptr, arg, 0);
3393

    
3394
    host_ifconf = (struct ifconf *)(unsigned long)buf_temp;
3395
    target_ifc_len = host_ifconf->ifc_len;
3396
    target_ifc_buf = (abi_long)(unsigned long)host_ifconf->ifc_buf;
3397

    
3398
    target_ifreq_size = thunk_type_size(ifreq_arg_type, 0);
3399
    nb_ifreq = target_ifc_len / target_ifreq_size;
3400
    host_ifc_len = nb_ifreq * sizeof(struct ifreq);
3401

    
3402
    outbufsz = sizeof(*host_ifconf) + host_ifc_len;
3403
    if (outbufsz > MAX_STRUCT_SIZE) {
3404
        /* We can't fit all the extents into the fixed size buffer.
3405
         * Allocate one that is large enough and use it instead.
3406
         */
3407
        host_ifconf = malloc(outbufsz);
3408
        if (!host_ifconf) {
3409
            return -TARGET_ENOMEM;
3410
        }
3411
        memcpy(host_ifconf, buf_temp, sizeof(*host_ifconf));
3412
        free_buf = 1;
3413
    }
3414
    host_ifc_buf = (char*)host_ifconf + sizeof(*host_ifconf);
3415

    
3416
    host_ifconf->ifc_len = host_ifc_len;
3417
    host_ifconf->ifc_buf = host_ifc_buf;
3418

    
3419
    ret = get_errno(ioctl(fd, ie->host_cmd, host_ifconf));
3420
    if (!is_error(ret)) {
3421
        /* convert host ifc_len to target ifc_len */
3422

    
3423
        nb_ifreq = host_ifconf->ifc_len / sizeof(struct ifreq);
3424
        target_ifc_len = nb_ifreq * target_ifreq_size;
3425
        host_ifconf->ifc_len = target_ifc_len;
3426

    
3427
        /* restore target ifc_buf */
3428

    
3429
        host_ifconf->ifc_buf = (char *)(unsigned long)target_ifc_buf;
3430

    
3431
        /* copy struct ifconf to target user */
3432

    
3433
        argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3434
        if (!argptr)
3435
            return -TARGET_EFAULT;
3436
        thunk_convert(argptr, host_ifconf, arg_type, THUNK_TARGET);
3437
        unlock_user(argptr, arg, target_size);
3438

    
3439
        /* copy ifreq[] to target user */
3440

    
3441
        argptr = lock_user(VERIFY_WRITE, target_ifc_buf, target_ifc_len, 0);
3442
        for (i = 0; i < nb_ifreq ; i++) {
3443
            thunk_convert(argptr + i * target_ifreq_size,
3444
                          host_ifc_buf + i * sizeof(struct ifreq),
3445
                          ifreq_arg_type, THUNK_TARGET);
3446
        }
3447
        unlock_user(argptr, target_ifc_buf, target_ifc_len);
3448
    }
3449

    
3450
    if (free_buf) {
3451
        free(host_ifconf);
3452
    }
3453

    
3454
    return ret;
3455
}
3456

    
3457
static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
3458
                            abi_long cmd, abi_long arg)
3459
{
3460
    void *argptr;
3461
    struct dm_ioctl *host_dm;
3462
    abi_long guest_data;
3463
    uint32_t guest_data_size;
3464
    int target_size;
3465
    const argtype *arg_type = ie->arg_type;
3466
    abi_long ret;
3467
    void *big_buf = NULL;
3468
    char *host_data;
3469

    
3470
    arg_type++;
3471
    target_size = thunk_type_size(arg_type, 0);
3472
    argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3473
    if (!argptr) {
3474
        ret = -TARGET_EFAULT;
3475
        goto out;
3476
    }
3477
    thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3478
    unlock_user(argptr, arg, 0);
3479

    
3480
    /* buf_temp is too small, so fetch things into a bigger buffer */
3481
    big_buf = g_malloc0(((struct dm_ioctl*)buf_temp)->data_size * 2);
3482
    memcpy(big_buf, buf_temp, target_size);
3483
    buf_temp = big_buf;
3484
    host_dm = big_buf;
3485

    
3486
    guest_data = arg + host_dm->data_start;
3487
    if ((guest_data - arg) < 0) {
3488
        ret = -EINVAL;
3489
        goto out;
3490
    }
3491
    guest_data_size = host_dm->data_size - host_dm->data_start;
3492
    host_data = (char*)host_dm + host_dm->data_start;
3493

    
3494
    argptr = lock_user(VERIFY_READ, guest_data, guest_data_size, 1);
3495
    switch (ie->host_cmd) {
3496
    case DM_REMOVE_ALL:
3497
    case DM_LIST_DEVICES:
3498
    case DM_DEV_CREATE:
3499
    case DM_DEV_REMOVE:
3500
    case DM_DEV_SUSPEND:
3501
    case DM_DEV_STATUS:
3502
    case DM_DEV_WAIT:
3503
    case DM_TABLE_STATUS:
3504
    case DM_TABLE_CLEAR:
3505
    case DM_TABLE_DEPS:
3506
    case DM_LIST_VERSIONS:
3507
        /* no input data */
3508
        break;
3509
    case DM_DEV_RENAME:
3510
    case DM_DEV_SET_GEOMETRY:
3511
        /* data contains only strings */
3512
        memcpy(host_data, argptr, guest_data_size);
3513
        break;
3514
    case DM_TARGET_MSG:
3515
        memcpy(host_data, argptr, guest_data_size);
3516
        *(uint64_t*)host_data = tswap64(*(uint64_t*)argptr);
3517
        break;
3518
    case DM_TABLE_LOAD:
3519
    {
3520
        void *gspec = argptr;
3521
        void *cur_data = host_data;
3522
        const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };
3523
        int spec_size = thunk_type_size(arg_type, 0);
3524
        int i;
3525

    
3526
        for (i = 0; i < host_dm->target_count; i++) {
3527
            struct dm_target_spec *spec = cur_data;
3528
            uint32_t next;
3529
            int slen;
3530

    
3531
            thunk_convert(spec, gspec, arg_type, THUNK_HOST);
3532
            slen = strlen((char*)gspec + spec_size) + 1;
3533
            next = spec->next;
3534
            spec->next = sizeof(*spec) + slen;
3535
            strcpy((char*)&spec[1], gspec + spec_size);
3536
            gspec += next;
3537
            cur_data += spec->next;
3538
        }
3539
        break;
3540
    }
3541
    default:
3542
        ret = -TARGET_EINVAL;
3543
        goto out;
3544
    }
3545
    unlock_user(argptr, guest_data, 0);
3546

    
3547
    ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3548
    if (!is_error(ret)) {
3549
        guest_data = arg + host_dm->data_start;
3550
        guest_data_size = host_dm->data_size - host_dm->data_start;
3551
        argptr = lock_user(VERIFY_WRITE, guest_data, guest_data_size, 0);
3552
        switch (ie->host_cmd) {
3553
        case DM_REMOVE_ALL:
3554
        case DM_DEV_CREATE:
3555
        case DM_DEV_REMOVE:
3556
        case DM_DEV_RENAME:
3557
        case DM_DEV_SUSPEND:
3558
        case DM_DEV_STATUS:
3559
        case DM_TABLE_LOAD:
3560
        case DM_TABLE_CLEAR:
3561
        case DM_TARGET_MSG:
3562
        case DM_DEV_SET_GEOMETRY:
3563
            /* no return data */
3564
            break;
3565
        case DM_LIST_DEVICES:
3566
        {
3567
            struct dm_name_list *nl = (void*)host_dm + host_dm->data_start;
3568
            uint32_t remaining_data = guest_data_size;
3569
            void *cur_data = argptr;
3570
            const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_name_list) };
3571
            int nl_size = 12; /* can't use thunk_size due to alignment */
3572

    
3573
            while (1) {
3574
                uint32_t next = nl->next;
3575
                if (next) {
3576
                    nl->next = nl_size + (strlen(nl->name) + 1);
3577
                }
3578
                if (remaining_data < nl->next) {
3579
                    host_dm->flags |= DM_BUFFER_FULL_FLAG;
3580
                    break;
3581
                }
3582
                thunk_convert(cur_data, nl, arg_type, THUNK_TARGET);
3583
                strcpy(cur_data + nl_size, nl->name);
3584
                cur_data += nl->next;
3585
                remaining_data -= nl->next;
3586
                if (!next) {
3587
                    break;
3588
                }
3589
                nl = (void*)nl + next;
3590
            }
3591
            break;
3592
        }
3593
        case DM_DEV_WAIT:
3594
        case DM_TABLE_STATUS:
3595
        {
3596
            struct dm_target_spec *spec = (void*)host_dm + host_dm->data_start;
3597
            void *cur_data = argptr;
3598
            const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };
3599
            int spec_size = thunk_type_size(arg_type, 0);
3600
            int i;
3601

    
3602
            for (i = 0; i < host_dm->target_count; i++) {
3603
                uint32_t next = spec->next;
3604
                int slen = strlen((char*)&spec[1]) + 1;
3605
                spec->next = (cur_data - argptr) + spec_size + slen;
3606
                if (guest_data_size < spec->next) {
3607
                    host_dm->flags |= DM_BUFFER_FULL_FLAG;
3608
                    break;
3609
                }
3610
                thunk_convert(cur_data, spec, arg_type, THUNK_TARGET);
3611
                strcpy(cur_data + spec_size, (char*)&spec[1]);
3612
                cur_data = argptr + spec->next;
3613
                spec = (void*)host_dm + host_dm->data_start + next;
3614
            }
3615
            break;
3616
        }
3617
        case DM_TABLE_DEPS:
3618
        {
3619
            void *hdata = (void*)host_dm + host_dm->data_start;
3620
            int count = *(uint32_t*)hdata;
3621
            uint64_t *hdev = hdata + 8;
3622
            uint64_t *gdev = argptr + 8;
3623
            int i;
3624

    
3625
            *(uint32_t*)argptr = tswap32(count);
3626
            for (i = 0; i < count; i++) {
3627
                *gdev = tswap64(*hdev);
3628
                gdev++;
3629
                hdev++;
3630
            }
3631
            break;
3632
        }
3633
        case DM_LIST_VERSIONS:
3634
        {
3635
            struct dm_target_versions *vers = (void*)host_dm + host_dm->data_start;
3636
            uint32_t remaining_data = guest_data_size;
3637
            void *cur_data = argptr;
3638
            const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_versions) };
3639
            int vers_size = thunk_type_size(arg_type, 0);
3640

    
3641
            while (1) {
3642
                uint32_t next = vers->next;
3643
                if (next) {
3644
                    vers->next = vers_size + (strlen(vers->name) + 1);
3645
                }
3646
                if (remaining_data < vers->next) {
3647
                    host_dm->flags |= DM_BUFFER_FULL_FLAG;
3648
                    break;
3649
                }
3650
                thunk_convert(cur_data, vers, arg_type, THUNK_TARGET);
3651
                strcpy(cur_data + vers_size, vers->name);
3652
                cur_data += vers->next;
3653
                remaining_data -= vers->next;
3654
                if (!next) {
3655
                    break;
3656
                }
3657
                vers = (void*)vers + next;
3658
            }
3659
            break;
3660
        }
3661
        default:
3662
            ret = -TARGET_EINVAL;
3663
            goto out;
3664
        }
3665
        unlock_user(argptr, guest_data, guest_data_size);
3666

    
3667
        argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3668
        if (!argptr) {
3669
            ret = -TARGET_EFAULT;
3670
            goto out;
3671
        }
3672
        thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
3673
        unlock_user(argptr, arg, target_size);
3674
    }
3675
out:
3676
    g_free(big_buf);
3677
    return ret;
3678
}
3679

    
3680
static IOCTLEntry ioctl_entries[] = {
3681
#define IOCTL(cmd, access, ...) \
3682
    { TARGET_ ## cmd, cmd, #cmd, access, 0, {  __VA_ARGS__ } },
3683
#define IOCTL_SPECIAL(cmd, access, dofn, ...)                      \
3684
    { TARGET_ ## cmd, cmd, #cmd, access, dofn, {  __VA_ARGS__ } },
3685
#include "ioctls.h"
3686
    { 0, 0, },
3687
};
3688

    
3689
/* ??? Implement proper locking for ioctls.  */
3690
/* do_ioctl() Must return target values and target errnos. */
3691
static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
3692
{
3693
    const IOCTLEntry *ie;
3694
    const argtype *arg_type;
3695
    abi_long ret;
3696
    uint8_t buf_temp[MAX_STRUCT_SIZE];
3697
    int target_size;
3698
    void *argptr;
3699

    
3700
    ie = ioctl_entries;
3701
    for(;;) {
3702
        if (ie->target_cmd == 0) {
3703
            gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
3704
            return -TARGET_ENOSYS;
3705
        }
3706
        if (ie->target_cmd == cmd)
3707
            break;
3708
        ie++;
3709
    }
3710
    arg_type = ie->arg_type;
3711
#if defined(DEBUG)
3712
    gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
3713
#endif
3714
    if (ie->do_ioctl) {
3715
        return ie->do_ioctl(ie, buf_temp, fd, cmd, arg);
3716
    }
3717

    
3718
    switch(arg_type[0]) {
3719
    case TYPE_NULL:
3720
        /* no argument */
3721
        ret = get_errno(ioctl(fd, ie->host_cmd));
3722
        break;
3723
    case TYPE_PTRVOID:
3724
    case TYPE_INT:
3725
        /* int argment */
3726
        ret = get_errno(ioctl(fd, ie->host_cmd, arg));
3727
        break;
3728
    case TYPE_PTR:
3729
        arg_type++;
3730
        target_size = thunk_type_size(arg_type, 0);
3731
        switch(ie->access) {
3732
        case IOC_R:
3733
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3734
            if (!is_error(ret)) {
3735
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3736
                if (!argptr)
3737
                    return -TARGET_EFAULT;
3738
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
3739
                unlock_user(argptr, arg, target_size);
3740
            }
3741
            break;
3742
        case IOC_W:
3743
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3744
            if (!argptr)
3745
                return -TARGET_EFAULT;
3746
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3747
            unlock_user(argptr, arg, 0);
3748
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3749
            break;
3750
        default:
3751
        case IOC_RW:
3752
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3753
            if (!argptr)
3754
                return -TARGET_EFAULT;
3755
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3756
            unlock_user(argptr, arg, 0);
3757
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3758
            if (!is_error(ret)) {
3759
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3760
                if (!argptr)
3761
                    return -TARGET_EFAULT;
3762
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
3763
                unlock_user(argptr, arg, target_size);
3764
            }
3765
            break;
3766
        }
3767
        break;
3768
    default:
3769
        gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
3770
                 (long)cmd, arg_type[0]);
3771
        ret = -TARGET_ENOSYS;
3772
        break;
3773
    }
3774
    return ret;
3775
}
3776

    
3777
static const bitmask_transtbl iflag_tbl[] = {
3778
        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
3779
        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
3780
        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
3781
        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
3782
        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
3783
        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
3784
        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
3785
        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
3786
        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
3787
        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
3788
        { TARGET_IXON, TARGET_IXON, IXON, IXON },
3789
        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
3790
        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
3791
        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
3792
        { 0, 0, 0, 0 }
3793
};
3794

    
3795
static const bitmask_transtbl oflag_tbl[] = {
3796
        { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
3797
        { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
3798
        { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
3799
        { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
3800
        { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
3801
        { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
3802
        { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
3803
        { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
3804
        { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
3805
        { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
3806
        { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
3807
        { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
3808
        { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
3809
        { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
3810
        { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
3811
        { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
3812
        { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
3813
        { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
3814
        { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
3815
        { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
3816
        { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
3817
        { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
3818
        { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
3819
        { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
3820
        { 0, 0, 0, 0 }
3821
};
3822

    
3823
static const bitmask_transtbl cflag_tbl[] = {
3824
        { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
3825
        { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
3826
        { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
3827
        { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
3828
        { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
3829
        { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
3830
        { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
3831
        { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
3832
        { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
3833
        { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
3834
        { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
3835
        { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
3836
        { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
3837
        { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
3838
        { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
3839
        { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
3840
        { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
3841
        { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
3842
        { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
3843
        { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
3844
        { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
3845
        { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
3846
        { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
3847
        { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
3848
        { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
3849
        { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
3850
        { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
3851
        { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
3852
        { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
3853
        { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
3854
        { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
3855
        { 0, 0, 0, 0 }
3856
};
3857

    
3858
static const bitmask_transtbl lflag_tbl[] = {
3859
        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
3860
        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
3861
        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
3862
        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
3863
        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
3864
        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
3865
        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
3866
        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
3867
        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
3868
        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
3869
        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
3870
        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
3871
        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
3872
        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
3873
        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
3874
        { 0, 0, 0, 0 }
3875
};
3876

    
3877
static void target_to_host_termios (void *dst, const void *src)
3878
{
3879
    struct host_termios *host = dst;
3880
    const struct target_termios *target = src;
3881

    
3882
    host->c_iflag =
3883
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
3884
    host->c_oflag =
3885
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
3886
    host->c_cflag =
3887
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
3888
    host->c_lflag =
3889
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
3890
    host->c_line = target->c_line;
3891

    
3892
    memset(host->c_cc, 0, sizeof(host->c_cc));
3893
    host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
3894
    host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
3895
    host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
3896
    host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
3897
    host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
3898
    host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
3899
    host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
3900
    host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
3901
    host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
3902
    host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
3903
    host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
3904
    host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
3905
    host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
3906
    host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
3907
    host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
3908
    host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
3909
    host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
3910
}
3911

    
3912
static void host_to_target_termios (void *dst, const void *src)
3913
{
3914
    struct target_termios *target = dst;
3915
    const struct host_termios *host = src;
3916

    
3917
    target->c_iflag =
3918
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
3919
    target->c_oflag =
3920
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
3921
    target->c_cflag =
3922
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
3923
    target->c_lflag =
3924
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
3925
    target->c_line = host->c_line;
3926

    
3927
    memset(target->c_cc, 0, sizeof(target->c_cc));
3928
    target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
3929
    target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
3930
    target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
3931
    target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
3932
    target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
3933
    target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
3934
    target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
3935
    target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
3936
    target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
3937
    target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
3938
    target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
3939
    target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
3940
    target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
3941
    target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
3942
    target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
3943
    target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
3944
    target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
3945
}
3946

    
3947
static const StructEntry struct_termios_def = {
3948
    .convert = { host_to_target_termios, target_to_host_termios },
3949
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
3950
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
3951
};
3952

    
3953
static bitmask_transtbl mmap_flags_tbl[] = {
3954
        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
3955
        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
3956
        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
3957
        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
3958
        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
3959
        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
3960
        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
3961
        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
3962
        { 0, 0, 0, 0 }
3963
};
3964

    
3965
#if defined(TARGET_I386)
3966

    
3967
/* NOTE: there is really one LDT for all the threads */
3968
static uint8_t *ldt_table;
3969

    
3970
static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
3971
{
3972
    int size;
3973
    void *p;
3974

    
3975
    if (!ldt_table)
3976
        return 0;
3977
    size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
3978
    if (size > bytecount)
3979
        size = bytecount;
3980
    p = lock_user(VERIFY_WRITE, ptr, size, 0);
3981
    if (!p)
3982
        return -TARGET_EFAULT;
3983
    /* ??? Should this by byteswapped?  */
3984
    memcpy(p, ldt_table, size);
3985
    unlock_user(p, ptr, size);
3986
    return size;
3987
}
3988

    
3989
/* XXX: add locking support */
3990
static abi_long write_ldt(CPUX86State *env,
3991
                          abi_ulong ptr, unsigned long bytecount, int oldmode)
3992
{
3993
    struct target_modify_ldt_ldt_s ldt_info;
3994
    struct target_modify_ldt_ldt_s *target_ldt_info;
3995
    int seg_32bit, contents, read_exec_only, limit_in_pages;
3996
    int seg_not_present, useable, lm;
3997
    uint32_t *lp, entry_1, entry_2;
3998

    
3999
    if (bytecount != sizeof(ldt_info))
4000
        return -TARGET_EINVAL;
4001
    if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
4002
        return -TARGET_EFAULT;
4003
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
4004
    ldt_info.base_addr = tswapal(target_ldt_info->base_addr);
4005
    ldt_info.limit = tswap32(target_ldt_info->limit);
4006
    ldt_info.flags = tswap32(target_ldt_info->flags);
4007
    unlock_user_struct(target_ldt_info, ptr, 0);
4008

    
4009
    if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
4010
        return -TARGET_EINVAL;
4011
    seg_32bit = ldt_info.flags & 1;
4012
    contents = (ldt_info.flags >> 1) & 3;
4013
    read_exec_only = (ldt_info.flags >> 3) & 1;
4014
    limit_in_pages = (ldt_info.flags >> 4) & 1;
4015
    seg_not_present = (ldt_info.flags >> 5) & 1;
4016
    useable = (ldt_info.flags >> 6) & 1;
4017
#ifdef TARGET_ABI32
4018
    lm = 0;
4019
#else
4020
    lm = (ldt_info.flags >> 7) & 1;
4021
#endif
4022
    if (contents == 3) {
4023
        if (oldmode)
4024
            return -TARGET_EINVAL;
4025
        if (seg_not_present == 0)
4026
            return -TARGET_EINVAL;
4027
    }
4028
    /* allocate the LDT */
4029
    if (!ldt_table) {
4030
        env->ldt.base = target_mmap(0,
4031
                                    TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
4032
                                    PROT_READ|PROT_WRITE,
4033
                                    MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
4034
        if (env->ldt.base == -1)
4035
            return -TARGET_ENOMEM;
4036
        memset(g2h(env->ldt.base), 0,
4037
               TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
4038
        env->ldt.limit = 0xffff;
4039
        ldt_table = g2h(env->ldt.base);
4040
    }
4041

    
4042
    /* NOTE: same code as Linux kernel */
4043
    /* Allow LDTs to be cleared by the user. */
4044
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
4045
        if (oldmode ||
4046
            (contents == 0                &&
4047
             read_exec_only == 1        &&
4048
             seg_32bit == 0                &&
4049
             limit_in_pages == 0        &&
4050
             seg_not_present == 1        &&
4051
             useable == 0 )) {
4052
            entry_1 = 0;
4053
            entry_2 = 0;
4054
            goto install;
4055
        }
4056
    }
4057

    
4058
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
4059
        (ldt_info.limit & 0x0ffff);
4060
    entry_2 = (ldt_info.base_addr & 0xff000000) |
4061
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
4062
        (ldt_info.limit & 0xf0000) |
4063
        ((read_exec_only ^ 1) << 9) |
4064
        (contents << 10) |
4065
        ((seg_not_present ^ 1) << 15) |
4066
        (seg_32bit << 22) |
4067
        (limit_in_pages << 23) |
4068
        (lm << 21) |
4069
        0x7000;
4070
    if (!oldmode)
4071
        entry_2 |= (useable << 20);
4072

    
4073
    /* Install the new entry ...  */
4074
install:
4075
    lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
4076
    lp[0] = tswap32(entry_1);
4077
    lp[1] = tswap32(entry_2);
4078
    return 0;
4079
}
4080

    
4081
/* specific and weird i386 syscalls */
4082
static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
4083
                              unsigned long bytecount)
4084
{
4085
    abi_long ret;
4086

    
4087
    switch (func) {
4088
    case 0:
4089
        ret = read_ldt(ptr, bytecount);
4090
        break;
4091
    case 1:
4092
        ret = write_ldt(env, ptr, bytecount, 1);
4093
        break;
4094
    case 0x11:
4095
        ret = write_ldt(env, ptr, bytecount, 0);
4096
        break;
4097
    default:
4098
        ret = -TARGET_ENOSYS;
4099
        break;
4100
    }
4101
    return ret;
4102
}
4103

    
4104
#if defined(TARGET_I386) && defined(TARGET_ABI32)
4105
static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
4106
{
4107
    uint64_t *gdt_table = g2h(env->gdt.base);
4108
    struct target_modify_ldt_ldt_s ldt_info;
4109
    struct target_modify_ldt_ldt_s *target_ldt_info;
4110
    int seg_32bit, contents, read_exec_only, limit_in_pages;
4111
    int seg_not_present, useable, lm;
4112
    uint32_t *lp, entry_1, entry_2;
4113
    int i;
4114

    
4115
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
4116
    if (!target_ldt_info)
4117
        return -TARGET_EFAULT;
4118
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
4119
    ldt_info.base_addr = tswapal(target_ldt_info->base_addr);
4120
    ldt_info.limit = tswap32(target_ldt_info->limit);
4121
    ldt_info.flags = tswap32(target_ldt_info->flags);
4122
    if (ldt_info.entry_number == -1) {
4123
        for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
4124
            if (gdt_table[i] == 0) {
4125
                ldt_info.entry_number = i;
4126
                target_ldt_info->entry_number = tswap32(i);
4127
                break;
4128
            }
4129
        }
4130
    }
4131
    unlock_user_struct(target_ldt_info, ptr, 1);
4132

    
4133
    if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || 
4134
        ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
4135
           return -TARGET_EINVAL;
4136
    seg_32bit = ldt_info.flags & 1;
4137
    contents = (ldt_info.flags >> 1) & 3;
4138
    read_exec_only = (ldt_info.flags >> 3) & 1;
4139
    limit_in_pages = (ldt_info.flags >> 4) & 1;
4140
    seg_not_present = (ldt_info.flags >> 5) & 1;
4141
    useable = (ldt_info.flags >> 6) & 1;
4142
#ifdef TARGET_ABI32
4143
    lm = 0;
4144
#else
4145
    lm = (ldt_info.flags >> 7) & 1;
4146
#endif
4147

    
4148
    if (contents == 3) {
4149
        if (seg_not_present == 0)
4150
            return -TARGET_EINVAL;
4151
    }
4152

    
4153
    /* NOTE: same code as Linux kernel */
4154
    /* Allow LDTs to be cleared by the user. */
4155
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
4156
        if ((contents == 0             &&
4157
             read_exec_only == 1       &&
4158
             seg_32bit == 0            &&
4159
             limit_in_pages == 0       &&
4160
             seg_not_present == 1      &&
4161
             useable == 0 )) {
4162
            entry_1 = 0;
4163
            entry_2 = 0;
4164
            goto install;
4165
        }
4166
    }
4167

    
4168
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
4169
        (ldt_info.limit & 0x0ffff);
4170
    entry_2 = (ldt_info.base_addr & 0xff000000) |
4171
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
4172
        (ldt_info.limit & 0xf0000) |
4173
        ((read_exec_only ^ 1) << 9) |
4174
        (contents << 10) |
4175
        ((seg_not_present ^ 1) << 15) |
4176
        (seg_32bit << 22) |
4177
        (limit_in_pages << 23) |
4178
        (useable << 20) |
4179
        (lm << 21) |
4180
        0x7000;
4181

    
4182
    /* Install the new entry ...  */
4183
install:
4184
    lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
4185
    lp[0] = tswap32(entry_1);
4186
    lp[1] = tswap32(entry_2);
4187
    return 0;
4188
}
4189

    
4190
static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
4191
{
4192
    struct target_modify_ldt_ldt_s *target_ldt_info;
4193
    uint64_t *gdt_table = g2h(env->gdt.base);
4194
    uint32_t base_addr, limit, flags;
4195
    int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
4196
    int seg_not_present, useable, lm;
4197
    uint32_t *lp, entry_1, entry_2;
4198

    
4199
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
4200
    if (!target_ldt_info)
4201
        return -TARGET_EFAULT;
4202
    idx = tswap32(target_ldt_info->entry_number);
4203
    if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
4204
        idx > TARGET_GDT_ENTRY_TLS_MAX) {
4205
        unlock_user_struct(target_ldt_info, ptr, 1);
4206
        return -TARGET_EINVAL;
4207
    }
4208
    lp = (uint32_t *)(gdt_table + idx);
4209
    entry_1 = tswap32(lp[0]);
4210
    entry_2 = tswap32(lp[1]);
4211
    
4212
    read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
4213
    contents = (entry_2 >> 10) & 3;
4214
    seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
4215
    seg_32bit = (entry_2 >> 22) & 1;
4216
    limit_in_pages = (entry_2 >> 23) & 1;
4217
    useable = (entry_2 >> 20) & 1;
4218
#ifdef TARGET_ABI32
4219
    lm = 0;
4220
#else
4221
    lm = (entry_2 >> 21) & 1;
4222
#endif
4223
    flags = (seg_32bit << 0) | (contents << 1) |
4224
        (read_exec_only << 3) | (limit_in_pages << 4) |
4225
        (seg_not_present << 5) | (useable << 6) | (lm << 7);
4226
    limit = (entry_1 & 0xffff) | (entry_2  & 0xf0000);
4227
    base_addr = (entry_1 >> 16) | 
4228
        (entry_2 & 0xff000000) | 
4229
        ((entry_2 & 0xff) << 16);
4230
    target_ldt_info->base_addr = tswapal(base_addr);
4231
    target_ldt_info->limit = tswap32(limit);
4232
    target_ldt_info->flags = tswap32(flags);
4233
    unlock_user_struct(target_ldt_info, ptr, 1);
4234
    return 0;
4235
}
4236
#endif /* TARGET_I386 && TARGET_ABI32 */
4237

    
4238
#ifndef TARGET_ABI32
4239
static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
4240
{
4241
    abi_long ret = 0;
4242
    abi_ulong val;
4243
    int idx;
4244

    
4245
    switch(code) {
4246
    case TARGET_ARCH_SET_GS:
4247
    case TARGET_ARCH_SET_FS:
4248
        if (code == TARGET_ARCH_SET_GS)
4249
            idx = R_GS;
4250
        else
4251
            idx = R_FS;
4252
        cpu_x86_load_seg(env, idx, 0);
4253
        env->segs[idx].base = addr;
4254
        break;
4255
    case TARGET_ARCH_GET_GS:
4256
    case TARGET_ARCH_GET_FS:
4257
        if (code == TARGET_ARCH_GET_GS)
4258
            idx = R_GS;
4259
        else
4260
            idx = R_FS;
4261
        val = env->segs[idx].base;
4262
        if (put_user(val, addr, abi_ulong))
4263
            ret = -TARGET_EFAULT;
4264
        break;
4265
    default:
4266
        ret = -TARGET_EINVAL;
4267
        break;
4268
    }
4269
    return ret;
4270
}
4271
#endif
4272

    
4273
#endif /* defined(TARGET_I386) */
4274

    
4275
#define NEW_STACK_SIZE 0x40000
4276

    
4277
#if defined(CONFIG_USE_NPTL)
4278

    
4279
static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
4280
typedef struct {
4281
    CPUArchState *env;
4282
    pthread_mutex_t mutex;
4283
    pthread_cond_t cond;
4284
    pthread_t thread;
4285
    uint32_t tid;
4286
    abi_ulong child_tidptr;
4287
    abi_ulong parent_tidptr;
4288
    sigset_t sigmask;
4289
} new_thread_info;
4290

    
4291
static void *clone_func(void *arg)
4292
{
4293
    new_thread_info *info = arg;
4294
    CPUArchState *env;
4295
    TaskState *ts;
4296

    
4297
    env = info->env;
4298
    thread_env = env;
4299
    ts = (TaskState *)thread_env->opaque;
4300
    info->tid = gettid();
4301
    env->host_tid = info->tid;
4302
    task_settid(ts);
4303
    if (info->child_tidptr)
4304
        put_user_u32(info->tid, info->child_tidptr);
4305
    if (info->parent_tidptr)
4306
        put_user_u32(info->tid, info->parent_tidptr);
4307
    /* Enable signals.  */
4308
    sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
4309
    /* Signal to the parent that we're ready.  */
4310
    pthread_mutex_lock(&info->mutex);
4311
    pthread_cond_broadcast(&info->cond);
4312
    pthread_mutex_unlock(&info->mutex);
4313
    /* Wait until the parent has finshed initializing the tls state.  */
4314
    pthread_mutex_lock(&clone_lock);
4315
    pthread_mutex_unlock(&clone_lock);
4316
    cpu_loop(env);
4317
    /* never exits */
4318
    return NULL;
4319
}
4320
#else
4321

    
4322
static int clone_func(void *arg)
4323
{
4324
    CPUArchState *env = arg;
4325
    cpu_loop(env);
4326
    /* never exits */
4327
    return 0;
4328
}
4329
#endif
4330

    
4331
/* do_fork() Must return host values and target errnos (unlike most
4332
   do_*() functions). */
4333
static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
4334
                   abi_ulong parent_tidptr, target_ulong newtls,
4335
                   abi_ulong child_tidptr)
4336
{
4337
    int ret;
4338
    TaskState *ts;
4339
    CPUArchState *new_env;
4340
#if defined(CONFIG_USE_NPTL)
4341
    unsigned int nptl_flags;
4342
    sigset_t sigmask;
4343
#else
4344
    uint8_t *new_stack;
4345
#endif
4346

    
4347
    /* Emulate vfork() with fork() */
4348
    if (flags & CLONE_VFORK)
4349
        flags &= ~(CLONE_VFORK | CLONE_VM);
4350

    
4351
    if (flags & CLONE_VM) {
4352
        TaskState *parent_ts = (TaskState *)env->opaque;
4353
#if defined(CONFIG_USE_NPTL)
4354
        new_thread_info info;
4355
        pthread_attr_t attr;
4356
#endif
4357
        ts = g_malloc0(sizeof(TaskState));
4358
        init_task_state(ts);
4359
        /* we create a new CPU instance. */
4360
        new_env = cpu_copy(env);
4361
#if defined(TARGET_I386) || defined(TARGET_SPARC) || defined(TARGET_PPC)
4362
        cpu_reset(ENV_GET_CPU(new_env));
4363
#endif
4364
        /* Init regs that differ from the parent.  */
4365
        cpu_clone_regs(new_env, newsp);
4366
        new_env->opaque = ts;
4367
        ts->bprm = parent_ts->bprm;
4368
        ts->info = parent_ts->info;
4369
#if defined(CONFIG_USE_NPTL)
4370
        nptl_flags = flags;
4371
        flags &= ~CLONE_NPTL_FLAGS2;
4372

    
4373
        if (nptl_flags & CLONE_CHILD_CLEARTID) {
4374
            ts->child_tidptr = child_tidptr;
4375
        }
4376

    
4377
        if (nptl_flags & CLONE_SETTLS)
4378
            cpu_set_tls (new_env, newtls);
4379

    
4380
        /* Grab a mutex so that thread setup appears atomic.  */
4381
        pthread_mutex_lock(&clone_lock);
4382

    
4383
        memset(&info, 0, sizeof(info));
4384
        pthread_mutex_init(&info.mutex, NULL);
4385
        pthread_mutex_lock(&info.mutex);
4386
        pthread_cond_init(&info.cond, NULL);
4387
        info.env = new_env;
4388
        if (nptl_flags & CLONE_CHILD_SETTID)
4389
            info.child_tidptr = child_tidptr;
4390
        if (nptl_flags & CLONE_PARENT_SETTID)
4391
            info.parent_tidptr = parent_tidptr;
4392

    
4393
        ret = pthread_attr_init(&attr);
4394
        ret = pthread_attr_setstacksize(&attr, NEW_STACK_SIZE);
4395
        ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
4396
        /* It is not safe to deliver signals until the child has finished
4397
           initializing, so temporarily block all signals.  */
4398
        sigfillset(&sigmask);
4399
        sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
4400

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

    
4404
        sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
4405
        pthread_attr_destroy(&attr);
4406
        if (ret == 0) {
4407
            /* Wait for the child to initialize.  */
4408
            pthread_cond_wait(&info.cond, &info.mutex);
4409
            ret = info.tid;
4410
            if (flags & CLONE_PARENT_SETTID)
4411
                put_user_u32(ret, parent_tidptr);
4412
        } else {
4413
            ret = -1;
4414
        }
4415
        pthread_mutex_unlock(&info.mutex);
4416
        pthread_cond_destroy(&info.cond);
4417
        pthread_mutex_destroy(&info.mutex);
4418
        pthread_mutex_unlock(&clone_lock);
4419
#else
4420
        if (flags & CLONE_NPTL_FLAGS2)
4421
            return -EINVAL;
4422
        /* This is probably going to die very quickly, but do it anyway.  */
4423
        new_stack = g_malloc0 (NEW_STACK_SIZE);
4424
#ifdef __ia64__
4425
        ret = __clone2(clone_func, new_stack, NEW_STACK_SIZE, flags, new_env);
4426
#else
4427
        ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
4428
#endif
4429
#endif
4430
    } else {
4431
        /* if no CLONE_VM, we consider it is a fork */
4432
        if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
4433
            return -EINVAL;
4434
        fork_start();
4435
        ret = fork();
4436
        if (ret == 0) {
4437
            /* Child Process.  */
4438
            cpu_clone_regs(env, newsp);
4439
            fork_end(1);
4440
#if defined(CONFIG_USE_NPTL)
4441
            /* There is a race condition here.  The parent process could
4442
               theoretically read the TID in the child process before the child
4443
               tid is set.  This would require using either ptrace
4444
               (not implemented) or having *_tidptr to point at a shared memory
4445
               mapping.  We can't repeat the spinlock hack used above because
4446
               the child process gets its own copy of the lock.  */
4447
            if (flags & CLONE_CHILD_SETTID)
4448
                put_user_u32(gettid(), child_tidptr);
4449
            if (flags & CLONE_PARENT_SETTID)
4450
                put_user_u32(gettid(), parent_tidptr);
4451
            ts = (TaskState *)env->opaque;
4452
            if (flags & CLONE_SETTLS)
4453
                cpu_set_tls (env, newtls);
4454
            if (flags & CLONE_CHILD_CLEARTID)
4455
                ts->child_tidptr = child_tidptr;
4456
#endif
4457
        } else {
4458
            fork_end(0);
4459
        }
4460
    }
4461
    return ret;
4462
}
4463

    
4464
/* warning : doesn't handle linux specific flags... */
4465
static int target_to_host_fcntl_cmd(int cmd)
4466
{
4467
    switch(cmd) {
4468
        case TARGET_F_DUPFD:
4469
        case TARGET_F_GETFD:
4470
        case TARGET_F_SETFD:
4471
        case TARGET_F_GETFL:
4472
        case TARGET_F_SETFL:
4473
            return cmd;
4474
        case TARGET_F_GETLK:
4475
            return F_GETLK;
4476
        case TARGET_F_SETLK:
4477
            return F_SETLK;
4478
        case TARGET_F_SETLKW:
4479
            return F_SETLKW;
4480
        case TARGET_F_GETOWN:
4481
            return F_GETOWN;
4482
        case TARGET_F_SETOWN:
4483
            return F_SETOWN;
4484
        case TARGET_F_GETSIG:
4485
            return F_GETSIG;
4486
        case TARGET_F_SETSIG:
4487
            return F_SETSIG;
4488
#if TARGET_ABI_BITS == 32
4489
        case TARGET_F_GETLK64:
4490
            return F_GETLK64;
4491
        case TARGET_F_SETLK64:
4492
            return F_SETLK64;
4493
        case TARGET_F_SETLKW64:
4494
            return F_SETLKW64;
4495
#endif
4496
        case TARGET_F_SETLEASE:
4497
            return F_SETLEASE;
4498
        case TARGET_F_GETLEASE:
4499
            return F_GETLEASE;
4500
#ifdef F_DUPFD_CLOEXEC
4501
        case TARGET_F_DUPFD_CLOEXEC:
4502
            return F_DUPFD_CLOEXEC;
4503
#endif
4504
        case TARGET_F_NOTIFY:
4505
            return F_NOTIFY;
4506
        default:
4507
            return -TARGET_EINVAL;
4508
    }
4509
    return -TARGET_EINVAL;
4510
}
4511

    
4512
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
4513
{
4514
    struct flock fl;
4515
    struct target_flock *target_fl;
4516
    struct flock64 fl64;
4517
    struct target_flock64 *target_fl64;
4518
    abi_long ret;
4519
    int host_cmd = target_to_host_fcntl_cmd(cmd);
4520

    
4521
    if (host_cmd == -TARGET_EINVAL)
4522
            return host_cmd;
4523

    
4524
    switch(cmd) {
4525
    case TARGET_F_GETLK:
4526
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
4527
            return -TARGET_EFAULT;
4528
        fl.l_type = tswap16(target_fl->l_type);
4529
        fl.l_whence = tswap16(target_fl->l_whence);
4530
        fl.l_start = tswapal(target_fl->l_start);
4531
        fl.l_len = tswapal(target_fl->l_len);
4532
        fl.l_pid = tswap32(target_fl->l_pid);
4533
        unlock_user_struct(target_fl, arg, 0);
4534
        ret = get_errno(fcntl(fd, host_cmd, &fl));
4535
        if (ret == 0) {
4536
            if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
4537
                return -TARGET_EFAULT;
4538
            target_fl->l_type = tswap16(fl.l_type);
4539
            target_fl->l_whence = tswap16(fl.l_whence);
4540
            target_fl->l_start = tswapal(fl.l_start);
4541
            target_fl->l_len = tswapal(fl.l_len);
4542
            target_fl->l_pid = tswap32(fl.l_pid);
4543
            unlock_user_struct(target_fl, arg, 1);
4544
        }
4545
        break;
4546

    
4547
    case TARGET_F_SETLK:
4548
    case TARGET_F_SETLKW:
4549
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
4550
            return -TARGET_EFAULT;
4551
        fl.l_type = tswap16(target_fl->l_type);
4552
        fl.l_whence = tswap16(target_fl->l_whence);
4553
        fl.l_start = tswapal(target_fl->l_start);
4554
        fl.l_len = tswapal(target_fl->l_len);
4555
        fl.l_pid = tswap32(target_fl->l_pid);
4556
        unlock_user_struct(target_fl, arg, 0);
4557
        ret = get_errno(fcntl(fd, host_cmd, &fl));
4558
        break;
4559

    
4560
    case TARGET_F_GETLK64:
4561
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
4562
            return -TARGET_EFAULT;
4563
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
4564
        fl64.l_whence = tswap16(target_fl64->l_whence);
4565
        fl64.l_start = tswap64(target_fl64->l_start);
4566
        fl64.l_len = tswap64(target_fl64->l_len);
4567
        fl64.l_pid = tswap32(target_fl64->l_pid);
4568
        unlock_user_struct(target_fl64, arg, 0);
4569
        ret = get_errno(fcntl(fd, host_cmd, &fl64));
4570
        if (ret == 0) {
4571
            if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
4572
                return -TARGET_EFAULT;
4573
            target_fl64->l_type = tswap16(fl64.l_type) >> 1;
4574
            target_fl64->l_whence = tswap16(fl64.l_whence);
4575
            target_fl64->l_start = tswap64(fl64.l_start);
4576
            target_fl64->l_len = tswap64(fl64.l_len);
4577
            target_fl64->l_pid = tswap32(fl64.l_pid);
4578
            unlock_user_struct(target_fl64, arg, 1);
4579
        }
4580
        break;
4581
    case TARGET_F_SETLK64:
4582
    case TARGET_F_SETLKW64:
4583
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
4584
            return -TARGET_EFAULT;
4585
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
4586
        fl64.l_whence = tswap16(target_fl64->l_whence);
4587
        fl64.l_start = tswap64(target_fl64->l_start);
4588
        fl64.l_len = tswap64(target_fl64->l_len);
4589
        fl64.l_pid = tswap32(target_fl64->l_pid);
4590
        unlock_user_struct(target_fl64, arg, 0);
4591
        ret = get_errno(fcntl(fd, host_cmd, &fl64));
4592
        break;
4593

    
4594
    case TARGET_F_GETFL:
4595
        ret = get_errno(fcntl(fd, host_cmd, arg));
4596
        if (ret >= 0) {
4597
            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
4598
        }
4599
        break;
4600

    
4601
    case TARGET_F_SETFL:
4602
        ret = get_errno(fcntl(fd, host_cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
4603
        break;
4604

    
4605
    case TARGET_F_SETOWN:
4606
    case TARGET_F_GETOWN:
4607
    case TARGET_F_SETSIG:
4608
    case TARGET_F_GETSIG:
4609
    case TARGET_F_SETLEASE:
4610
    case TARGET_F_GETLEASE:
4611
        ret = get_errno(fcntl(fd, host_cmd, arg));
4612
        break;
4613

    
4614
    default:
4615
        ret = get_errno(fcntl(fd, cmd, arg));
4616
        break;
4617
    }
4618
    return ret;
4619
}
4620

    
4621
#ifdef USE_UID16
4622

    
4623
static inline int high2lowuid(int uid)
4624
{
4625
    if (uid > 65535)
4626
        return 65534;
4627
    else
4628
        return uid;
4629
}
4630

    
4631
static inline int high2lowgid(int gid)
4632
{
4633
    if (gid > 65535)
4634
        return 65534;
4635
    else
4636
        return gid;
4637
}
4638

    
4639
static inline int low2highuid(int uid)
4640
{
4641
    if ((int16_t)uid == -1)
4642
        return -1;
4643
    else
4644
        return uid;
4645
}
4646

    
4647
static inline int low2highgid(int gid)
4648
{
4649
    if ((int16_t)gid == -1)
4650
        return -1;
4651
    else
4652
        return gid;
4653
}
4654
static inline int tswapid(int id)
4655
{
4656
    return tswap16(id);
4657
}
4658
#else /* !USE_UID16 */
4659
static inline int high2lowuid(int uid)
4660
{
4661
    return uid;
4662
}
4663
static inline int high2lowgid(int gid)
4664
{
4665
    return gid;
4666
}
4667
static inline int low2highuid(int uid)
4668
{
4669
    return uid;
4670
}
4671
static inline int low2highgid(int gid)
4672
{
4673
    return gid;
4674
}
4675
static inline int tswapid(int id)
4676
{
4677
    return tswap32(id);
4678
}
4679
#endif /* USE_UID16 */
4680

    
4681
void syscall_init(void)
4682
{
4683
    IOCTLEntry *ie;
4684
    const argtype *arg_type;
4685
    int size;
4686
    int i;
4687

    
4688
#define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
4689
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
4690
#include "syscall_types.h"
4691
#undef STRUCT
4692
#undef STRUCT_SPECIAL
4693

    
4694
    /* Build target_to_host_errno_table[] table from
4695
     * host_to_target_errno_table[]. */
4696
    for (i = 0; i < ERRNO_TABLE_SIZE; i++) {
4697
        target_to_host_errno_table[host_to_target_errno_table[i]] = i;
4698
    }
4699

    
4700
    /* we patch the ioctl size if necessary. We rely on the fact that
4701
       no ioctl has all the bits at '1' in the size field */
4702
    ie = ioctl_entries;
4703
    while (ie->target_cmd != 0) {
4704
        if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
4705
            TARGET_IOC_SIZEMASK) {
4706
            arg_type = ie->arg_type;
4707
            if (arg_type[0] != TYPE_PTR) {
4708
                fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
4709
                        ie->target_cmd);
4710
                exit(1);
4711
            }
4712
            arg_type++;
4713
            size = thunk_type_size(arg_type, 0);
4714
            ie->target_cmd = (ie->target_cmd &
4715
                              ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
4716
                (size << TARGET_IOC_SIZESHIFT);
4717
        }
4718

    
4719
        /* automatic consistency check if same arch */
4720
#if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
4721
    (defined(__x86_64__) && defined(TARGET_X86_64))
4722
        if (unlikely(ie->target_cmd != ie->host_cmd)) {
4723
            fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
4724
                    ie->name, ie->target_cmd, ie->host_cmd);
4725
        }
4726
#endif
4727
        ie++;
4728
    }
4729
}
4730

    
4731
#if TARGET_ABI_BITS == 32
4732
static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
4733
{
4734
#ifdef TARGET_WORDS_BIGENDIAN
4735
    return ((uint64_t)word0 << 32) | word1;
4736
#else
4737
    return ((uint64_t)word1 << 32) | word0;
4738
#endif
4739
}
4740
#else /* TARGET_ABI_BITS == 32 */
4741
static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
4742
{
4743
    return word0;
4744
}
4745
#endif /* TARGET_ABI_BITS != 32 */
4746

    
4747
#ifdef TARGET_NR_truncate64
4748
static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
4749
                                         abi_long arg2,
4750
                                         abi_long arg3,
4751
                                         abi_long arg4)
4752
{
4753
    if (regpairs_aligned(cpu_env)) {
4754
        arg2 = arg3;
4755
        arg3 = arg4;
4756
    }
4757
    return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
4758
}
4759
#endif
4760

    
4761
#ifdef TARGET_NR_ftruncate64
4762
static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
4763
                                          abi_long arg2,
4764
                                          abi_long arg3,
4765
                                          abi_long arg4)
4766
{
4767
    if (regpairs_aligned(cpu_env)) {
4768
        arg2 = arg3;
4769
        arg3 = arg4;
4770
    }
4771
    return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
4772
}
4773
#endif
4774

    
4775
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
4776
                                               abi_ulong target_addr)
4777
{
4778
    struct target_timespec *target_ts;
4779

    
4780
    if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
4781
        return -TARGET_EFAULT;
4782
    host_ts->tv_sec = tswapal(target_ts->tv_sec);
4783
    host_ts->tv_nsec = tswapal(target_ts->tv_nsec);
4784
    unlock_user_struct(target_ts, target_addr, 0);
4785
    return 0;
4786
}
4787

    
4788
static inline abi_long host_to_target_timespec(abi_ulong target_addr,
4789
                                               struct timespec *host_ts)
4790
{
4791
    struct target_timespec *target_ts;
4792

    
4793
    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
4794
        return -TARGET_EFAULT;
4795
    target_ts->tv_sec = tswapal(host_ts->tv_sec);
4796
    target_ts->tv_nsec = tswapal(host_ts->tv_nsec);
4797
    unlock_user_struct(target_ts, target_addr, 1);
4798
    return 0;
4799
}
4800

    
4801
#if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
4802
static inline abi_long host_to_target_stat64(void *cpu_env,
4803
                                             abi_ulong target_addr,
4804
                                             struct stat *host_st)
4805
{
4806
#ifdef TARGET_ARM
4807
    if (((CPUARMState *)cpu_env)->eabi) {
4808
        struct target_eabi_stat64 *target_st;
4809

    
4810
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
4811
            return -TARGET_EFAULT;
4812
        memset(target_st, 0, sizeof(struct target_eabi_stat64));
4813
        __put_user(host_st->st_dev, &target_st->st_dev);
4814
        __put_user(host_st->st_ino, &target_st->st_ino);
4815
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4816
        __put_user(host_st->st_ino, &target_st->__st_ino);
4817
#endif
4818
        __put_user(host_st->st_mode, &target_st->st_mode);
4819
        __put_user(host_st->st_nlink, &target_st->st_nlink);
4820
        __put_user(host_st->st_uid, &target_st->st_uid);
4821
        __put_user(host_st->st_gid, &target_st->st_gid);
4822
        __put_user(host_st->st_rdev, &target_st->st_rdev);
4823
        __put_user(host_st->st_size, &target_st->st_size);
4824
        __put_user(host_st->st_blksize, &target_st->st_blksize);
4825
        __put_user(host_st->st_blocks, &target_st->st_blocks);
4826
        __put_user(host_st->st_atime, &target_st->target_st_atime);
4827
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
4828
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
4829
        unlock_user_struct(target_st, target_addr, 1);
4830
    } else
4831
#endif
4832
    {
4833
#if TARGET_ABI_BITS == 64 && !defined(TARGET_ALPHA)
4834
        struct target_stat *target_st;
4835
#else
4836
        struct target_stat64 *target_st;
4837
#endif
4838

    
4839
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
4840
            return -TARGET_EFAULT;
4841
        memset(target_st, 0, sizeof(*target_st));
4842
        __put_user(host_st->st_dev, &target_st->st_dev);
4843
        __put_user(host_st->st_ino, &target_st->st_ino);
4844
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4845
        __put_user(host_st->st_ino, &target_st->__st_ino);
4846
#endif
4847
        __put_user(host_st->st_mode, &target_st->st_mode);
4848
        __put_user(host_st->st_nlink, &target_st->st_nlink);
4849
        __put_user(host_st->st_uid, &target_st->st_uid);
4850
        __put_user(host_st->st_gid, &target_st->st_gid);
4851
        __put_user(host_st->st_rdev, &target_st->st_rdev);
4852
        /* XXX: better use of kernel struct */
4853
        __put_user(host_st->st_size, &target_st->st_size);
4854
        __put_user(host_st->st_blksize, &target_st->st_blksize);
4855
        __put_user(host_st->st_blocks, &target_st->st_blocks);
4856
        __put_user(host_st->st_atime, &target_st->target_st_atime);
4857
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
4858
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
4859
        unlock_user_struct(target_st, target_addr, 1);
4860
    }
4861

    
4862
    return 0;
4863
}
4864
#endif
4865

    
4866
#if defined(CONFIG_USE_NPTL)
4867
/* ??? Using host futex calls even when target atomic operations
4868
   are not really atomic probably breaks things.  However implementing
4869
   futexes locally would make futexes shared between multiple processes
4870
   tricky.  However they're probably useless because guest atomic
4871
   operations won't work either.  */
4872
static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
4873
                    target_ulong uaddr2, int val3)
4874
{
4875
    struct timespec ts, *pts;
4876
    int base_op;
4877

    
4878
    /* ??? We assume FUTEX_* constants are the same on both host
4879
       and target.  */
4880
#ifdef FUTEX_CMD_MASK
4881
    base_op = op & FUTEX_CMD_MASK;
4882
#else
4883
    base_op = op;
4884
#endif
4885
    switch (base_op) {
4886
    case FUTEX_WAIT:
4887
        if (timeout) {
4888
            pts = &ts;
4889
            target_to_host_timespec(pts, timeout);
4890
        } else {
4891
            pts = NULL;
4892
        }
4893
        return get_errno(sys_futex(g2h(uaddr), op, tswap32(val),
4894
                         pts, NULL, 0));
4895
    case FUTEX_WAKE:
4896
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4897
    case FUTEX_FD:
4898
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4899
    case FUTEX_REQUEUE:
4900
    case FUTEX_CMP_REQUEUE:
4901
    case FUTEX_WAKE_OP:
4902
        /* For FUTEX_REQUEUE, FUTEX_CMP_REQUEUE, and FUTEX_WAKE_OP, the
4903
           TIMEOUT parameter is interpreted as a uint32_t by the kernel.
4904
           But the prototype takes a `struct timespec *'; insert casts
4905
           to satisfy the compiler.  We do not need to tswap TIMEOUT
4906
           since it's not compared to guest memory.  */
4907
        pts = (struct timespec *)(uintptr_t) timeout;
4908
        return get_errno(sys_futex(g2h(uaddr), op, val, pts,
4909
                                   g2h(uaddr2),
4910
                                   (base_op == FUTEX_CMP_REQUEUE
4911
                                    ? tswap32(val3)
4912
                                    : val3)));
4913
    default:
4914
        return -TARGET_ENOSYS;
4915
    }
4916
}
4917
#endif
4918

    
4919
/* Map host to target signal numbers for the wait family of syscalls.
4920
   Assume all other status bits are the same.  */
4921
int host_to_target_waitstatus(int status)
4922
{
4923
    if (WIFSIGNALED(status)) {
4924
        return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f);
4925
    }
4926
    if (WIFSTOPPED(status)) {
4927
        return (host_to_target_signal(WSTOPSIG(status)) << 8)
4928
               | (status & 0xff);
4929
    }
4930
    return status;
4931
}
4932

    
4933
int get_osversion(void)
4934
{
4935
    static int osversion;
4936
    struct new_utsname buf;
4937
    const char *s;
4938
    int i, n, tmp;
4939
    if (osversion)
4940
        return osversion;
4941
    if (qemu_uname_release && *qemu_uname_release) {
4942
        s = qemu_uname_release;
4943
    } else {
4944
        if (sys_uname(&buf))
4945
            return 0;
4946
        s = buf.release;
4947
    }
4948
    tmp = 0;
4949
    for (i = 0; i < 3; i++) {
4950
        n = 0;
4951
        while (*s >= '0' && *s <= '9') {
4952
            n *= 10;
4953
            n += *s - '0';
4954
            s++;
4955
        }
4956
        tmp = (tmp << 8) + n;
4957
        if (*s == '.')
4958
            s++;
4959
    }
4960
    osversion = tmp;
4961
    return osversion;
4962
}
4963

    
4964

    
4965
static int open_self_maps(void *cpu_env, int fd)
4966
{
4967
#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
4968
    TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
4969
#endif
4970
    FILE *fp;
4971
    char *line = NULL;
4972
    size_t len = 0;
4973
    ssize_t read;
4974

    
4975
    fp = fopen("/proc/self/maps", "r");
4976
    if (fp == NULL) {
4977
        return -EACCES;
4978
    }
4979

    
4980
    while ((read = getline(&line, &len, fp)) != -1) {
4981
        int fields, dev_maj, dev_min, inode;
4982
        uint64_t min, max, offset;
4983
        char flag_r, flag_w, flag_x, flag_p;
4984
        char path[512] = "";
4985
        fields = sscanf(line, "%"PRIx64"-%"PRIx64" %c%c%c%c %"PRIx64" %x:%x %d"
4986
                        " %512s", &min, &max, &flag_r, &flag_w, &flag_x,
4987
                        &flag_p, &offset, &dev_maj, &dev_min, &inode, path);
4988

    
4989
        if ((fields < 10) || (fields > 11)) {
4990
            continue;
4991
        }
4992
        if (!strncmp(path, "[stack]", 7)) {
4993
            continue;
4994
        }
4995
        if (h2g_valid(min) && h2g_valid(max)) {
4996
            dprintf(fd, TARGET_ABI_FMT_lx "-" TARGET_ABI_FMT_lx
4997
                    " %c%c%c%c %08" PRIx64 " %02x:%02x %d%s%s\n",
4998
                    h2g(min), h2g(max), flag_r, flag_w,
4999
                    flag_x, flag_p, offset, dev_maj, dev_min, inode,
5000
                    path[0] ? "          " : "", path);
5001
        }
5002
    }
5003

    
5004
    free(line);
5005
    fclose(fp);
5006

    
5007
#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
5008
    dprintf(fd, "%08llx-%08llx rw-p %08llx 00:00 0          [stack]\n",
5009
                (unsigned long long)ts->info->stack_limit,
5010
                (unsigned long long)(ts->info->start_stack +
5011
                                     (TARGET_PAGE_SIZE - 1)) & TARGET_PAGE_MASK,
5012
                (unsigned long long)0);
5013
#endif
5014

    
5015
    return 0;
5016
}
5017

    
5018
static int open_self_stat(void *cpu_env, int fd)
5019
{
5020
    TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
5021
    abi_ulong start_stack = ts->info->start_stack;
5022
    int i;
5023

    
5024
    for (i = 0; i < 44; i++) {
5025
      char buf[128];
5026
      int len;
5027
      uint64_t val = 0;
5028

    
5029
      if (i == 0) {
5030
        /* pid */
5031
        val = getpid();
5032
        snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
5033
      } else if (i == 1) {
5034
        /* app name */
5035
        snprintf(buf, sizeof(buf), "(%s) ", ts->bprm->argv[0]);
5036
      } else if (i == 27) {
5037
        /* stack bottom */
5038
        val = start_stack;
5039
        snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
5040
      } else {
5041
        /* for the rest, there is MasterCard */
5042
        snprintf(buf, sizeof(buf), "0%c", i == 43 ? '\n' : ' ');
5043
      }
5044

    
5045
      len = strlen(buf);
5046
      if (write(fd, buf, len) != len) {
5047
          return -1;
5048
      }
5049
    }
5050

    
5051
    return 0;
5052
}
5053

    
5054
static int open_self_auxv(void *cpu_env, int fd)
5055
{
5056
    TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
5057
    abi_ulong auxv = ts->info->saved_auxv;
5058
    abi_ulong len = ts->info->auxv_len;
5059
    char *ptr;
5060

    
5061
    /*
5062
     * Auxiliary vector is stored in target process stack.
5063
     * read in whole auxv vector and copy it to file
5064
     */
5065
    ptr = lock_user(VERIFY_READ, auxv, len, 0);
5066
    if (ptr != NULL) {
5067
        while (len > 0) {
5068
            ssize_t r;
5069
            r = write(fd, ptr, len);
5070
            if (r <= 0) {
5071
                break;
5072
            }
5073
            len -= r;
5074
            ptr += r;
5075
        }
5076
        lseek(fd, 0, SEEK_SET);
5077
        unlock_user(ptr, auxv, len);
5078
    }
5079

    
5080
    return 0;
5081
}
5082

    
5083
static int do_open(void *cpu_env, const char *pathname, int flags, mode_t mode)
5084
{
5085
    struct fake_open {
5086
        const char *filename;
5087
        int (*fill)(void *cpu_env, int fd);
5088
    };
5089
    const struct fake_open *fake_open;
5090
    static const struct fake_open fakes[] = {
5091
        { "/proc/self/maps", open_self_maps },
5092
        { "/proc/self/stat", open_self_stat },
5093
        { "/proc/self/auxv", open_self_auxv },
5094
        { NULL, NULL }
5095
    };
5096

    
5097
    for (fake_open = fakes; fake_open->filename; fake_open++) {
5098
        if (!strncmp(pathname, fake_open->filename,
5099
                     strlen(fake_open->filename))) {
5100
            break;
5101
        }
5102
    }
5103

    
5104
    if (fake_open->filename) {
5105
        const char *tmpdir;
5106
        char filename[PATH_MAX];
5107
        int fd, r;
5108

    
5109
        /* create temporary file to map stat to */
5110
        tmpdir = getenv("TMPDIR");
5111
        if (!tmpdir)
5112
            tmpdir = "/tmp";
5113
        snprintf(filename, sizeof(filename), "%s/qemu-open.XXXXXX", tmpdir);
5114
        fd = mkstemp(filename);
5115
        if (fd < 0) {
5116
            return fd;
5117
        }
5118
        unlink(filename);
5119

    
5120
        if ((r = fake_open->fill(cpu_env, fd))) {
5121
            close(fd);
5122
            return r;
5123
        }
5124
        lseek(fd, 0, SEEK_SET);
5125

    
5126
        return fd;
5127
    }
5128

    
5129
    return get_errno(open(path(pathname), flags, mode));
5130
}
5131

    
5132
/* do_syscall() should always have a single exit point at the end so
5133
   that actions, such as logging of syscall results, can be performed.
5134
   All errnos that do_syscall() returns must be -TARGET_<errcode>. */
5135
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
5136
                    abi_long arg2, abi_long arg3, abi_long arg4,
5137
                    abi_long arg5, abi_long arg6, abi_long arg7,
5138
                    abi_long arg8)
5139
{
5140
    abi_long ret;
5141
    struct stat st;
5142
    struct statfs stfs;
5143
    void *p;
5144

    
5145
#ifdef DEBUG
5146
    gemu_log("syscall %d", num);
5147
#endif
5148
    if(do_strace)
5149
        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
5150

    
5151
    switch(num) {
5152
    case TARGET_NR_exit:
5153
#ifdef CONFIG_USE_NPTL
5154
      /* In old applications this may be used to implement _exit(2).
5155
         However in threaded applictions it is used for thread termination,
5156
         and _exit_group is used for application termination.
5157
         Do thread termination if we have more then one thread.  */
5158
      /* FIXME: This probably breaks if a signal arrives.  We should probably
5159
         be disabling signals.  */
5160
      if (first_cpu->next_cpu) {
5161
          TaskState *ts;
5162
          CPUArchState **lastp;
5163
          CPUArchState *p;
5164

    
5165
          cpu_list_lock();
5166
          lastp = &first_cpu;
5167
          p = first_cpu;
5168
          while (p && p != (CPUArchState *)cpu_env) {
5169
              lastp = &p->next_cpu;
5170
              p = p->next_cpu;
5171
          }
5172
          /* If we didn't find the CPU for this thread then something is
5173
             horribly wrong.  */
5174
          if (!p)
5175
              abort();
5176
          /* Remove the CPU from the list.  */
5177
          *lastp = p->next_cpu;
5178
          cpu_list_unlock();
5179
          ts = ((CPUArchState *)cpu_env)->opaque;
5180
          if (ts->child_tidptr) {
5181
              put_user_u32(0, ts->child_tidptr);
5182
              sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
5183
                        NULL, NULL, 0);
5184
          }
5185
          thread_env = NULL;
5186
          object_delete(OBJECT(ENV_GET_CPU(cpu_env)));
5187
          g_free(ts);
5188
          pthread_exit(NULL);
5189
      }
5190
#endif
5191
#ifdef TARGET_GPROF
5192
        _mcleanup();
5193
#endif
5194
        gdb_exit(cpu_env, arg1);
5195
        _exit(arg1);
5196
        ret = 0; /* avoid warning */
5197
        break;
5198
    case TARGET_NR_read:
5199
        if (arg3 == 0)
5200
            ret = 0;
5201
        else {
5202
            if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5203
                goto efault;
5204
            ret = get_errno(read(arg1, p, arg3));
5205
            unlock_user(p, arg2, ret);
5206
        }
5207
        break;
5208
    case TARGET_NR_write:
5209
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5210
            goto efault;
5211
        ret = get_errno(write(arg1, p, arg3));
5212
        unlock_user(p, arg2, 0);
5213
        break;
5214
    case TARGET_NR_open:
5215
        if (!(p = lock_user_string(arg1)))
5216
            goto efault;
5217
        ret = get_errno(do_open(cpu_env, p,
5218
                                target_to_host_bitmask(arg2, fcntl_flags_tbl),
5219
                                arg3));
5220
        unlock_user(p, arg1, 0);
5221
        break;
5222
#if defined(TARGET_NR_openat) && defined(__NR_openat)
5223
    case TARGET_NR_openat:
5224
        if (!(p = lock_user_string(arg2)))
5225
            goto efault;
5226
        ret = get_errno(sys_openat(arg1,
5227
                                   path(p),
5228
                                   target_to_host_bitmask(arg3, fcntl_flags_tbl),
5229
                                   arg4));
5230
        unlock_user(p, arg2, 0);
5231
        break;
5232
#endif
5233
    case TARGET_NR_close:
5234
        ret = get_errno(close(arg1));
5235
        break;
5236
    case TARGET_NR_brk:
5237
        ret = do_brk(arg1);
5238
        break;
5239
    case TARGET_NR_fork:
5240
        ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
5241
        break;
5242
#ifdef TARGET_NR_waitpid
5243
    case TARGET_NR_waitpid:
5244
        {
5245
            int status;
5246
            ret = get_errno(waitpid(arg1, &status, arg3));
5247
            if (!is_error(ret) && arg2 && ret
5248
                && put_user_s32(host_to_target_waitstatus(status), arg2))
5249
                goto efault;
5250
        }
5251
        break;
5252
#endif
5253
#ifdef TARGET_NR_waitid
5254
    case TARGET_NR_waitid:
5255
        {
5256
            siginfo_t info;
5257
            info.si_pid = 0;
5258
            ret = get_errno(waitid(arg1, arg2, &info, arg4));
5259
            if (!is_error(ret) && arg3 && info.si_pid != 0) {
5260
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
5261
                    goto efault;
5262
                host_to_target_siginfo(p, &info);
5263
                unlock_user(p, arg3, sizeof(target_siginfo_t));
5264
            }
5265
        }
5266
        break;
5267
#endif
5268
#ifdef TARGET_NR_creat /* not on alpha */
5269
    case TARGET_NR_creat:
5270
        if (!(p = lock_user_string(arg1)))
5271
            goto efault;
5272
        ret = get_errno(creat(p, arg2));
5273
        unlock_user(p, arg1, 0);
5274
        break;
5275
#endif
5276
    case TARGET_NR_link:
5277
        {
5278
            void * p2;
5279
            p = lock_user_string(arg1);
5280
            p2 = lock_user_string(arg2);
5281
            if (!p || !p2)
5282
                ret = -TARGET_EFAULT;
5283
            else
5284
                ret = get_errno(link(p, p2));
5285
            unlock_user(p2, arg2, 0);
5286
            unlock_user(p, arg1, 0);
5287
        }
5288
        break;
5289
#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
5290
    case TARGET_NR_linkat:
5291
        {
5292
            void * p2 = NULL;
5293
            if (!arg2 || !arg4)
5294
                goto efault;
5295
            p  = lock_user_string(arg2);
5296
            p2 = lock_user_string(arg4);
5297
            if (!p || !p2)
5298
                ret = -TARGET_EFAULT;
5299
            else
5300
                ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
5301
            unlock_user(p, arg2, 0);
5302
            unlock_user(p2, arg4, 0);
5303
        }
5304
        break;
5305
#endif
5306
    case TARGET_NR_unlink:
5307
        if (!(p = lock_user_string(arg1)))
5308
            goto efault;
5309
        ret = get_errno(unlink(p));
5310
        unlock_user(p, arg1, 0);
5311
        break;
5312
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
5313
    case TARGET_NR_unlinkat:
5314
        if (!(p = lock_user_string(arg2)))
5315
            goto efault;
5316
        ret = get_errno(sys_unlinkat(arg1, p, arg3));
5317
        unlock_user(p, arg2, 0);
5318
        break;
5319
#endif
5320
    case TARGET_NR_execve:
5321
        {
5322
            char **argp, **envp;
5323
            int argc, envc;
5324
            abi_ulong gp;
5325
            abi_ulong guest_argp;
5326
            abi_ulong guest_envp;
5327
            abi_ulong addr;
5328
            char **q;
5329
            int total_size = 0;
5330

    
5331
            argc = 0;
5332
            guest_argp = arg2;
5333
            for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
5334
                if (get_user_ual(addr, gp))
5335
                    goto efault;
5336
                if (!addr)
5337
                    break;
5338
                argc++;
5339
            }
5340
            envc = 0;
5341
            guest_envp = arg3;
5342
            for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
5343
                if (get_user_ual(addr, gp))
5344
                    goto efault;
5345
                if (!addr)
5346
                    break;
5347
                envc++;
5348
            }
5349

    
5350
            argp = alloca((argc + 1) * sizeof(void *));
5351
            envp = alloca((envc + 1) * sizeof(void *));
5352

    
5353
            for (gp = guest_argp, q = argp; gp;
5354
                  gp += sizeof(abi_ulong), q++) {
5355
                if (get_user_ual(addr, gp))
5356
                    goto execve_efault;
5357
                if (!addr)
5358
                    break;
5359
                if (!(*q = lock_user_string(addr)))
5360
                    goto execve_efault;
5361
                total_size += strlen(*q) + 1;
5362
            }
5363
            *q = NULL;
5364

    
5365
            for (gp = guest_envp, q = envp; gp;
5366
                  gp += sizeof(abi_ulong), q++) {
5367
                if (get_user_ual(addr, gp))
5368
                    goto execve_efault;
5369
                if (!addr)
5370
                    break;
5371
                if (!(*q = lock_user_string(addr)))
5372
                    goto execve_efault;
5373
                total_size += strlen(*q) + 1;
5374
            }
5375
            *q = NULL;
5376

    
5377
            /* This case will not be caught by the host's execve() if its
5378
               page size is bigger than the target's. */
5379
            if (total_size > MAX_ARG_PAGES * TARGET_PAGE_SIZE) {
5380
                ret = -TARGET_E2BIG;
5381
                goto execve_end;
5382
            }
5383
            if (!(p = lock_user_string(arg1)))
5384
                goto execve_efault;
5385
            ret = get_errno(execve(p, argp, envp));
5386
            unlock_user(p, arg1, 0);
5387

    
5388
            goto execve_end;
5389

    
5390
        execve_efault:
5391
            ret = -TARGET_EFAULT;
5392

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

    
5814
            if (arg2) {
5815
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
5816
                    goto efault;
5817
                act._sa_handler = old_act->_sa_handler;
5818
                target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
5819
                act.sa_flags = old_act->sa_flags;
5820
                unlock_user_struct(old_act, arg2, 0);
5821
                pact = &act;
5822
            } else {
5823
                pact = NULL;
5824
            }
5825

    
5826
            ret = get_errno(do_sigaction(arg1, pact, &oact));
5827

    
5828
            if (!is_error(ret) && arg3) {
5829
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
5830
                    goto efault;
5831
                old_act->_sa_handler = oact._sa_handler;
5832
                old_act->sa_flags = oact.sa_flags;
5833
                old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
5834
                old_act->sa_mask.sig[1] = 0;
5835
                old_act->sa_mask.sig[2] = 0;
5836
                old_act->sa_mask.sig[3] = 0;
5837
                unlock_user_struct(old_act, arg3, 1);
5838
            }
5839
#else
5840
            struct target_old_sigaction *old_act;
5841
            struct target_sigaction act, oact, *pact;
5842
            if (arg2) {
5843
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
5844
                    goto efault;
5845
                act._sa_handler = old_act->_sa_handler;
5846
                target_siginitset(&act.sa_mask, old_act->sa_mask);
5847
                act.sa_flags = old_act->sa_flags;
5848
                act.sa_restorer = old_act->sa_restorer;
5849
                unlock_user_struct(old_act, arg2, 0);
5850
                pact = &act;
5851
            } else {
5852
                pact = NULL;
5853
            }
5854
            ret = get_errno(do_sigaction(arg1, pact, &oact));
5855
            if (!is_error(ret) && arg3) {
5856
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
5857
                    goto efault;
5858
                old_act->_sa_handler = oact._sa_handler;
5859
                old_act->sa_mask = oact.sa_mask.sig[0];
5860
                old_act->sa_flags = oact.sa_flags;
5861
                old_act->sa_restorer = oact.sa_restorer;
5862
                unlock_user_struct(old_act, arg3, 1);
5863
            }
5864
#endif
5865
        }
5866
        break;
5867
#endif
5868
    case TARGET_NR_rt_sigaction:
5869
        {
5870
#if defined(TARGET_ALPHA)
5871
            struct target_sigaction act, oact, *pact = 0;
5872
            struct target_rt_sigaction *rt_act;
5873
            /* ??? arg4 == sizeof(sigset_t).  */
5874
            if (arg2) {
5875
                if (!lock_user_struct(VERIFY_READ, rt_act, arg2, 1))
5876
                    goto efault;
5877
                act._sa_handler = rt_act->_sa_handler;
5878
                act.sa_mask = rt_act->sa_mask;
5879
                act.sa_flags = rt_act->sa_flags;
5880
                act.sa_restorer = arg5;
5881
                unlock_user_struct(rt_act, arg2, 0);
5882
                pact = &act;
5883
            }
5884
            ret = get_errno(do_sigaction(arg1, pact, &oact));
5885
            if (!is_error(ret) && arg3) {
5886
                if (!lock_user_struct(VERIFY_WRITE, rt_act, arg3, 0))
5887
                    goto efault;
5888
                rt_act->_sa_handler = oact._sa_handler;
5889
                rt_act->sa_mask = oact.sa_mask;
5890
                rt_act->sa_flags = oact.sa_flags;
5891
                unlock_user_struct(rt_act, arg3, 1);
5892
            }
5893
#else
5894
            struct target_sigaction *act;
5895
            struct target_sigaction *oact;
5896

    
5897
            if (arg2) {
5898
                if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
5899
                    goto efault;
5900
            } else
5901
                act = NULL;
5902
            if (arg3) {
5903
                if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
5904
                    ret = -TARGET_EFAULT;
5905
                    goto rt_sigaction_fail;
5906
                }
5907
            } else
5908
                oact = NULL;
5909
            ret = get_errno(do_sigaction(arg1, act, oact));
5910
        rt_sigaction_fail:
5911
            if (act)
5912
                unlock_user_struct(act, arg2, 0);
5913
            if (oact)
5914
                unlock_user_struct(oact, arg3, 1);
5915
#endif
5916
        }
5917
        break;
5918
#ifdef TARGET_NR_sgetmask /* not on alpha */
5919
    case TARGET_NR_sgetmask:
5920
        {
5921
            sigset_t cur_set;
5922
            abi_ulong target_set;
5923
            sigprocmask(0, NULL, &cur_set);
5924
            host_to_target_old_sigset(&target_set, &cur_set);
5925
            ret = target_set;
5926
        }
5927
        break;
5928
#endif
5929
#ifdef TARGET_NR_ssetmask /* not on alpha */
5930
    case TARGET_NR_ssetmask:
5931
        {
5932
            sigset_t set, oset, cur_set;
5933
            abi_ulong target_set = arg1;
5934
            sigprocmask(0, NULL, &cur_set);
5935
            target_to_host_old_sigset(&set, &target_set);
5936
            sigorset(&set, &set, &cur_set);
5937
            sigprocmask(SIG_SETMASK, &set, &oset);
5938
            host_to_target_old_sigset(&target_set, &oset);
5939
            ret = target_set;
5940
        }
5941
        break;
5942
#endif
5943
#ifdef TARGET_NR_sigprocmask
5944
    case TARGET_NR_sigprocmask:
5945
        {
5946
#if defined(TARGET_ALPHA)
5947
            sigset_t set, oldset;
5948
            abi_ulong mask;
5949
            int how;
5950

    
5951
            switch (arg1) {
5952
            case TARGET_SIG_BLOCK:
5953
                how = SIG_BLOCK;
5954
                break;
5955
            case TARGET_SIG_UNBLOCK:
5956
                how = SIG_UNBLOCK;
5957
                break;
5958
            case TARGET_SIG_SETMASK:
5959
                how = SIG_SETMASK;
5960
                break;
5961
            default:
5962
                ret = -TARGET_EINVAL;
5963
                goto fail;
5964
            }
5965
            mask = arg2;
5966
            target_to_host_old_sigset(&set, &mask);
5967

    
5968
            ret = get_errno(sigprocmask(how, &set, &oldset));
5969
            if (!is_error(ret)) {
5970
                host_to_target_old_sigset(&mask, &oldset);
5971
                ret = mask;
5972
                ((CPUAlphaState *)cpu_env)->ir[IR_V0] = 0; /* force no error */
5973
            }
5974
#else
5975
            sigset_t set, oldset, *set_ptr;
5976
            int how;
5977

    
5978
            if (arg2) {
5979
                switch (arg1) {
5980
                case TARGET_SIG_BLOCK:
5981
                    how = SIG_BLOCK;
5982
                    break;
5983
                case TARGET_SIG_UNBLOCK:
5984
                    how = SIG_UNBLOCK;
5985
                    break;
5986
                case TARGET_SIG_SETMASK:
5987
                    how = SIG_SETMASK;
5988
                    break;
5989
                default:
5990
                    ret = -TARGET_EINVAL;
5991
                    goto fail;
5992
                }
5993
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
5994
                    goto efault;
5995
                target_to_host_old_sigset(&set, p);
5996
                unlock_user(p, arg2, 0);
5997
                set_ptr = &set;
5998
            } else {
5999
                how = 0;
6000
                set_ptr = NULL;
6001
            }
6002
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
6003
            if (!is_error(ret) && arg3) {
6004
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
6005
                    goto efault;
6006
                host_to_target_old_sigset(p, &oldset);
6007
                unlock_user(p, arg3, sizeof(target_sigset_t));
6008
            }
6009
#endif
6010
        }
6011
        break;
6012
#endif
6013
    case TARGET_NR_rt_sigprocmask:
6014
        {
6015
            int how = arg1;
6016
            sigset_t set, oldset, *set_ptr;
6017

    
6018
            if (arg2) {
6019
                switch(how) {
6020
                case TARGET_SIG_BLOCK:
6021
                    how = SIG_BLOCK;
6022
                    break;
6023
                case TARGET_SIG_UNBLOCK:
6024
                    how = SIG_UNBLOCK;
6025
                    break;
6026
                case TARGET_SIG_SETMASK:
6027
                    how = SIG_SETMASK;
6028
                    break;
6029
                default:
6030
                    ret = -TARGET_EINVAL;
6031
                    goto fail;
6032
                }
6033
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
6034
                    goto efault;
6035
                target_to_host_sigset(&set, p);
6036
                unlock_user(p, arg2, 0);
6037
                set_ptr = &set;
6038
            } else {
6039
                how = 0;
6040
                set_ptr = NULL;
6041
            }
6042
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
6043
            if (!is_error(ret) && arg3) {
6044
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
6045
                    goto efault;
6046
                host_to_target_sigset(p, &oldset);
6047
                unlock_user(p, arg3, sizeof(target_sigset_t));
6048
            }
6049
        }
6050
        break;
6051
#ifdef TARGET_NR_sigpending
6052
    case TARGET_NR_sigpending:
6053
        {
6054
            sigset_t set;
6055
            ret = get_errno(sigpending(&set));
6056
            if (!is_error(ret)) {
6057
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
6058
                    goto efault;
6059
                host_to_target_old_sigset(p, &set);
6060
                unlock_user(p, arg1, sizeof(target_sigset_t));
6061
            }
6062
        }
6063
        break;
6064
#endif
6065
    case TARGET_NR_rt_sigpending:
6066
        {
6067
            sigset_t set;
6068
            ret = get_errno(sigpending(&set));
6069
            if (!is_error(ret)) {
6070
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
6071
                    goto efault;
6072
                host_to_target_sigset(p, &set);
6073
                unlock_user(p, arg1, sizeof(target_sigset_t));
6074
            }
6075
        }
6076
        break;
6077
#ifdef TARGET_NR_sigsuspend
6078
    case TARGET_NR_sigsuspend:
6079
        {
6080
            sigset_t set;
6081
#if defined(TARGET_ALPHA)
6082
            abi_ulong mask = arg1;
6083
            target_to_host_old_sigset(&set, &mask);
6084
#else
6085
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
6086
                goto efault;
6087
            target_to_host_old_sigset(&set, p);
6088
            unlock_user(p, arg1, 0);
6089
#endif
6090
            ret = get_errno(sigsuspend(&set));
6091
        }
6092
        break;
6093
#endif
6094
    case TARGET_NR_rt_sigsuspend:
6095
        {
6096
            sigset_t set;
6097
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
6098
                goto efault;
6099
            target_to_host_sigset(&set, p);
6100
            unlock_user(p, arg1, 0);
6101
            ret = get_errno(sigsuspend(&set));
6102
        }
6103
        break;
6104
    case TARGET_NR_rt_sigtimedwait:
6105
        {
6106
            sigset_t set;
6107
            struct timespec uts, *puts;
6108
            siginfo_t uinfo;
6109

    
6110
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
6111
                goto efault;
6112
            target_to_host_sigset(&set, p);
6113
            unlock_user(p, arg1, 0);
6114
            if (arg3) {
6115
                puts = &uts;
6116
                target_to_host_timespec(puts, arg3);
6117
            } else {
6118
                puts = NULL;
6119
            }
6120
            ret = get_errno(sigtimedwait(&set, &uinfo, puts));
6121
            if (!is_error(ret) && arg2) {
6122
                if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
6123
                    goto efault;
6124
                host_to_target_siginfo(p, &uinfo);
6125
                unlock_user(p, arg2, sizeof(target_siginfo_t));
6126
            }
6127
        }
6128
        break;
6129
    case TARGET_NR_rt_sigqueueinfo:
6130
        {
6131
            siginfo_t uinfo;
6132
            if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
6133
                goto efault;
6134
            target_to_host_siginfo(&uinfo, p);
6135
            unlock_user(p, arg1, 0);
6136
            ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
6137
        }
6138
        break;
6139
#ifdef TARGET_NR_sigreturn
6140
    case TARGET_NR_sigreturn:
6141
        /* NOTE: ret is eax, so not transcoding must be done */
6142
        ret = do_sigreturn(cpu_env);
6143
        break;
6144
#endif
6145
    case TARGET_NR_rt_sigreturn:
6146
        /* NOTE: ret is eax, so not transcoding must be done */
6147
        ret = do_rt_sigreturn(cpu_env);
6148
        break;
6149
    case TARGET_NR_sethostname:
6150
        if (!(p = lock_user_string(arg1)))
6151
            goto efault;
6152
        ret = get_errno(sethostname(p, arg2));
6153
        unlock_user(p, arg1, 0);
6154
        break;
6155
    case TARGET_NR_setrlimit:
6156
        {
6157
            int resource = target_to_host_resource(arg1);
6158
            struct target_rlimit *target_rlim;
6159
            struct rlimit rlim;
6160
            if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
6161
                goto efault;
6162
            rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur);
6163
            rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max);
6164
            unlock_user_struct(target_rlim, arg2, 0);
6165
            ret = get_errno(setrlimit(resource, &rlim));
6166
        }
6167
        break;
6168
    case TARGET_NR_getrlimit:
6169
        {
6170
            int resource = target_to_host_resource(arg1);
6171
            struct target_rlimit *target_rlim;
6172
            struct rlimit rlim;
6173

    
6174
            ret = get_errno(getrlimit(resource, &rlim));
6175
            if (!is_error(ret)) {
6176
                if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
6177
                    goto efault;
6178
                target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
6179
                target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
6180
                unlock_user_struct(target_rlim, arg2, 1);
6181
            }
6182
        }
6183
        break;
6184
    case TARGET_NR_getrusage:
6185
        {
6186
            struct rusage rusage;
6187
            ret = get_errno(getrusage(arg1, &rusage));
6188
            if (!is_error(ret)) {
6189
                host_to_target_rusage(arg2, &rusage);
6190
            }
6191
        }
6192
        break;
6193
    case TARGET_NR_gettimeofday:
6194
        {
6195
            struct timeval tv;
6196
            ret = get_errno(gettimeofday(&tv, NULL));
6197
            if (!is_error(ret)) {
6198
                if (copy_to_user_timeval(arg1, &tv))
6199
                    goto efault;
6200
            }
6201
        }
6202
        break;
6203
    case TARGET_NR_settimeofday:
6204
        {
6205
            struct timeval tv;
6206
            if (copy_from_user_timeval(&tv, arg1))
6207
                goto efault;
6208
            ret = get_errno(settimeofday(&tv, NULL));
6209
        }
6210
        break;
6211
#if defined(TARGET_NR_select) && !defined(TARGET_S390X) && !defined(TARGET_S390)
6212
    case TARGET_NR_select:
6213
        {
6214
            struct target_sel_arg_struct *sel;
6215
            abi_ulong inp, outp, exp, tvp;
6216
            long nsel;
6217

    
6218
            if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
6219
                goto efault;
6220
            nsel = tswapal(sel->n);
6221
            inp = tswapal(sel->inp);
6222
            outp = tswapal(sel->outp);
6223
            exp = tswapal(sel->exp);
6224
            tvp = tswapal(sel->tvp);
6225
            unlock_user_struct(sel, arg1, 0);
6226
            ret = do_select(nsel, inp, outp, exp, tvp);
6227
        }
6228
        break;
6229
#endif
6230
#ifdef TARGET_NR_pselect6
6231
    case TARGET_NR_pselect6:
6232
        {
6233
            abi_long rfd_addr, wfd_addr, efd_addr, n, ts_addr;
6234
            fd_set rfds, wfds, efds;
6235
            fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
6236
            struct timespec ts, *ts_ptr;
6237

    
6238
            /*
6239
             * The 6th arg is actually two args smashed together,
6240
             * so we cannot use the C library.
6241
             */
6242
            sigset_t set;
6243
            struct {
6244
                sigset_t *set;
6245
                size_t size;
6246
            } sig, *sig_ptr;
6247

    
6248
            abi_ulong arg_sigset, arg_sigsize, *arg7;
6249
            target_sigset_t *target_sigset;
6250

    
6251
            n = arg1;
6252
            rfd_addr = arg2;
6253
            wfd_addr = arg3;
6254
            efd_addr = arg4;
6255
            ts_addr = arg5;
6256

    
6257
            ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
6258
            if (ret) {
6259
                goto fail;
6260
            }
6261
            ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
6262
            if (ret) {
6263
                goto fail;
6264
            }
6265
            ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
6266
            if (ret) {
6267
                goto fail;
6268
            }
6269

    
6270
            /*
6271
             * This takes a timespec, and not a timeval, so we cannot
6272
             * use the do_select() helper ...
6273
             */
6274
            if (ts_addr) {
6275
                if (target_to_host_timespec(&ts, ts_addr)) {
6276
                    goto efault;
6277
                }
6278
                ts_ptr = &ts;
6279
            } else {
6280
                ts_ptr = NULL;
6281
            }
6282

    
6283
            /* Extract the two packed args for the sigset */
6284
            if (arg6) {
6285
                sig_ptr = &sig;
6286
                sig.size = _NSIG / 8;
6287

    
6288
                arg7 = lock_user(VERIFY_READ, arg6, sizeof(*arg7) * 2, 1);
6289
                if (!arg7) {
6290
                    goto efault;
6291
                }
6292
                arg_sigset = tswapal(arg7[0]);
6293
                arg_sigsize = tswapal(arg7[1]);
6294
                unlock_user(arg7, arg6, 0);
6295

    
6296
                if (arg_sigset) {
6297
                    sig.set = &set;
6298
                    if (arg_sigsize != sizeof(*target_sigset)) {
6299
                        /* Like the kernel, we enforce correct size sigsets */
6300
                        ret = -TARGET_EINVAL;
6301
                        goto fail;
6302
                    }
6303
                    target_sigset = lock_user(VERIFY_READ, arg_sigset,
6304
                                              sizeof(*target_sigset), 1);
6305
                    if (!target_sigset) {
6306
                        goto efault;
6307
                    }
6308
                    target_to_host_sigset(&set, target_sigset);
6309
                    unlock_user(target_sigset, arg_sigset, 0);
6310
                } else {
6311
                    sig.set = NULL;
6312
                }
6313
            } else {
6314
                sig_ptr = NULL;
6315
            }
6316

    
6317
            ret = get_errno(sys_pselect6(n, rfds_ptr, wfds_ptr, efds_ptr,
6318
                                         ts_ptr, sig_ptr));
6319

    
6320
            if (!is_error(ret)) {
6321
                if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
6322
                    goto efault;
6323
                if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
6324
                    goto efault;
6325
                if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
6326
                    goto efault;
6327

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

    
6565
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
6566
                goto efault;
6567
            __put_user(stfs.f_type, &target_stfs->f_type);
6568
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
6569
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
6570
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
6571
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
6572
            __put_user(stfs.f_files, &target_stfs->f_files);
6573
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
6574
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
6575
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
6576
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
6577
            __put_user(stfs.f_frsize, &target_stfs->f_frsize);
6578
            memset(target_stfs->f_spare, 0, sizeof(target_stfs->f_spare));
6579
            unlock_user_struct(target_stfs, arg2, 1);
6580
        }
6581
        break;
6582
    case TARGET_NR_fstatfs:
6583
        ret = get_errno(fstatfs(arg1, &stfs));
6584
        goto convert_statfs;
6585
#ifdef TARGET_NR_statfs64
6586
    case TARGET_NR_statfs64:
6587
        if (!(p = lock_user_string(arg1)))
6588
            goto efault;
6589
        ret = get_errno(statfs(path(p), &stfs));
6590
        unlock_user(p, arg1, 0);
6591
    convert_statfs64:
6592
        if (!is_error(ret)) {
6593
            struct target_statfs64 *target_stfs;
6594

    
6595
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
6596
                goto efault;
6597
            __put_user(stfs.f_type, &target_stfs->f_type);
6598
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
6599
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
6600
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
6601
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
6602
            __put_user(stfs.f_files, &target_stfs->f_files);
6603
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
6604
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
6605
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
6606
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
6607
            __put_user(stfs.f_frsize, &target_stfs->f_frsize);
6608
            memset(target_stfs->f_spare, 0, sizeof(target_stfs->f_spare));
6609
            unlock_user_struct(target_stfs, arg3, 1);
6610
        }
6611
        break;
6612
    case TARGET_NR_fstatfs64:
6613
        ret = get_errno(fstatfs(arg1, &stfs));
6614
        goto convert_statfs64;
6615
#endif
6616
#ifdef TARGET_NR_ioperm
6617
    case TARGET_NR_ioperm:
6618
        goto unimplemented;
6619
#endif
6620
#ifdef TARGET_NR_socketcall
6621
    case TARGET_NR_socketcall:
6622
        ret = do_socketcall(arg1, arg2);
6623
        break;
6624
#endif
6625
#ifdef TARGET_NR_accept
6626
    case TARGET_NR_accept:
6627
        ret = do_accept(arg1, arg2, arg3);
6628
        break;
6629
#endif
6630
#ifdef TARGET_NR_bind
6631
    case TARGET_NR_bind:
6632
        ret = do_bind(arg1, arg2, arg3);
6633
        break;
6634
#endif
6635
#ifdef TARGET_NR_connect
6636
    case TARGET_NR_connect:
6637
        ret = do_connect(arg1, arg2, arg3);
6638
        break;
6639
#endif
6640
#ifdef TARGET_NR_getpeername
6641
    case TARGET_NR_getpeername:
6642
        ret = do_getpeername(arg1, arg2, arg3);
6643
        break;
6644
#endif
6645
#ifdef TARGET_NR_getsockname
6646
    case TARGET_NR_getsockname:
6647
        ret = do_getsockname(arg1, arg2, arg3);
6648
        break;
6649
#endif
6650
#ifdef TARGET_NR_getsockopt
6651
    case TARGET_NR_getsockopt:
6652
        ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
6653
        break;
6654
#endif
6655
#ifdef TARGET_NR_listen
6656
    case TARGET_NR_listen:
6657
        ret = get_errno(listen(arg1, arg2));
6658
        break;
6659
#endif
6660
#ifdef TARGET_NR_recv
6661
    case TARGET_NR_recv:
6662
        ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
6663
        break;
6664
#endif
6665
#ifdef TARGET_NR_recvfrom
6666
    case TARGET_NR_recvfrom:
6667
        ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
6668
        break;
6669
#endif
6670
#ifdef TARGET_NR_recvmsg
6671
    case TARGET_NR_recvmsg:
6672
        ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
6673
        break;
6674
#endif
6675
#ifdef TARGET_NR_send
6676
    case TARGET_NR_send:
6677
        ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
6678
        break;
6679
#endif
6680
#ifdef TARGET_NR_sendmsg
6681
    case TARGET_NR_sendmsg:
6682
        ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
6683
        break;
6684
#endif
6685
#ifdef TARGET_NR_sendto
6686
    case TARGET_NR_sendto:
6687
        ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
6688
        break;
6689
#endif
6690
#ifdef TARGET_NR_shutdown
6691
    case TARGET_NR_shutdown:
6692
        ret = get_errno(shutdown(arg1, arg2));
6693
        break;
6694
#endif
6695
#ifdef TARGET_NR_socket
6696
    case TARGET_NR_socket:
6697
        ret = do_socket(arg1, arg2, arg3);
6698
        break;
6699
#endif
6700
#ifdef TARGET_NR_socketpair
6701
    case TARGET_NR_socketpair:
6702
        ret = do_socketpair(arg1, arg2, arg3, arg4);
6703
        break;
6704
#endif
6705
#ifdef TARGET_NR_setsockopt
6706
    case TARGET_NR_setsockopt:
6707
        ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
6708
        break;
6709
#endif
6710

    
6711
    case TARGET_NR_syslog:
6712
        if (!(p = lock_user_string(arg2)))
6713
            goto efault;
6714
        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
6715
        unlock_user(p, arg2, 0);
6716
        break;
6717

    
6718
    case TARGET_NR_setitimer:
6719
        {
6720
            struct itimerval value, ovalue, *pvalue;
6721

    
6722
            if (arg2) {
6723
                pvalue = &value;
6724
                if (copy_from_user_timeval(&pvalue->it_interval, arg2)
6725
                    || copy_from_user_timeval(&pvalue->it_value,
6726
                                              arg2 + sizeof(struct target_timeval)))
6727
                    goto efault;
6728
            } else {
6729
                pvalue = NULL;
6730
            }
6731
            ret = get_errno(setitimer(arg1, pvalue, &ovalue));
6732
            if (!is_error(ret) && arg3) {
6733
                if (copy_to_user_timeval(arg3,
6734
                                         &ovalue.it_interval)
6735
                    || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
6736
                                            &ovalue.it_value))
6737
                    goto efault;
6738
            }
6739
        }
6740
        break;
6741
    case TARGET_NR_getitimer:
6742
        {
6743
            struct itimerval value;
6744

    
6745
            ret = get_errno(getitimer(arg1, &value));
6746
            if (!is_error(ret) && arg2) {
6747
                if (copy_to_user_timeval(arg2,
6748
                                         &value.it_interval)
6749
                    || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
6750
                                            &value.it_value))
6751
                    goto efault;
6752
            }
6753
        }
6754
        break;
6755
    case TARGET_NR_stat:
6756
        if (!(p = lock_user_string(arg1)))
6757
            goto efault;
6758
        ret = get_errno(stat(path(p), &st));
6759
        unlock_user(p, arg1, 0);
6760
        goto do_stat;
6761
    case TARGET_NR_lstat:
6762
        if (!(p = lock_user_string(arg1)))
6763
            goto efault;
6764
        ret = get_errno(lstat(path(p), &st));
6765
        unlock_user(p, arg1, 0);
6766
        goto do_stat;
6767
    case TARGET_NR_fstat:
6768
        {
6769
            ret = get_errno(fstat(arg1, &st));
6770
        do_stat:
6771
            if (!is_error(ret)) {
6772
                struct target_stat *target_st;
6773

    
6774
                if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
6775
                    goto efault;
6776
                memset(target_st, 0, sizeof(*target_st));
6777
                __put_user(st.st_dev, &target_st->st_dev);
6778
                __put_user(st.st_ino, &target_st->st_ino);
6779
                __put_user(st.st_mode, &target_st->st_mode);
6780
                __put_user(st.st_uid, &target_st->st_uid);
6781
                __put_user(st.st_gid, &target_st->st_gid);
6782
                __put_user(st.st_nlink, &target_st->st_nlink);
6783
                __put_user(st.st_rdev, &target_st->st_rdev);
6784
                __put_user(st.st_size, &target_st->st_size);
6785
                __put_user(st.st_blksize, &target_st->st_blksize);
6786
                __put_user(st.st_blocks, &target_st->st_blocks);
6787
                __put_user(st.st_atime, &target_st->target_st_atime);
6788
                __put_user(st.st_mtime, &target_st->target_st_mtime);
6789
                __put_user(st.st_ctime, &target_st->target_st_ctime);
6790
                unlock_user_struct(target_st, arg2, 1);
6791
            }
6792
        }
6793
        break;
6794
#ifdef TARGET_NR_olduname
6795
    case TARGET_NR_olduname:
6796
        goto unimplemented;
6797
#endif
6798
#ifdef TARGET_NR_iopl
6799
    case TARGET_NR_iopl:
6800
        goto unimplemented;
6801
#endif
6802
    case TARGET_NR_vhangup:
6803
        ret = get_errno(vhangup());
6804
        break;
6805
#ifdef TARGET_NR_idle
6806
    case TARGET_NR_idle:
6807
        goto unimplemented;
6808
#endif
6809
#ifdef TARGET_NR_syscall
6810
    case TARGET_NR_syscall:
6811
        ret = do_syscall(cpu_env, arg1 & 0xffff, arg2, arg3, arg4, arg5,
6812
                         arg6, arg7, arg8, 0);
6813
        break;
6814
#endif
6815
    case TARGET_NR_wait4:
6816
        {
6817
            int status;
6818
            abi_long status_ptr = arg2;
6819
            struct rusage rusage, *rusage_ptr;
6820
            abi_ulong target_rusage = arg4;
6821
            if (target_rusage)
6822
                rusage_ptr = &rusage;
6823
            else
6824
                rusage_ptr = NULL;
6825
            ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
6826
            if (!is_error(ret)) {
6827
                if (status_ptr && ret) {
6828
                    status = host_to_target_waitstatus(status);
6829
                    if (put_user_s32(status, status_ptr))
6830
                        goto efault;
6831
                }
6832
                if (target_rusage)
6833
                    host_to_target_rusage(target_rusage, &rusage);
6834
            }
6835
        }
6836
        break;
6837
#ifdef TARGET_NR_swapoff
6838
    case TARGET_NR_swapoff:
6839
        if (!(p = lock_user_string(arg1)))
6840
            goto efault;
6841
        ret = get_errno(swapoff(p));
6842
        unlock_user(p, arg1, 0);
6843
        break;
6844
#endif
6845
    case TARGET_NR_sysinfo:
6846
        {
6847
            struct target_sysinfo *target_value;
6848
            struct sysinfo value;
6849
            ret = get_errno(sysinfo(&value));
6850
            if (!is_error(ret) && arg1)
6851
            {
6852
                if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
6853
                    goto efault;
6854
                __put_user(value.uptime, &target_value->uptime);
6855
                __put_user(value.loads[0], &target_value->loads[0]);
6856
                __put_user(value.loads[1], &target_value->loads[1]);
6857
                __put_user(value.loads[2], &target_value->loads[2]);
6858
                __put_user(value.totalram, &target_value->totalram);
6859
                __put_user(value.freeram, &target_value->freeram);
6860
                __put_user(value.sharedram, &target_value->sharedram);
6861
                __put_user(value.bufferram, &target_value->bufferram);
6862
                __put_user(value.totalswap, &target_value->totalswap);
6863
                __put_user(value.freeswap, &target_value->freeswap);
6864
                __put_user(value.procs, &target_value->procs);
6865
                __put_user(value.totalhigh, &target_value->totalhigh);
6866
                __put_user(value.freehigh, &target_value->freehigh);
6867
                __put_user(value.mem_unit, &target_value->mem_unit);
6868
                unlock_user_struct(target_value, arg1, 1);
6869
            }
6870
        }
6871
        break;
6872
#ifdef TARGET_NR_ipc
6873
    case TARGET_NR_ipc:
6874
        ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
6875
        break;
6876
#endif
6877
#ifdef TARGET_NR_semget
6878
    case TARGET_NR_semget:
6879
        ret = get_errno(semget(arg1, arg2, arg3));
6880
        break;
6881
#endif
6882
#ifdef TARGET_NR_semop
6883
    case TARGET_NR_semop:
6884
        ret = get_errno(do_semop(arg1, arg2, arg3));
6885
        break;
6886
#endif
6887
#ifdef TARGET_NR_semctl
6888
    case TARGET_NR_semctl:
6889
        ret = do_semctl(arg1, arg2, arg3, (union target_semun)(abi_ulong)arg4);
6890
        break;
6891
#endif
6892
#ifdef TARGET_NR_msgctl
6893
    case TARGET_NR_msgctl:
6894
        ret = do_msgctl(arg1, arg2, arg3);
6895
        break;
6896
#endif
6897
#ifdef TARGET_NR_msgget
6898
    case TARGET_NR_msgget:
6899
        ret = get_errno(msgget(arg1, arg2));
6900
        break;
6901
#endif
6902
#ifdef TARGET_NR_msgrcv
6903
    case TARGET_NR_msgrcv:
6904
        ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
6905
        break;
6906
#endif
6907
#ifdef TARGET_NR_msgsnd
6908
    case TARGET_NR_msgsnd:
6909
        ret = do_msgsnd(arg1, arg2, arg3, arg4);
6910
        break;
6911
#endif
6912
#ifdef TARGET_NR_shmget
6913
    case TARGET_NR_shmget:
6914
        ret = get_errno(shmget(arg1, arg2, arg3));
6915
        break;
6916
#endif
6917
#ifdef TARGET_NR_shmctl
6918
    case TARGET_NR_shmctl:
6919
        ret = do_shmctl(arg1, arg2, arg3);
6920
        break;
6921
#endif
6922
#ifdef TARGET_NR_shmat
6923
    case TARGET_NR_shmat:
6924
        ret = do_shmat(arg1, arg2, arg3);
6925
        break;
6926
#endif
6927
#ifdef TARGET_NR_shmdt
6928
    case TARGET_NR_shmdt:
6929
        ret = do_shmdt(arg1);
6930
        break;
6931
#endif
6932
    case TARGET_NR_fsync:
6933
        ret = get_errno(fsync(arg1));
6934
        break;
6935
    case TARGET_NR_clone:
6936
#if defined(TARGET_SH4) || defined(TARGET_ALPHA)
6937
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
6938
#elif defined(TARGET_CRIS)
6939
        ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg4, arg5));
6940
#elif defined(TARGET_S390X)
6941
        ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg5, arg4));
6942
#else
6943
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
6944
#endif
6945
        break;
6946
#ifdef __NR_exit_group
6947
        /* new thread calls */
6948
    case TARGET_NR_exit_group:
6949
#ifdef TARGET_GPROF
6950
        _mcleanup();
6951
#endif
6952
        gdb_exit(cpu_env, arg1);
6953
        ret = get_errno(exit_group(arg1));
6954
        break;
6955
#endif
6956
    case TARGET_NR_setdomainname:
6957
        if (!(p = lock_user_string(arg1)))
6958
            goto efault;
6959
        ret = get_errno(setdomainname(p, arg2));
6960
        unlock_user(p, arg1, 0);
6961
        break;
6962
    case TARGET_NR_uname:
6963
        /* no need to transcode because we use the linux syscall */
6964
        {
6965
            struct new_utsname * buf;
6966

    
6967
            if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
6968
                goto efault;
6969
            ret = get_errno(sys_uname(buf));
6970
            if (!is_error(ret)) {
6971
                /* Overrite the native machine name with whatever is being
6972
                   emulated. */
6973
                strcpy (buf->machine, cpu_to_uname_machine(cpu_env));
6974
                /* Allow the user to override the reported release.  */
6975
                if (qemu_uname_release && *qemu_uname_release)
6976
                  strcpy (buf->release, qemu_uname_release);
6977
            }
6978
            unlock_user_struct(buf, arg1, 1);
6979
        }
6980
        break;
6981
#ifdef TARGET_I386
6982
    case TARGET_NR_modify_ldt:
6983
        ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
6984
        break;
6985
#if !defined(TARGET_X86_64)
6986
    case TARGET_NR_vm86old:
6987
        goto unimplemented;
6988
    case TARGET_NR_vm86:
6989
        ret = do_vm86(cpu_env, arg1, arg2);
6990
        break;
6991
#endif
6992
#endif
6993
    case TARGET_NR_adjtimex:
6994
        goto unimplemented;
6995
#ifdef TARGET_NR_create_module
6996
    case TARGET_NR_create_module:
6997
#endif
6998
    case TARGET_NR_init_module:
6999
    case TARGET_NR_delete_module:
7000
#ifdef TARGET_NR_get_kernel_syms
7001
    case TARGET_NR_get_kernel_syms:
7002
#endif
7003
        goto unimplemented;
7004
    case TARGET_NR_quotactl:
7005
        goto unimplemented;
7006
    case TARGET_NR_getpgid:
7007
        ret = get_errno(getpgid(arg1));
7008
        break;
7009
    case TARGET_NR_fchdir:
7010
        ret = get_errno(fchdir(arg1));
7011
        break;
7012
#ifdef TARGET_NR_bdflush /* not on x86_64 */
7013
    case TARGET_NR_bdflush:
7014
        goto unimplemented;
7015
#endif
7016
#ifdef TARGET_NR_sysfs
7017
    case TARGET_NR_sysfs:
7018
        goto unimplemented;
7019
#endif
7020
    case TARGET_NR_personality:
7021
        ret = get_errno(personality(arg1));
7022
        break;
7023
#ifdef TARGET_NR_afs_syscall
7024
    case TARGET_NR_afs_syscall:
7025
        goto unimplemented;
7026
#endif
7027
#ifdef TARGET_NR__llseek /* Not on alpha */
7028
    case TARGET_NR__llseek:
7029
        {
7030
            int64_t res;
7031
#if !defined(__NR_llseek)
7032
            res = lseek(arg1, ((uint64_t)arg2 << 32) | arg3, arg5);
7033
            if (res == -1) {
7034
                ret = get_errno(res);
7035
            } else {
7036
                ret = 0;
7037
            }
7038
#else
7039
            ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
7040
#endif
7041
            if ((ret == 0) && put_user_s64(res, arg4)) {
7042
                goto efault;
7043
            }
7044
        }
7045
        break;
7046
#endif
7047
    case TARGET_NR_getdents:
7048
#if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
7049
        {
7050
            struct target_dirent *target_dirp;
7051
            struct linux_dirent *dirp;
7052
            abi_long count = arg3;
7053

    
7054
            dirp = malloc(count);
7055
            if (!dirp) {
7056
                ret = -TARGET_ENOMEM;
7057
                goto fail;
7058
            }
7059

    
7060
            ret = get_errno(sys_getdents(arg1, dirp, count));
7061
            if (!is_error(ret)) {
7062
                struct linux_dirent *de;
7063
                struct target_dirent *tde;
7064
                int len = ret;
7065
                int reclen, treclen;
7066
                int count1, tnamelen;
7067

    
7068
                count1 = 0;
7069
                de = dirp;
7070
                if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
7071
                    goto efault;
7072
                tde = target_dirp;
7073
                while (len > 0) {
7074
                    reclen = de->d_reclen;
7075
                    tnamelen = reclen - offsetof(struct linux_dirent, d_name);
7076
                    assert(tnamelen >= 0);
7077
                    treclen = tnamelen + offsetof(struct target_dirent, d_name);
7078
                    assert(count1 + treclen <= count);
7079
                    tde->d_reclen = tswap16(treclen);
7080
                    tde->d_ino = tswapal(de->d_ino);
7081
                    tde->d_off = tswapal(de->d_off);
7082
                    memcpy(tde->d_name, de->d_name, tnamelen);
7083
                    de = (struct linux_dirent *)((char *)de + reclen);
7084
                    len -= reclen;
7085
                    tde = (struct target_dirent *)((char *)tde + treclen);
7086
                    count1 += treclen;
7087
                }
7088
                ret = count1;
7089
                unlock_user(target_dirp, arg2, ret);
7090
            }
7091
            free(dirp);
7092
        }
7093
#else
7094
        {
7095
            struct linux_dirent *dirp;
7096
            abi_long count = arg3;
7097

    
7098
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
7099
                goto efault;
7100
            ret = get_errno(sys_getdents(arg1, dirp, count));
7101
            if (!is_error(ret)) {
7102
                struct linux_dirent *de;
7103
                int len = ret;
7104
                int reclen;
7105
                de = dirp;
7106
                while (len > 0) {
7107
                    reclen = de->d_reclen;
7108
                    if (reclen > len)
7109
                        break;
7110
                    de->d_reclen = tswap16(reclen);
7111
                    tswapls(&de->d_ino);
7112
                    tswapls(&de->d_off);
7113
                    de = (struct linux_dirent *)((char *)de + reclen);
7114
                    len -= reclen;
7115
                }
7116
            }
7117
            unlock_user(dirp, arg2, ret);
7118
        }
7119
#endif
7120
        break;
7121
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
7122
    case TARGET_NR_getdents64:
7123
        {
7124
            struct linux_dirent64 *dirp;
7125
            abi_long count = arg3;
7126
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
7127
                goto efault;
7128
            ret = get_errno(sys_getdents64(arg1, dirp, count));
7129
            if (!is_error(ret)) {
7130
                struct linux_dirent64 *de;
7131
                int len = ret;
7132
                int reclen;
7133
                de = dirp;
7134
                while (len > 0) {
7135
                    reclen = de->d_reclen;
7136
                    if (reclen > len)
7137
                        break;
7138
                    de->d_reclen = tswap16(reclen);
7139
                    tswap64s((uint64_t *)&de->d_ino);
7140
                    tswap64s((uint64_t *)&de->d_off);
7141
                    de = (struct linux_dirent64 *)((char *)de + reclen);
7142
                    len -= reclen;
7143
                }
7144
            }
7145
            unlock_user(dirp, arg2, ret);
7146
        }
7147
        break;
7148
#endif /* TARGET_NR_getdents64 */
7149
#if defined(TARGET_NR__newselect) || defined(TARGET_S390X)
7150
#ifdef TARGET_S390X
7151
    case TARGET_NR_select:
7152
#else
7153
    case TARGET_NR__newselect:
7154
#endif
7155
        ret = do_select(arg1, arg2, arg3, arg4, arg5);
7156
        break;
7157
#endif
7158
#if defined(TARGET_NR_poll) || defined(TARGET_NR_ppoll)
7159
# ifdef TARGET_NR_poll
7160
    case TARGET_NR_poll:
7161
# endif
7162
# ifdef TARGET_NR_ppoll
7163
    case TARGET_NR_ppoll:
7164
# endif
7165
        {
7166
            struct target_pollfd *target_pfd;
7167
            unsigned int nfds = arg2;
7168
            int timeout = arg3;
7169
            struct pollfd *pfd;
7170
            unsigned int i;
7171

    
7172
            target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
7173
            if (!target_pfd)
7174
                goto efault;
7175

    
7176
            pfd = alloca(sizeof(struct pollfd) * nfds);
7177
            for(i = 0; i < nfds; i++) {
7178
                pfd[i].fd = tswap32(target_pfd[i].fd);
7179
                pfd[i].events = tswap16(target_pfd[i].events);
7180
            }
7181

    
7182
# ifdef TARGET_NR_ppoll
7183
            if (num == TARGET_NR_ppoll) {
7184
                struct timespec _timeout_ts, *timeout_ts = &_timeout_ts;
7185
                target_sigset_t *target_set;
7186
                sigset_t _set, *set = &_set;
7187

    
7188
                if (arg3) {
7189
                    if (target_to_host_timespec(timeout_ts, arg3)) {
7190
                        unlock_user(target_pfd, arg1, 0);
7191
                        goto efault;
7192
                    }
7193
                } else {
7194
                    timeout_ts = NULL;
7195
                }
7196

    
7197
                if (arg4) {
7198
                    target_set = lock_user(VERIFY_READ, arg4, sizeof(target_sigset_t), 1);
7199
                    if (!target_set) {
7200
                        unlock_user(target_pfd, arg1, 0);
7201
                        goto efault;
7202
                    }
7203
                    target_to_host_sigset(set, target_set);
7204
                } else {
7205
                    set = NULL;
7206
                }
7207

    
7208
                ret = get_errno(sys_ppoll(pfd, nfds, timeout_ts, set, _NSIG/8));
7209

    
7210
                if (!is_error(ret) && arg3) {
7211
                    host_to_target_timespec(arg3, timeout_ts);
7212
                }
7213
                if (arg4) {
7214
                    unlock_user(target_set, arg4, 0);
7215
                }
7216
            } else
7217
# endif
7218
                ret = get_errno(poll(pfd, nfds, timeout));
7219

    
7220
            if (!is_error(ret)) {
7221
                for(i = 0; i < nfds; i++) {
7222
                    target_pfd[i].revents = tswap16(pfd[i].revents);
7223
                }
7224
            }
7225
            unlock_user(target_pfd, arg1, sizeof(struct target_pollfd) * nfds);
7226
        }
7227
        break;
7228
#endif
7229
    case TARGET_NR_flock:
7230
        /* NOTE: the flock constant seems to be the same for every
7231
           Linux platform */
7232
        ret = get_errno(flock(arg1, arg2));
7233
        break;
7234
    case TARGET_NR_readv:
7235
        {
7236
            struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 0);
7237
            if (vec != NULL) {
7238
                ret = get_errno(readv(arg1, vec, arg3));
7239
                unlock_iovec(vec, arg2, arg3, 1);
7240
            } else {
7241
                ret = -host_to_target_errno(errno);
7242
            }
7243
        }
7244
        break;
7245
    case TARGET_NR_writev:
7246
        {
7247
            struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
7248
            if (vec != NULL) {
7249
                ret = get_errno(writev(arg1, vec, arg3));
7250
                unlock_iovec(vec, arg2, arg3, 0);
7251
            } else {
7252
                ret = -host_to_target_errno(errno);
7253
            }
7254
        }
7255
        break;
7256
    case TARGET_NR_getsid:
7257
        ret = get_errno(getsid(arg1));
7258
        break;
7259
#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
7260
    case TARGET_NR_fdatasync:
7261
        ret = get_errno(fdatasync(arg1));
7262
        break;
7263
#endif
7264
    case TARGET_NR__sysctl:
7265
        /* We don't implement this, but ENOTDIR is always a safe
7266
           return value. */
7267
        ret = -TARGET_ENOTDIR;
7268
        break;
7269
    case TARGET_NR_sched_getaffinity:
7270
        {
7271
            unsigned int mask_size;
7272
            unsigned long *mask;
7273

    
7274
            /*
7275
             * sched_getaffinity needs multiples of ulong, so need to take
7276
             * care of mismatches between target ulong and host ulong sizes.
7277
             */
7278
            if (arg2 & (sizeof(abi_ulong) - 1)) {
7279
                ret = -TARGET_EINVAL;
7280
                break;
7281
            }
7282
            mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
7283

    
7284
            mask = alloca(mask_size);
7285
            ret = get_errno(sys_sched_getaffinity(arg1, mask_size, mask));
7286

    
7287
            if (!is_error(ret)) {
7288
                if (copy_to_user(arg3, mask, ret)) {
7289
                    goto efault;
7290
                }
7291
            }
7292
        }
7293
        break;
7294
    case TARGET_NR_sched_setaffinity:
7295
        {
7296
            unsigned int mask_size;
7297
            unsigned long *mask;
7298

    
7299
            /*
7300
             * sched_setaffinity needs multiples of ulong, so need to take
7301
             * care of mismatches between target ulong and host ulong sizes.
7302
             */
7303
            if (arg2 & (sizeof(abi_ulong) - 1)) {
7304
                ret = -TARGET_EINVAL;
7305
                break;
7306
            }
7307
            mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
7308

    
7309
            mask = alloca(mask_size);
7310
            if (!lock_user_struct(VERIFY_READ, p, arg3, 1)) {
7311
                goto efault;
7312
            }
7313
            memcpy(mask, p, arg2);
7314
            unlock_user_struct(p, arg2, 0);
7315

    
7316
            ret = get_errno(sys_sched_setaffinity(arg1, mask_size, mask));
7317
        }
7318
        break;
7319
    case TARGET_NR_sched_setparam:
7320
        {
7321
            struct sched_param *target_schp;
7322
            struct sched_param schp;
7323

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

    
7627
            grouplist = alloca(gidsetsize * sizeof(gid_t));
7628
            ret = get_errno(getgroups(gidsetsize, grouplist));
7629
            if (gidsetsize == 0)
7630
                break;
7631
            if (!is_error(ret)) {
7632
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
7633
                if (!target_grouplist)
7634
                    goto efault;
7635
                for(i = 0;i < ret; i++)
7636
                    target_grouplist[i] = tswapid(high2lowgid(grouplist[i]));
7637
                unlock_user(target_grouplist, arg2, gidsetsize * 2);
7638
            }
7639
        }
7640
        break;
7641
    case TARGET_NR_setgroups:
7642
        {
7643
            int gidsetsize = arg1;
7644
            target_id *target_grouplist;
7645
            gid_t *grouplist;
7646
            int i;
7647

    
7648
            grouplist = alloca(gidsetsize * sizeof(gid_t));
7649
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
7650
            if (!target_grouplist) {
7651
                ret = -TARGET_EFAULT;
7652
                goto fail;
7653
            }
7654
            for(i = 0;i < gidsetsize; i++)
7655
                grouplist[i] = low2highgid(tswapid(target_grouplist[i]));
7656
            unlock_user(target_grouplist, arg2, 0);
7657
            ret = get_errno(setgroups(gidsetsize, grouplist));
7658
        }
7659
        break;
7660
    case TARGET_NR_fchown:
7661
        ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
7662
        break;
7663
#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
7664
    case TARGET_NR_fchownat:
7665
        if (!(p = lock_user_string(arg2))) 
7666
            goto efault;
7667
        ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
7668
        unlock_user(p, arg2, 0);
7669
        break;
7670
#endif
7671
#ifdef TARGET_NR_setresuid
7672
    case TARGET_NR_setresuid:
7673
        ret = get_errno(setresuid(low2highuid(arg1),
7674
                                  low2highuid(arg2),
7675
                                  low2highuid(arg3)));
7676
        break;
7677
#endif
7678
#ifdef TARGET_NR_getresuid
7679
    case TARGET_NR_getresuid:
7680
        {
7681
            uid_t ruid, euid, suid;
7682
            ret = get_errno(getresuid(&ruid, &euid, &suid));
7683
            if (!is_error(ret)) {
7684
                if (put_user_u16(high2lowuid(ruid), arg1)
7685
                    || put_user_u16(high2lowuid(euid), arg2)
7686
                    || put_user_u16(high2lowuid(suid), arg3))
7687
                    goto efault;
7688
            }
7689
        }
7690
        break;
7691
#endif
7692
#ifdef TARGET_NR_getresgid
7693
    case TARGET_NR_setresgid:
7694
        ret = get_errno(setresgid(low2highgid(arg1),
7695
                                  low2highgid(arg2),
7696
                                  low2highgid(arg3)));
7697
        break;
7698
#endif
7699
#ifdef TARGET_NR_getresgid
7700
    case TARGET_NR_getresgid:
7701
        {
7702
            gid_t rgid, egid, sgid;
7703
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
7704
            if (!is_error(ret)) {
7705
                if (put_user_u16(high2lowgid(rgid), arg1)
7706
                    || put_user_u16(high2lowgid(egid), arg2)
7707
                    || put_user_u16(high2lowgid(sgid), arg3))
7708
                    goto efault;
7709
            }
7710
        }
7711
        break;
7712
#endif
7713
    case TARGET_NR_chown:
7714
        if (!(p = lock_user_string(arg1)))
7715
            goto efault;
7716
        ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
7717
        unlock_user(p, arg1, 0);
7718
        break;
7719
    case TARGET_NR_setuid:
7720
        ret = get_errno(setuid(low2highuid(arg1)));
7721
        break;
7722
    case TARGET_NR_setgid:
7723
        ret = get_errno(setgid(low2highgid(arg1)));
7724
        break;
7725
    case TARGET_NR_setfsuid:
7726
        ret = get_errno(setfsuid(arg1));
7727
        break;
7728
    case TARGET_NR_setfsgid:
7729
        ret = get_errno(setfsgid(arg1));
7730
        break;
7731

    
7732
#ifdef TARGET_NR_lchown32
7733
    case TARGET_NR_lchown32:
7734
        if (!(p = lock_user_string(arg1)))
7735
            goto efault;
7736
        ret = get_errno(lchown(p, arg2, arg3));
7737
        unlock_user(p, arg1, 0);
7738
        break;
7739
#endif
7740
#ifdef TARGET_NR_getuid32
7741
    case TARGET_NR_getuid32:
7742
        ret = get_errno(getuid());
7743
        break;
7744
#endif
7745

    
7746
#if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
7747
   /* Alpha specific */
7748
    case TARGET_NR_getxuid:
7749
         {
7750
            uid_t euid;
7751
            euid=geteuid();
7752
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
7753
         }
7754
        ret = get_errno(getuid());
7755
        break;
7756
#endif
7757
#if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
7758
   /* Alpha specific */
7759
    case TARGET_NR_getxgid:
7760
         {
7761
            uid_t egid;
7762
            egid=getegid();
7763
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
7764
         }
7765
        ret = get_errno(getgid());
7766
        break;
7767
#endif
7768
#if defined(TARGET_NR_osf_getsysinfo) && defined(TARGET_ALPHA)
7769
    /* Alpha specific */
7770
    case TARGET_NR_osf_getsysinfo:
7771
        ret = -TARGET_EOPNOTSUPP;
7772
        switch (arg1) {
7773
          case TARGET_GSI_IEEE_FP_CONTROL:
7774
            {
7775
                uint64_t swcr, fpcr = cpu_alpha_load_fpcr (cpu_env);
7776

    
7777
                /* Copied from linux ieee_fpcr_to_swcr.  */
7778
                swcr = (fpcr >> 35) & SWCR_STATUS_MASK;
7779
                swcr |= (fpcr >> 36) & SWCR_MAP_DMZ;
7780
                swcr |= (~fpcr >> 48) & (SWCR_TRAP_ENABLE_INV
7781
                                        | SWCR_TRAP_ENABLE_DZE
7782
                                        | SWCR_TRAP_ENABLE_OVF);
7783
                swcr |= (~fpcr >> 57) & (SWCR_TRAP_ENABLE_UNF
7784
                                        | SWCR_TRAP_ENABLE_INE);
7785
                swcr |= (fpcr >> 47) & SWCR_MAP_UMZ;
7786
                swcr |= (~fpcr >> 41) & SWCR_TRAP_ENABLE_DNO;
7787

    
7788
                if (put_user_u64 (swcr, arg2))
7789
                        goto efault;
7790
                ret = 0;
7791
            }
7792
            break;
7793

    
7794
          /* case GSI_IEEE_STATE_AT_SIGNAL:
7795
             -- Not implemented in linux kernel.
7796
             case GSI_UACPROC:
7797
             -- Retrieves current unaligned access state; not much used.
7798
             case GSI_PROC_TYPE:
7799
             -- Retrieves implver information; surely not used.
7800
             case GSI_GET_HWRPB:
7801
             -- Grabs a copy of the HWRPB; surely not used.
7802
          */
7803
        }
7804
        break;
7805
#endif
7806
#if defined(TARGET_NR_osf_setsysinfo) && defined(TARGET_ALPHA)
7807
    /* Alpha specific */
7808
    case TARGET_NR_osf_setsysinfo:
7809
        ret = -TARGET_EOPNOTSUPP;
7810
        switch (arg1) {
7811
          case TARGET_SSI_IEEE_FP_CONTROL:
7812
            {
7813
                uint64_t swcr, fpcr, orig_fpcr;
7814

    
7815
                if (get_user_u64 (swcr, arg2)) {
7816
                    goto efault;
7817
                }
7818
                orig_fpcr = cpu_alpha_load_fpcr(cpu_env);
7819
                fpcr = orig_fpcr & FPCR_DYN_MASK;
7820

    
7821
                /* Copied from linux ieee_swcr_to_fpcr.  */
7822
                fpcr |= (swcr & SWCR_STATUS_MASK) << 35;
7823
                fpcr |= (swcr & SWCR_MAP_DMZ) << 36;
7824
                fpcr |= (~swcr & (SWCR_TRAP_ENABLE_INV
7825
                                  | SWCR_TRAP_ENABLE_DZE
7826
                                  | SWCR_TRAP_ENABLE_OVF)) << 48;
7827
                fpcr |= (~swcr & (SWCR_TRAP_ENABLE_UNF
7828
                                  | SWCR_TRAP_ENABLE_INE)) << 57;
7829
                fpcr |= (swcr & SWCR_MAP_UMZ ? FPCR_UNDZ | FPCR_UNFD : 0);
7830
                fpcr |= (~swcr & SWCR_TRAP_ENABLE_DNO) << 41;
7831

    
7832
                cpu_alpha_store_fpcr(cpu_env, fpcr);
7833
                ret = 0;
7834
            }
7835
            break;
7836

    
7837
          case TARGET_SSI_IEEE_RAISE_EXCEPTION:
7838
            {
7839
                uint64_t exc, fpcr, orig_fpcr;
7840
                int si_code;
7841

    
7842
                if (get_user_u64(exc, arg2)) {
7843
                    goto efault;
7844
                }
7845

    
7846
                orig_fpcr = cpu_alpha_load_fpcr(cpu_env);
7847

    
7848
                /* We only add to the exception status here.  */
7849
                fpcr = orig_fpcr | ((exc & SWCR_STATUS_MASK) << 35);
7850

    
7851
                cpu_alpha_store_fpcr(cpu_env, fpcr);
7852
                ret = 0;
7853

    
7854
                /* Old exceptions are not signaled.  */
7855
                fpcr &= ~(orig_fpcr & FPCR_STATUS_MASK);
7856

    
7857
                /* If any exceptions set by this call,
7858
                   and are unmasked, send a signal.  */
7859
                si_code = 0;
7860
                if ((fpcr & (FPCR_INE | FPCR_INED)) == FPCR_INE) {
7861
                    si_code = TARGET_FPE_FLTRES;
7862
                }
7863
                if ((fpcr & (FPCR_UNF | FPCR_UNFD)) == FPCR_UNF) {
7864
                    si_code = TARGET_FPE_FLTUND;
7865
                }
7866
                if ((fpcr & (FPCR_OVF | FPCR_OVFD)) == FPCR_OVF) {
7867
                    si_code = TARGET_FPE_FLTOVF;
7868
                }
7869
                if ((fpcr & (FPCR_DZE | FPCR_DZED)) == FPCR_DZE) {
7870
                    si_code = TARGET_FPE_FLTDIV;
7871
                }
7872
                if ((fpcr & (FPCR_INV | FPCR_INVD)) == FPCR_INV) {
7873
                    si_code = TARGET_FPE_FLTINV;
7874
                }
7875
                if (si_code != 0) {
7876
                    target_siginfo_t info;
7877
                    info.si_signo = SIGFPE;
7878
                    info.si_errno = 0;
7879
                    info.si_code = si_code;
7880
                    info._sifields._sigfault._addr
7881
                        = ((CPUArchState *)cpu_env)->pc;
7882
                    queue_signal((CPUArchState *)cpu_env, info.si_signo, &info);
7883
                }
7884
            }
7885
            break;
7886

    
7887
          /* case SSI_NVPAIRS:
7888
             -- Used with SSIN_UACPROC to enable unaligned accesses.
7889
             case SSI_IEEE_STATE_AT_SIGNAL:
7890
             case SSI_IEEE_IGNORE_STATE_AT_SIGNAL:
7891
             -- Not implemented in linux kernel
7892
          */
7893
        }
7894
        break;
7895
#endif
7896
#ifdef TARGET_NR_osf_sigprocmask
7897
    /* Alpha specific.  */
7898
    case TARGET_NR_osf_sigprocmask:
7899
        {
7900
            abi_ulong mask;
7901
            int how;
7902
            sigset_t set, oldset;
7903

    
7904
            switch(arg1) {
7905
            case TARGET_SIG_BLOCK:
7906
                how = SIG_BLOCK;
7907
                break;
7908
            case TARGET_SIG_UNBLOCK:
7909
                how = SIG_UNBLOCK;
7910
                break;
7911
            case TARGET_SIG_SETMASK:
7912
                how = SIG_SETMASK;
7913
                break;
7914
            default:
7915
                ret = -TARGET_EINVAL;
7916
                goto fail;
7917
            }
7918
            mask = arg2;
7919
            target_to_host_old_sigset(&set, &mask);
7920
            sigprocmask(how, &set, &oldset);
7921
            host_to_target_old_sigset(&mask, &oldset);
7922
            ret = mask;
7923
        }
7924
        break;
7925
#endif
7926

    
7927
#ifdef TARGET_NR_getgid32
7928
    case TARGET_NR_getgid32:
7929
        ret = get_errno(getgid());
7930
        break;
7931
#endif
7932
#ifdef TARGET_NR_geteuid32
7933
    case TARGET_NR_geteuid32:
7934
        ret = get_errno(geteuid());
7935
        break;
7936
#endif
7937
#ifdef TARGET_NR_getegid32
7938
    case TARGET_NR_getegid32:
7939
        ret = get_errno(getegid());
7940
        break;
7941
#endif
7942
#ifdef TARGET_NR_setreuid32
7943
    case TARGET_NR_setreuid32:
7944
        ret = get_errno(setreuid(arg1, arg2));
7945
        break;
7946
#endif
7947
#ifdef TARGET_NR_setregid32
7948
    case TARGET_NR_setregid32:
7949
        ret = get_errno(setregid(arg1, arg2));
7950
        break;
7951
#endif
7952
#ifdef TARGET_NR_getgroups32
7953
    case TARGET_NR_getgroups32:
7954
        {
7955
            int gidsetsize = arg1;
7956
            uint32_t *target_grouplist;
7957
            gid_t *grouplist;
7958
            int i;
7959

    
7960
            grouplist = alloca(gidsetsize * sizeof(gid_t));
7961
            ret = get_errno(getgroups(gidsetsize, grouplist));
7962
            if (gidsetsize == 0)
7963
                break;
7964
            if (!is_error(ret)) {
7965
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
7966
                if (!target_grouplist) {
7967
                    ret = -TARGET_EFAULT;
7968
                    goto fail;
7969
                }
7970
                for(i = 0;i < ret; i++)
7971
                    target_grouplist[i] = tswap32(grouplist[i]);
7972
                unlock_user(target_grouplist, arg2, gidsetsize * 4);
7973
            }
7974
        }
7975
        break;
7976
#endif
7977
#ifdef TARGET_NR_setgroups32
7978
    case TARGET_NR_setgroups32:
7979
        {
7980
            int gidsetsize = arg1;
7981
            uint32_t *target_grouplist;
7982
            gid_t *grouplist;
7983
            int i;
7984

    
7985
            grouplist = alloca(gidsetsize * sizeof(gid_t));
7986
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
7987
            if (!target_grouplist) {
7988
                ret = -TARGET_EFAULT;
7989
                goto fail;
7990
            }
7991
            for(i = 0;i < gidsetsize; i++)
7992
                grouplist[i] = tswap32(target_grouplist[i]);
7993
            unlock_user(target_grouplist, arg2, 0);
7994
            ret = get_errno(setgroups(gidsetsize, grouplist));
7995
        }
7996
        break;
7997
#endif
7998
#ifdef TARGET_NR_fchown32
7999
    case TARGET_NR_fchown32:
8000
        ret = get_errno(fchown(arg1, arg2, arg3));
8001
        break;
8002
#endif
8003
#ifdef TARGET_NR_setresuid32
8004
    case TARGET_NR_setresuid32:
8005
        ret = get_errno(setresuid(arg1, arg2, arg3));
8006
        break;
8007
#endif
8008
#ifdef TARGET_NR_getresuid32
8009
    case TARGET_NR_getresuid32:
8010
        {
8011
            uid_t ruid, euid, suid;
8012
            ret = get_errno(getresuid(&ruid, &euid, &suid));
8013
            if (!is_error(ret)) {
8014
                if (put_user_u32(ruid, arg1)
8015
                    || put_user_u32(euid, arg2)
8016
                    || put_user_u32(suid, arg3))
8017
                    goto efault;
8018
            }
8019
        }
8020
        break;
8021
#endif
8022
#ifdef TARGET_NR_setresgid32
8023
    case TARGET_NR_setresgid32:
8024
        ret = get_errno(setresgid(arg1, arg2, arg3));
8025
        break;
8026
#endif
8027
#ifdef TARGET_NR_getresgid32
8028
    case TARGET_NR_getresgid32:
8029
        {
8030
            gid_t rgid, egid, sgid;
8031
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
8032
            if (!is_error(ret)) {
8033
                if (put_user_u32(rgid, arg1)
8034
                    || put_user_u32(egid, arg2)
8035
                    || put_user_u32(sgid, arg3))
8036
                    goto efault;
8037
            }
8038
        }
8039
        break;
8040
#endif
8041
#ifdef TARGET_NR_chown32
8042
    case TARGET_NR_chown32:
8043
        if (!(p = lock_user_string(arg1)))
8044
            goto efault;
8045
        ret = get_errno(chown(p, arg2, arg3));
8046
        unlock_user(p, arg1, 0);
8047
        break;
8048
#endif
8049
#ifdef TARGET_NR_setuid32
8050
    case TARGET_NR_setuid32:
8051
        ret = get_errno(setuid(arg1));
8052
        break;
8053
#endif
8054
#ifdef TARGET_NR_setgid32
8055
    case TARGET_NR_setgid32:
8056
        ret = get_errno(setgid(arg1));
8057
        break;
8058
#endif
8059
#ifdef TARGET_NR_setfsuid32
8060
    case TARGET_NR_setfsuid32:
8061
        ret = get_errno(setfsuid(arg1));
8062
        break;
8063
#endif
8064
#ifdef TARGET_NR_setfsgid32
8065
    case TARGET_NR_setfsgid32:
8066
        ret = get_errno(setfsgid(arg1));
8067
        break;
8068
#endif
8069

    
8070
    case TARGET_NR_pivot_root:
8071
        goto unimplemented;
8072
#ifdef TARGET_NR_mincore
8073
    case TARGET_NR_mincore:
8074
        {
8075
            void *a;
8076
            ret = -TARGET_EFAULT;
8077
            if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
8078
                goto efault;
8079
            if (!(p = lock_user_string(arg3)))
8080
                goto mincore_fail;
8081
            ret = get_errno(mincore(a, arg2, p));
8082
            unlock_user(p, arg3, ret);
8083
            mincore_fail:
8084
            unlock_user(a, arg1, 0);
8085
        }
8086
        break;
8087
#endif
8088
#ifdef TARGET_NR_arm_fadvise64_64
8089
    case TARGET_NR_arm_fadvise64_64:
8090
        {
8091
                /*
8092
                 * arm_fadvise64_64 looks like fadvise64_64 but
8093
                 * with different argument order
8094
                 */
8095
                abi_long temp;
8096
                temp = arg3;
8097
                arg3 = arg4;
8098
                arg4 = temp;
8099
        }
8100
#endif
8101
#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64) || defined(TARGET_NR_fadvise64)
8102
#ifdef TARGET_NR_fadvise64_64
8103
    case TARGET_NR_fadvise64_64:
8104
#endif
8105
#ifdef TARGET_NR_fadvise64
8106
    case TARGET_NR_fadvise64:
8107
#endif
8108
#ifdef TARGET_S390X
8109
        switch (arg4) {
8110
        case 4: arg4 = POSIX_FADV_NOREUSE + 1; break; /* make sure it's an invalid value */
8111
        case 5: arg4 = POSIX_FADV_NOREUSE + 2; break; /* ditto */
8112
        case 6: arg4 = POSIX_FADV_DONTNEED; break;
8113
        case 7: arg4 = POSIX_FADV_NOREUSE; break;
8114
        default: break;
8115
        }
8116
#endif
8117
        ret = -posix_fadvise(arg1, arg2, arg3, arg4);
8118
        break;
8119
#endif
8120
#ifdef TARGET_NR_madvise
8121
    case TARGET_NR_madvise:
8122
        /* A straight passthrough may not be safe because qemu sometimes
8123
           turns private flie-backed mappings into anonymous mappings.
8124
           This will break MADV_DONTNEED.
8125
           This is a hint, so ignoring and returning success is ok.  */
8126
        ret = get_errno(0);
8127
        break;
8128
#endif
8129
#if TARGET_ABI_BITS == 32
8130
    case TARGET_NR_fcntl64:
8131
    {
8132
        int cmd;
8133
        struct flock64 fl;
8134
        struct target_flock64 *target_fl;
8135
#ifdef TARGET_ARM
8136
        struct target_eabi_flock64 *target_efl;
8137
#endif
8138

    
8139
        cmd = target_to_host_fcntl_cmd(arg2);
8140
        if (cmd == -TARGET_EINVAL) {
8141
            ret = cmd;
8142
            break;
8143
        }
8144

    
8145
        switch(arg2) {
8146
        case TARGET_F_GETLK64:
8147
#ifdef TARGET_ARM
8148
            if (((CPUARMState *)cpu_env)->eabi) {
8149
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
8150
                    goto efault;
8151
                fl.l_type = tswap16(target_efl->l_type);
8152
                fl.l_whence = tswap16(target_efl->l_whence);
8153
                fl.l_start = tswap64(target_efl->l_start);
8154
                fl.l_len = tswap64(target_efl->l_len);
8155
                fl.l_pid = tswap32(target_efl->l_pid);
8156
                unlock_user_struct(target_efl, arg3, 0);
8157
            } else
8158
#endif
8159
            {
8160
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
8161
                    goto efault;
8162
                fl.l_type = tswap16(target_fl->l_type);
8163
                fl.l_whence = tswap16(target_fl->l_whence);
8164
                fl.l_start = tswap64(target_fl->l_start);
8165
                fl.l_len = tswap64(target_fl->l_len);
8166
                fl.l_pid = tswap32(target_fl->l_pid);
8167
                unlock_user_struct(target_fl, arg3, 0);
8168
            }
8169
            ret = get_errno(fcntl(arg1, cmd, &fl));
8170
            if (ret == 0) {
8171
#ifdef TARGET_ARM
8172
                if (((CPUARMState *)cpu_env)->eabi) {
8173
                    if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) 
8174
                        goto efault;
8175
                    target_efl->l_type = tswap16(fl.l_type);
8176
                    target_efl->l_whence = tswap16(fl.l_whence);
8177
                    target_efl->l_start = tswap64(fl.l_start);
8178
                    target_efl->l_len = tswap64(fl.l_len);
8179
                    target_efl->l_pid = tswap32(fl.l_pid);
8180
                    unlock_user_struct(target_efl, arg3, 1);
8181
                } else
8182
#endif
8183
                {
8184
                    if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) 
8185
                        goto efault;
8186
                    target_fl->l_type = tswap16(fl.l_type);
8187
                    target_fl->l_whence = tswap16(fl.l_whence);
8188
                    target_fl->l_start = tswap64(fl.l_start);
8189
                    target_fl->l_len = tswap64(fl.l_len);
8190
                    target_fl->l_pid = tswap32(fl.l_pid);
8191
                    unlock_user_struct(target_fl, arg3, 1);
8192
                }
8193
            }
8194
            break;
8195

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

    
8463
#ifdef TARGET_NR_clock_gettime
8464
    case TARGET_NR_clock_gettime:
8465
    {
8466
        struct timespec ts;
8467
        ret = get_errno(clock_gettime(arg1, &ts));
8468
        if (!is_error(ret)) {
8469
            host_to_target_timespec(arg2, &ts);
8470
        }
8471
        break;
8472
    }
8473
#endif
8474
#ifdef TARGET_NR_clock_getres
8475
    case TARGET_NR_clock_getres:
8476
    {
8477
        struct timespec ts;
8478
        ret = get_errno(clock_getres(arg1, &ts));
8479
        if (!is_error(ret)) {
8480
            host_to_target_timespec(arg2, &ts);
8481
        }
8482
        break;
8483
    }
8484
#endif
8485
#ifdef TARGET_NR_clock_nanosleep
8486
    case TARGET_NR_clock_nanosleep:
8487
    {
8488
        struct timespec ts;
8489
        target_to_host_timespec(&ts, arg3);
8490
        ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
8491
        if (arg4)
8492
            host_to_target_timespec(arg4, &ts);
8493
        break;
8494
    }
8495
#endif
8496

    
8497
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
8498
    case TARGET_NR_set_tid_address:
8499
        ret = get_errno(set_tid_address((int *)g2h(arg1)));
8500
        break;
8501
#endif
8502

    
8503
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
8504
    case TARGET_NR_tkill:
8505
        ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
8506
        break;
8507
#endif
8508

    
8509
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
8510
    case TARGET_NR_tgkill:
8511
        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
8512
                        target_to_host_signal(arg3)));
8513
        break;
8514
#endif
8515

    
8516
#ifdef TARGET_NR_set_robust_list
8517
    case TARGET_NR_set_robust_list:
8518
        goto unimplemented_nowarn;
8519
#endif
8520

    
8521
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
8522
    case TARGET_NR_utimensat:
8523
        {
8524
            struct timespec *tsp, ts[2];
8525
            if (!arg3) {
8526
                tsp = NULL;
8527
            } else {
8528
                target_to_host_timespec(ts, arg3);
8529
                target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
8530
                tsp = ts;
8531
            }
8532
            if (!arg2)
8533
                ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4));
8534
            else {
8535
                if (!(p = lock_user_string(arg2))) {
8536
                    ret = -TARGET_EFAULT;
8537
                    goto fail;
8538
                }
8539
                ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4));
8540
                unlock_user(p, arg2, 0);
8541
            }
8542
        }
8543
        break;
8544
#endif
8545
#if defined(CONFIG_USE_NPTL)
8546
    case TARGET_NR_futex:
8547
        ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
8548
        break;
8549
#endif
8550
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
8551
    case TARGET_NR_inotify_init:
8552
        ret = get_errno(sys_inotify_init());
8553
        break;
8554
#endif
8555
#ifdef CONFIG_INOTIFY1
8556
#if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
8557
    case TARGET_NR_inotify_init1:
8558
        ret = get_errno(sys_inotify_init1(arg1));
8559
        break;
8560
#endif
8561
#endif
8562
#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
8563
    case TARGET_NR_inotify_add_watch:
8564
        p = lock_user_string(arg2);
8565
        ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
8566
        unlock_user(p, arg2, 0);
8567
        break;
8568
#endif
8569
#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
8570
    case TARGET_NR_inotify_rm_watch:
8571
        ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
8572
        break;
8573
#endif
8574

    
8575
#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
8576
    case TARGET_NR_mq_open:
8577
        {
8578
            struct mq_attr posix_mq_attr;
8579

    
8580
            p = lock_user_string(arg1 - 1);
8581
            if (arg4 != 0)
8582
                copy_from_user_mq_attr (&posix_mq_attr, arg4);
8583
            ret = get_errno(mq_open(p, arg2, arg3, &posix_mq_attr));
8584
            unlock_user (p, arg1, 0);
8585
        }
8586
        break;
8587

    
8588
    case TARGET_NR_mq_unlink:
8589
        p = lock_user_string(arg1 - 1);
8590
        ret = get_errno(mq_unlink(p));
8591
        unlock_user (p, arg1, 0);
8592
        break;
8593

    
8594
    case TARGET_NR_mq_timedsend:
8595
        {
8596
            struct timespec ts;
8597

    
8598
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
8599
            if (arg5 != 0) {
8600
                target_to_host_timespec(&ts, arg5);
8601
                ret = get_errno(mq_timedsend(arg1, p, arg3, arg4, &ts));
8602
                host_to_target_timespec(arg5, &ts);
8603
            }
8604
            else
8605
                ret = get_errno(mq_send(arg1, p, arg3, arg4));
8606
            unlock_user (p, arg2, arg3);
8607
        }
8608
        break;
8609

    
8610
    case TARGET_NR_mq_timedreceive:
8611
        {
8612
            struct timespec ts;
8613
            unsigned int prio;
8614

    
8615
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
8616
            if (arg5 != 0) {
8617
                target_to_host_timespec(&ts, arg5);
8618
                ret = get_errno(mq_timedreceive(arg1, p, arg3, &prio, &ts));
8619
                host_to_target_timespec(arg5, &ts);
8620
            }
8621
            else
8622
                ret = get_errno(mq_receive(arg1, p, arg3, &prio));
8623
            unlock_user (p, arg2, arg3);
8624
            if (arg4 != 0)
8625
                put_user_u32(prio, arg4);
8626
        }
8627
        break;
8628

    
8629
    /* Not implemented for now... */
8630
/*     case TARGET_NR_mq_notify: */
8631
/*         break; */
8632

    
8633
    case TARGET_NR_mq_getsetattr:
8634
        {
8635
            struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
8636
            ret = 0;
8637
            if (arg3 != 0) {
8638
                ret = mq_getattr(arg1, &posix_mq_attr_out);
8639
                copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
8640
            }
8641
            if (arg2 != 0) {
8642
                copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
8643
                ret |= mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_attr_out);
8644
            }
8645

    
8646
        }
8647
        break;
8648
#endif
8649

    
8650
#ifdef CONFIG_SPLICE
8651
#ifdef TARGET_NR_tee
8652
    case TARGET_NR_tee:
8653
        {
8654
            ret = get_errno(tee(arg1,arg2,arg3,arg4));
8655
        }
8656
        break;
8657
#endif
8658
#ifdef TARGET_NR_splice
8659
    case TARGET_NR_splice:
8660
        {
8661
            loff_t loff_in, loff_out;
8662
            loff_t *ploff_in = NULL, *ploff_out = NULL;
8663
            if(arg2) {
8664
                get_user_u64(loff_in, arg2);
8665
                ploff_in = &loff_in;
8666
            }
8667
            if(arg4) {
8668
                get_user_u64(loff_out, arg2);
8669
                ploff_out = &loff_out;
8670
            }
8671
            ret = get_errno(splice(arg1, ploff_in, arg3, ploff_out, arg5, arg6));
8672
        }
8673
        break;
8674
#endif
8675
#ifdef TARGET_NR_vmsplice
8676
        case TARGET_NR_vmsplice:
8677
        {
8678
            struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
8679
            if (vec != NULL) {
8680
                ret = get_errno(vmsplice(arg1, vec, arg3, arg4));
8681
                unlock_iovec(vec, arg2, arg3, 0);
8682
            } else {
8683
                ret = -host_to_target_errno(errno);
8684
            }
8685
        }
8686
        break;
8687
#endif
8688
#endif /* CONFIG_SPLICE */
8689
#ifdef CONFIG_EVENTFD
8690
#if defined(TARGET_NR_eventfd)
8691
    case TARGET_NR_eventfd:
8692
        ret = get_errno(eventfd(arg1, 0));
8693
        break;
8694
#endif
8695
#if defined(TARGET_NR_eventfd2)
8696
    case TARGET_NR_eventfd2:
8697
        ret = get_errno(eventfd(arg1, arg2));
8698
        break;
8699
#endif
8700
#endif /* CONFIG_EVENTFD  */
8701
#if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate)
8702
    case TARGET_NR_fallocate:
8703
#if TARGET_ABI_BITS == 32
8704
        ret = get_errno(fallocate(arg1, arg2, target_offset64(arg3, arg4),
8705
                                  target_offset64(arg5, arg6)));
8706
#else
8707
        ret = get_errno(fallocate(arg1, arg2, arg3, arg4));
8708
#endif
8709
        break;
8710
#endif
8711
#if defined(CONFIG_SYNC_FILE_RANGE)
8712
#if defined(TARGET_NR_sync_file_range)
8713
    case TARGET_NR_sync_file_range:
8714
#if TARGET_ABI_BITS == 32
8715
#if defined(TARGET_MIPS)
8716
        ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
8717
                                        target_offset64(arg5, arg6), arg7));
8718
#else
8719
        ret = get_errno(sync_file_range(arg1, target_offset64(arg2, arg3),
8720
                                        target_offset64(arg4, arg5), arg6));
8721
#endif /* !TARGET_MIPS */
8722
#else
8723
        ret = get_errno(sync_file_range(arg1, arg2, arg3, arg4));
8724
#endif
8725
        break;
8726
#endif
8727
#if defined(TARGET_NR_sync_file_range2)
8728
    case TARGET_NR_sync_file_range2:
8729
        /* This is like sync_file_range but the arguments are reordered */
8730
#if TARGET_ABI_BITS == 32
8731
        ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
8732
                                        target_offset64(arg5, arg6), arg2));
8733
#else
8734
        ret = get_errno(sync_file_range(arg1, arg3, arg4, arg2));
8735
#endif
8736
        break;
8737
#endif
8738
#endif
8739
#if defined(CONFIG_EPOLL)
8740
#if defined(TARGET_NR_epoll_create)
8741
    case TARGET_NR_epoll_create:
8742
        ret = get_errno(epoll_create(arg1));
8743
        break;
8744
#endif
8745
#if defined(TARGET_NR_epoll_create1) && defined(CONFIG_EPOLL_CREATE1)
8746
    case TARGET_NR_epoll_create1:
8747
        ret = get_errno(epoll_create1(arg1));
8748
        break;
8749
#endif
8750
#if defined(TARGET_NR_epoll_ctl)
8751
    case TARGET_NR_epoll_ctl:
8752
    {
8753
        struct epoll_event ep;
8754
        struct epoll_event *epp = 0;
8755
        if (arg4) {
8756
            struct target_epoll_event *target_ep;
8757
            if (!lock_user_struct(VERIFY_READ, target_ep, arg4, 1)) {
8758
                goto efault;
8759
            }
8760
            ep.events = tswap32(target_ep->events);
8761
            /* The epoll_data_t union is just opaque data to the kernel,
8762
             * so we transfer all 64 bits across and need not worry what
8763
             * actual data type it is.
8764
             */
8765
            ep.data.u64 = tswap64(target_ep->data.u64);
8766
            unlock_user_struct(target_ep, arg4, 0);
8767
            epp = &ep;
8768
        }
8769
        ret = get_errno(epoll_ctl(arg1, arg2, arg3, epp));
8770
        break;
8771
    }
8772
#endif
8773

    
8774
#if defined(TARGET_NR_epoll_pwait) && defined(CONFIG_EPOLL_PWAIT)
8775
#define IMPLEMENT_EPOLL_PWAIT
8776
#endif
8777
#if defined(TARGET_NR_epoll_wait) || defined(IMPLEMENT_EPOLL_PWAIT)
8778
#if defined(TARGET_NR_epoll_wait)
8779
    case TARGET_NR_epoll_wait:
8780
#endif
8781
#if defined(IMPLEMENT_EPOLL_PWAIT)
8782
    case TARGET_NR_epoll_pwait:
8783
#endif
8784
    {
8785
        struct target_epoll_event *target_ep;
8786
        struct epoll_event *ep;
8787
        int epfd = arg1;
8788
        int maxevents = arg3;
8789
        int timeout = arg4;
8790

    
8791
        target_ep = lock_user(VERIFY_WRITE, arg2,
8792
                              maxevents * sizeof(struct target_epoll_event), 1);
8793
        if (!target_ep) {
8794
            goto efault;
8795
        }
8796

    
8797
        ep = alloca(maxevents * sizeof(struct epoll_event));
8798

    
8799
        switch (num) {
8800
#if defined(IMPLEMENT_EPOLL_PWAIT)
8801
        case TARGET_NR_epoll_pwait:
8802
        {
8803
            target_sigset_t *target_set;
8804
            sigset_t _set, *set = &_set;
8805

    
8806
            if (arg5) {
8807
                target_set = lock_user(VERIFY_READ, arg5,
8808
                                       sizeof(target_sigset_t), 1);
8809
                if (!target_set) {
8810
                    unlock_user(target_ep, arg2, 0);
8811
                    goto efault;
8812
                }
8813
                target_to_host_sigset(set, target_set);
8814
                unlock_user(target_set, arg5, 0);
8815
            } else {
8816
                set = NULL;
8817
            }
8818

    
8819
            ret = get_errno(epoll_pwait(epfd, ep, maxevents, timeout, set));
8820
            break;
8821
        }
8822
#endif
8823
#if defined(TARGET_NR_epoll_wait)
8824
        case TARGET_NR_epoll_wait:
8825
            ret = get_errno(epoll_wait(epfd, ep, maxevents, timeout));
8826
            break;
8827
#endif
8828
        default:
8829
            ret = -TARGET_ENOSYS;
8830
        }
8831
        if (!is_error(ret)) {
8832
            int i;
8833
            for (i = 0; i < ret; i++) {
8834
                target_ep[i].events = tswap32(ep[i].events);
8835
                target_ep[i].data.u64 = tswap64(ep[i].data.u64);
8836
            }
8837
        }
8838
        unlock_user(target_ep, arg2, ret * sizeof(struct target_epoll_event));
8839
        break;
8840
    }
8841
#endif
8842
#endif
8843
#ifdef TARGET_NR_prlimit64
8844
    case TARGET_NR_prlimit64:
8845
    {
8846
        /* args: pid, resource number, ptr to new rlimit, ptr to old rlimit */
8847
        struct target_rlimit64 *target_rnew, *target_rold;
8848
        struct host_rlimit64 rnew, rold, *rnewp = 0;
8849
        if (arg3) {
8850
            if (!lock_user_struct(VERIFY_READ, target_rnew, arg3, 1)) {
8851
                goto efault;
8852
            }
8853
            rnew.rlim_cur = tswap64(target_rnew->rlim_cur);
8854
            rnew.rlim_max = tswap64(target_rnew->rlim_max);
8855
            unlock_user_struct(target_rnew, arg3, 0);
8856
            rnewp = &rnew;
8857
        }
8858

    
8859
        ret = get_errno(sys_prlimit64(arg1, arg2, rnewp, arg4 ? &rold : 0));
8860
        if (!is_error(ret) && arg4) {
8861
            if (!lock_user_struct(VERIFY_WRITE, target_rold, arg4, 1)) {
8862
                goto efault;
8863
            }
8864
            target_rold->rlim_cur = tswap64(rold.rlim_cur);
8865
            target_rold->rlim_max = tswap64(rold.rlim_max);
8866
            unlock_user_struct(target_rold, arg4, 1);
8867
        }
8868
        break;
8869
    }
8870
#endif
8871
#ifdef TARGET_NR_gethostname
8872
    case TARGET_NR_gethostname:
8873
    {
8874
        char *name = lock_user(VERIFY_WRITE, arg1, arg2, 0);
8875
        if (name) {
8876
            ret = get_errno(gethostname(name, arg2));
8877
            unlock_user(name, arg1, arg2);
8878
        } else {
8879
            ret = -TARGET_EFAULT;
8880
        }
8881
        break;
8882
    }
8883
#endif
8884
    default:
8885
    unimplemented:
8886
        gemu_log("qemu: Unsupported syscall: %d\n", num);
8887
#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
8888
    unimplemented_nowarn:
8889
#endif
8890
        ret = -TARGET_ENOSYS;
8891
        break;
8892
    }
8893
fail:
8894
#ifdef DEBUG
8895
    gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
8896
#endif
8897
    if(do_strace)
8898
        print_syscall_ret(num, ret);
8899
    return ret;
8900
efault:
8901
    ret = -TARGET_EFAULT;
8902
    goto fail;
8903
}