Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ 9e0e2f96

History | View | Annotate | Download (251.9 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 "qemu-common.h"
64
#ifdef TARGET_GPROF
65
#include <sys/gmon.h>
66
#endif
67
#ifdef CONFIG_EVENTFD
68
#include <sys/eventfd.h>
69
#endif
70
#ifdef CONFIG_EPOLL
71
#include <sys/epoll.h>
72
#endif
73
#ifdef CONFIG_ATTR
74
#include <attr/xattr.h>
75
#endif
76

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

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

    
101
#include "qemu.h"
102

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

    
111
//#define DEBUG
112

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

    
117

    
118
#undef _syscall0
119
#undef _syscall1
120
#undef _syscall2
121
#undef _syscall3
122
#undef _syscall4
123
#undef _syscall5
124
#undef _syscall6
125

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

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

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

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

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

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

    
163

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

    
172

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

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

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

    
254
static bitmask_transtbl fcntl_flags_tbl[] = {
255
  { TARGET_O_ACCMODE,   TARGET_O_WRONLY,    O_ACCMODE,   O_WRONLY,    },
256
  { TARGET_O_ACCMODE,   TARGET_O_RDWR,      O_ACCMODE,   O_RDWR,      },
257
  { TARGET_O_CREAT,     TARGET_O_CREAT,     O_CREAT,     O_CREAT,     },
258
  { TARGET_O_EXCL,      TARGET_O_EXCL,      O_EXCL,      O_EXCL,      },
259
  { TARGET_O_NOCTTY,    TARGET_O_NOCTTY,    O_NOCTTY,    O_NOCTTY,    },
260
  { TARGET_O_TRUNC,     TARGET_O_TRUNC,     O_TRUNC,     O_TRUNC,     },
261
  { TARGET_O_APPEND,    TARGET_O_APPEND,    O_APPEND,    O_APPEND,    },
262
  { TARGET_O_NONBLOCK,  TARGET_O_NONBLOCK,  O_NONBLOCK,  O_NONBLOCK,  },
263
  { TARGET_O_SYNC,      TARGET_O_SYNC,      O_SYNC,      O_SYNC,      },
264
  { TARGET_FASYNC,      TARGET_FASYNC,      FASYNC,      FASYNC,      },
265
  { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
266
  { TARGET_O_NOFOLLOW,  TARGET_O_NOFOLLOW,  O_NOFOLLOW,  O_NOFOLLOW,  },
267
  { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
268
#if defined(O_DIRECT)
269
  { TARGET_O_DIRECT,    TARGET_O_DIRECT,    O_DIRECT,    O_DIRECT,    },
270
#endif
271
  { 0, 0, 0, 0 }
272
};
273

    
274
#define COPY_UTSNAME_FIELD(dest, src) \
275
  do { \
276
      /* __NEW_UTS_LEN doesn't include terminating null */ \
277
      (void) strncpy((dest), (src), __NEW_UTS_LEN); \
278
      (dest)[__NEW_UTS_LEN] = '\0'; \
279
  } while (0)
280

    
281
static int sys_uname(struct new_utsname *buf)
282
{
283
  struct utsname uts_buf;
284

    
285
  if (uname(&uts_buf) < 0)
286
      return (-1);
287

    
288
  /*
289
   * Just in case these have some differences, we
290
   * translate utsname to new_utsname (which is the
291
   * struct linux kernel uses).
292
   */
293

    
294
  memset(buf, 0, sizeof(*buf));
295
  COPY_UTSNAME_FIELD(buf->sysname, uts_buf.sysname);
296
  COPY_UTSNAME_FIELD(buf->nodename, uts_buf.nodename);
297
  COPY_UTSNAME_FIELD(buf->release, uts_buf.release);
298
  COPY_UTSNAME_FIELD(buf->version, uts_buf.version);
299
  COPY_UTSNAME_FIELD(buf->machine, uts_buf.machine);
300
#ifdef _GNU_SOURCE
301
  COPY_UTSNAME_FIELD(buf->domainname, uts_buf.domainname);
302
#endif
303
  return (0);
304

    
305
#undef COPY_UTSNAME_FIELD
306
}
307

    
308
static int sys_getcwd1(char *buf, size_t size)
309
{
310
  if (getcwd(buf, size) == NULL) {
311
      /* getcwd() sets errno */
312
      return (-1);
313
  }
314
  return strlen(buf)+1;
315
}
316

    
317
#ifdef CONFIG_ATFILE
318
/*
319
 * Host system seems to have atfile syscall stubs available.  We
320
 * now enable them one by one as specified by target syscall_nr.h.
321
 */
322

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

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

    
480
#endif /* CONFIG_ATFILE */
481

    
482
#ifdef CONFIG_UTIMENSAT
483
static int sys_utimensat(int dirfd, const char *pathname,
484
    const struct timespec times[2], int flags)
485
{
486
    if (pathname == NULL)
487
        return futimens(dirfd, times);
488
    else
489
        return utimensat(dirfd, pathname, times, flags);
490
}
491
#else
492
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
493
_syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
494
          const struct timespec *,tsp,int,flags)
495
#endif
496
#endif /* CONFIG_UTIMENSAT  */
497

    
498
#ifdef CONFIG_INOTIFY
499
#include <sys/inotify.h>
500

    
501
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
502
static int sys_inotify_init(void)
503
{
504
  return (inotify_init());
505
}
506
#endif
507
#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
508
static int sys_inotify_add_watch(int fd,const char *pathname, int32_t mask)
509
{
510
  return (inotify_add_watch(fd, pathname, mask));
511
}
512
#endif
513
#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
514
static int sys_inotify_rm_watch(int fd, int32_t wd)
515
{
516
  return (inotify_rm_watch(fd, wd));
517
}
518
#endif
519
#ifdef CONFIG_INOTIFY1
520
#if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
521
static int sys_inotify_init1(int flags)
522
{
523
  return (inotify_init1(flags));
524
}
525
#endif
526
#endif
527
#else
528
/* Userspace can usually survive runtime without inotify */
529
#undef TARGET_NR_inotify_init
530
#undef TARGET_NR_inotify_init1
531
#undef TARGET_NR_inotify_add_watch
532
#undef TARGET_NR_inotify_rm_watch
533
#endif /* CONFIG_INOTIFY  */
534

    
535
#if defined(TARGET_NR_ppoll)
536
#ifndef __NR_ppoll
537
# define __NR_ppoll -1
538
#endif
539
#define __NR_sys_ppoll __NR_ppoll
540
_syscall5(int, sys_ppoll, struct pollfd *, fds, nfds_t, nfds,
541
          struct timespec *, timeout, const __sigset_t *, sigmask,
542
          size_t, sigsetsize)
543
#endif
544

    
545
#if defined(TARGET_NR_pselect6)
546
#ifndef __NR_pselect6
547
# define __NR_pselect6 -1
548
#endif
549
#define __NR_sys_pselect6 __NR_pselect6
550
_syscall6(int, sys_pselect6, int, nfds, fd_set *, readfds, fd_set *, writefds,
551
          fd_set *, exceptfds, struct timespec *, timeout, void *, sig);
552
#endif
553

    
554
#if defined(TARGET_NR_prlimit64)
555
#ifndef __NR_prlimit64
556
# define __NR_prlimit64 -1
557
#endif
558
#define __NR_sys_prlimit64 __NR_prlimit64
559
/* The glibc rlimit structure may not be that used by the underlying syscall */
560
struct host_rlimit64 {
561
    uint64_t rlim_cur;
562
    uint64_t rlim_max;
563
};
564
_syscall4(int, sys_prlimit64, pid_t, pid, int, resource,
565
          const struct host_rlimit64 *, new_limit,
566
          struct host_rlimit64 *, old_limit)
567
#endif
568

    
569
extern int personality(int);
570
extern int flock(int, int);
571
extern int setfsuid(int);
572
extern int setfsgid(int);
573
extern int setgroups(int, gid_t *);
574

    
575
/* ARM EABI and MIPS expect 64bit types aligned even on pairs or registers */
576
#ifdef TARGET_ARM 
577
static inline int regpairs_aligned(void *cpu_env) {
578
    return ((((CPUARMState *)cpu_env)->eabi) == 1) ;
579
}
580
#elif defined(TARGET_MIPS)
581
static inline int regpairs_aligned(void *cpu_env) { return 1; }
582
#else
583
static inline int regpairs_aligned(void *cpu_env) { return 0; }
584
#endif
585

    
586
#define ERRNO_TABLE_SIZE 1200
587

    
588
/* target_to_host_errno_table[] is initialized from
589
 * host_to_target_errno_table[] in syscall_init(). */
590
static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
591
};
592

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

    
705
static inline int host_to_target_errno(int err)
706
{
707
    if(host_to_target_errno_table[err])
708
        return host_to_target_errno_table[err];
709
    return err;
710
}
711

    
712
static inline int target_to_host_errno(int err)
713
{
714
    if (target_to_host_errno_table[err])
715
        return target_to_host_errno_table[err];
716
    return err;
717
}
718

    
719
static inline abi_long get_errno(abi_long ret)
720
{
721
    if (ret == -1)
722
        return -host_to_target_errno(errno);
723
    else
724
        return ret;
725
}
726

    
727
static inline int is_error(abi_long ret)
728
{
729
    return (abi_ulong)ret >= (abi_ulong)(-4096);
730
}
731

    
732
char *target_strerror(int err)
733
{
734
    return strerror(target_to_host_errno(err));
735
}
736

    
737
static abi_ulong target_brk;
738
static abi_ulong target_original_brk;
739
static abi_ulong brk_page;
740

    
741
void target_set_brk(abi_ulong new_brk)
742
{
743
    target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
744
    brk_page = HOST_PAGE_ALIGN(target_brk);
745
}
746

    
747
//#define DEBUGF_BRK(message, args...) do { fprintf(stderr, (message), ## args); } while (0)
748
#define DEBUGF_BRK(message, args...)
749

    
750
/* do_brk() must return target values and target errnos. */
751
abi_long do_brk(abi_ulong new_brk)
752
{
753
    abi_long mapped_addr;
754
    int        new_alloc_size;
755

    
756
    DEBUGF_BRK("do_brk(%#010x) -> ", new_brk);
757

    
758
    if (!new_brk) {
759
        DEBUGF_BRK("%#010x (!new_brk)\n", target_brk);
760
        return target_brk;
761
    }
762
    if (new_brk < target_original_brk) {
763
        DEBUGF_BRK("%#010x (new_brk < target_original_brk)\n", target_brk);
764
        return target_brk;
765
    }
766

    
767
    /* If the new brk is less than the highest page reserved to the
768
     * target heap allocation, set it and we're almost done...  */
769
    if (new_brk <= brk_page) {
770
        /* Heap contents are initialized to zero, as for anonymous
771
         * mapped pages.  */
772
        if (new_brk > target_brk) {
773
            memset(g2h(target_brk), 0, new_brk - target_brk);
774
        }
775
        target_brk = new_brk;
776
        DEBUGF_BRK("%#010x (new_brk <= brk_page)\n", target_brk);
777
            return target_brk;
778
    }
779

    
780
    /* We need to allocate more memory after the brk... Note that
781
     * we don't use MAP_FIXED because that will map over the top of
782
     * any existing mapping (like the one with the host libc or qemu
783
     * itself); instead we treat "mapped but at wrong address" as
784
     * a failure and unmap again.
785
     */
786
    new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page);
787
    mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
788
                                        PROT_READ|PROT_WRITE,
789
                                        MAP_ANON|MAP_PRIVATE, 0, 0));
790

    
791
    if (mapped_addr == brk_page) {
792
        /* Heap contents are initialized to zero, as for anonymous
793
         * mapped pages.  Technically the new pages are already
794
         * initialized to zero since they *are* anonymous mapped
795
         * pages, however we have to take care with the contents that
796
         * come from the remaining part of the previous page: it may
797
         * contains garbage data due to a previous heap usage (grown
798
         * then shrunken).  */
799
        memset(g2h(target_brk), 0, brk_page - target_brk);
800

    
801
        target_brk = new_brk;
802
        brk_page = HOST_PAGE_ALIGN(target_brk);
803
        DEBUGF_BRK("%#010x (mapped_addr == brk_page)\n", target_brk);
804
        return target_brk;
805
    } else if (mapped_addr != -1) {
806
        /* Mapped but at wrong address, meaning there wasn't actually
807
         * enough space for this brk.
808
         */
809
        target_munmap(mapped_addr, new_alloc_size);
810
        mapped_addr = -1;
811
        DEBUGF_BRK("%#010x (mapped_addr != -1)\n", target_brk);
812
    }
813
    else {
814
        DEBUGF_BRK("%#010x (otherwise)\n", target_brk);
815
    }
816

    
817
#if defined(TARGET_ALPHA)
818
    /* We (partially) emulate OSF/1 on Alpha, which requires we
819
       return a proper errno, not an unchanged brk value.  */
820
    return -TARGET_ENOMEM;
821
#endif
822
    /* For everything else, return the previous break. */
823
    return target_brk;
824
}
825

    
826
static inline abi_long copy_from_user_fdset(fd_set *fds,
827
                                            abi_ulong target_fds_addr,
828
                                            int n)
829
{
830
    int i, nw, j, k;
831
    abi_ulong b, *target_fds;
832

    
833
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
834
    if (!(target_fds = lock_user(VERIFY_READ,
835
                                 target_fds_addr,
836
                                 sizeof(abi_ulong) * nw,
837
                                 1)))
838
        return -TARGET_EFAULT;
839

    
840
    FD_ZERO(fds);
841
    k = 0;
842
    for (i = 0; i < nw; i++) {
843
        /* grab the abi_ulong */
844
        __get_user(b, &target_fds[i]);
845
        for (j = 0; j < TARGET_ABI_BITS; j++) {
846
            /* check the bit inside the abi_ulong */
847
            if ((b >> j) & 1)
848
                FD_SET(k, fds);
849
            k++;
850
        }
851
    }
852

    
853
    unlock_user(target_fds, target_fds_addr, 0);
854

    
855
    return 0;
856
}
857

    
858
static inline abi_ulong copy_from_user_fdset_ptr(fd_set *fds, fd_set **fds_ptr,
859
                                                 abi_ulong target_fds_addr,
860
                                                 int n)
861
{
862
    if (target_fds_addr) {
863
        if (copy_from_user_fdset(fds, target_fds_addr, n))
864
            return -TARGET_EFAULT;
865
        *fds_ptr = fds;
866
    } else {
867
        *fds_ptr = NULL;
868
    }
869
    return 0;
870
}
871

    
872
static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
873
                                          const fd_set *fds,
874
                                          int n)
875
{
876
    int i, nw, j, k;
877
    abi_long v;
878
    abi_ulong *target_fds;
879

    
880
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
881
    if (!(target_fds = lock_user(VERIFY_WRITE,
882
                                 target_fds_addr,
883
                                 sizeof(abi_ulong) * nw,
884
                                 0)))
885
        return -TARGET_EFAULT;
886

    
887
    k = 0;
888
    for (i = 0; i < nw; i++) {
889
        v = 0;
890
        for (j = 0; j < TARGET_ABI_BITS; j++) {
891
            v |= ((FD_ISSET(k, fds) != 0) << j);
892
            k++;
893
        }
894
        __put_user(v, &target_fds[i]);
895
    }
896

    
897
    unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
898

    
899
    return 0;
900
}
901

    
902
#if defined(__alpha__)
903
#define HOST_HZ 1024
904
#else
905
#define HOST_HZ 100
906
#endif
907

    
908
static inline abi_long host_to_target_clock_t(long ticks)
909
{
910
#if HOST_HZ == TARGET_HZ
911
    return ticks;
912
#else
913
    return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
914
#endif
915
}
916

    
917
static inline abi_long host_to_target_rusage(abi_ulong target_addr,
918
                                             const struct rusage *rusage)
919
{
920
    struct target_rusage *target_rusage;
921

    
922
    if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
923
        return -TARGET_EFAULT;
924
    target_rusage->ru_utime.tv_sec = tswapal(rusage->ru_utime.tv_sec);
925
    target_rusage->ru_utime.tv_usec = tswapal(rusage->ru_utime.tv_usec);
926
    target_rusage->ru_stime.tv_sec = tswapal(rusage->ru_stime.tv_sec);
927
    target_rusage->ru_stime.tv_usec = tswapal(rusage->ru_stime.tv_usec);
928
    target_rusage->ru_maxrss = tswapal(rusage->ru_maxrss);
929
    target_rusage->ru_ixrss = tswapal(rusage->ru_ixrss);
930
    target_rusage->ru_idrss = tswapal(rusage->ru_idrss);
931
    target_rusage->ru_isrss = tswapal(rusage->ru_isrss);
932
    target_rusage->ru_minflt = tswapal(rusage->ru_minflt);
933
    target_rusage->ru_majflt = tswapal(rusage->ru_majflt);
934
    target_rusage->ru_nswap = tswapal(rusage->ru_nswap);
935
    target_rusage->ru_inblock = tswapal(rusage->ru_inblock);
936
    target_rusage->ru_oublock = tswapal(rusage->ru_oublock);
937
    target_rusage->ru_msgsnd = tswapal(rusage->ru_msgsnd);
938
    target_rusage->ru_msgrcv = tswapal(rusage->ru_msgrcv);
939
    target_rusage->ru_nsignals = tswapal(rusage->ru_nsignals);
940
    target_rusage->ru_nvcsw = tswapal(rusage->ru_nvcsw);
941
    target_rusage->ru_nivcsw = tswapal(rusage->ru_nivcsw);
942
    unlock_user_struct(target_rusage, target_addr, 1);
943

    
944
    return 0;
945
}
946

    
947
static inline rlim_t target_to_host_rlim(abi_ulong target_rlim)
948
{
949
    abi_ulong target_rlim_swap;
950
    rlim_t result;
951
    
952
    target_rlim_swap = tswapal(target_rlim);
953
    if (target_rlim_swap == TARGET_RLIM_INFINITY)
954
        return RLIM_INFINITY;
955

    
956
    result = target_rlim_swap;
957
    if (target_rlim_swap != (rlim_t)result)
958
        return RLIM_INFINITY;
959
    
960
    return result;
961
}
962

    
963
static inline abi_ulong host_to_target_rlim(rlim_t rlim)
964
{
965
    abi_ulong target_rlim_swap;
966
    abi_ulong result;
967
    
968
    if (rlim == RLIM_INFINITY || rlim != (abi_long)rlim)
969
        target_rlim_swap = TARGET_RLIM_INFINITY;
970
    else
971
        target_rlim_swap = rlim;
972
    result = tswapal(target_rlim_swap);
973
    
974
    return result;
975
}
976

    
977
static inline int target_to_host_resource(int code)
978
{
979
    switch (code) {
980
    case TARGET_RLIMIT_AS:
981
        return RLIMIT_AS;
982
    case TARGET_RLIMIT_CORE:
983
        return RLIMIT_CORE;
984
    case TARGET_RLIMIT_CPU:
985
        return RLIMIT_CPU;
986
    case TARGET_RLIMIT_DATA:
987
        return RLIMIT_DATA;
988
    case TARGET_RLIMIT_FSIZE:
989
        return RLIMIT_FSIZE;
990
    case TARGET_RLIMIT_LOCKS:
991
        return RLIMIT_LOCKS;
992
    case TARGET_RLIMIT_MEMLOCK:
993
        return RLIMIT_MEMLOCK;
994
    case TARGET_RLIMIT_MSGQUEUE:
995
        return RLIMIT_MSGQUEUE;
996
    case TARGET_RLIMIT_NICE:
997
        return RLIMIT_NICE;
998
    case TARGET_RLIMIT_NOFILE:
999
        return RLIMIT_NOFILE;
1000
    case TARGET_RLIMIT_NPROC:
1001
        return RLIMIT_NPROC;
1002
    case TARGET_RLIMIT_RSS:
1003
        return RLIMIT_RSS;
1004
    case TARGET_RLIMIT_RTPRIO:
1005
        return RLIMIT_RTPRIO;
1006
    case TARGET_RLIMIT_SIGPENDING:
1007
        return RLIMIT_SIGPENDING;
1008
    case TARGET_RLIMIT_STACK:
1009
        return RLIMIT_STACK;
1010
    default:
1011
        return code;
1012
    }
1013
}
1014

    
1015
static inline abi_long copy_from_user_timeval(struct timeval *tv,
1016
                                              abi_ulong target_tv_addr)
1017
{
1018
    struct target_timeval *target_tv;
1019

    
1020
    if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
1021
        return -TARGET_EFAULT;
1022

    
1023
    __get_user(tv->tv_sec, &target_tv->tv_sec);
1024
    __get_user(tv->tv_usec, &target_tv->tv_usec);
1025

    
1026
    unlock_user_struct(target_tv, target_tv_addr, 0);
1027

    
1028
    return 0;
1029
}
1030

    
1031
static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
1032
                                            const struct timeval *tv)
1033
{
1034
    struct target_timeval *target_tv;
1035

    
1036
    if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
1037
        return -TARGET_EFAULT;
1038

    
1039
    __put_user(tv->tv_sec, &target_tv->tv_sec);
1040
    __put_user(tv->tv_usec, &target_tv->tv_usec);
1041

    
1042
    unlock_user_struct(target_tv, target_tv_addr, 1);
1043

    
1044
    return 0;
1045
}
1046

    
1047
#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
1048
#include <mqueue.h>
1049

    
1050
static inline abi_long copy_from_user_mq_attr(struct mq_attr *attr,
1051
                                              abi_ulong target_mq_attr_addr)
1052
{
1053
    struct target_mq_attr *target_mq_attr;
1054

    
1055
    if (!lock_user_struct(VERIFY_READ, target_mq_attr,
1056
                          target_mq_attr_addr, 1))
1057
        return -TARGET_EFAULT;
1058

    
1059
    __get_user(attr->mq_flags, &target_mq_attr->mq_flags);
1060
    __get_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
1061
    __get_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
1062
    __get_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
1063

    
1064
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0);
1065

    
1066
    return 0;
1067
}
1068

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

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

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

    
1083
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1);
1084

    
1085
    return 0;
1086
}
1087
#endif
1088

    
1089
#if defined(TARGET_NR_select) || defined(TARGET_NR__newselect)
1090
/* do_select() must return target values and target errnos. */
1091
static abi_long do_select(int n,
1092
                          abi_ulong rfd_addr, abi_ulong wfd_addr,
1093
                          abi_ulong efd_addr, abi_ulong target_tv_addr)
1094
{
1095
    fd_set rfds, wfds, efds;
1096
    fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
1097
    struct timeval tv, *tv_ptr;
1098
    abi_long ret;
1099

    
1100
    ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
1101
    if (ret) {
1102
        return ret;
1103
    }
1104
    ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
1105
    if (ret) {
1106
        return ret;
1107
    }
1108
    ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
1109
    if (ret) {
1110
        return ret;
1111
    }
1112

    
1113
    if (target_tv_addr) {
1114
        if (copy_from_user_timeval(&tv, target_tv_addr))
1115
            return -TARGET_EFAULT;
1116
        tv_ptr = &tv;
1117
    } else {
1118
        tv_ptr = NULL;
1119
    }
1120

    
1121
    ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
1122

    
1123
    if (!is_error(ret)) {
1124
        if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
1125
            return -TARGET_EFAULT;
1126
        if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
1127
            return -TARGET_EFAULT;
1128
        if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
1129
            return -TARGET_EFAULT;
1130

    
1131
        if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
1132
            return -TARGET_EFAULT;
1133
    }
1134

    
1135
    return ret;
1136
}
1137
#endif
1138

    
1139
static abi_long do_pipe2(int host_pipe[], int flags)
1140
{
1141
#ifdef CONFIG_PIPE2
1142
    return pipe2(host_pipe, flags);
1143
#else
1144
    return -ENOSYS;
1145
#endif
1146
}
1147

    
1148
static abi_long do_pipe(void *cpu_env, abi_ulong pipedes,
1149
                        int flags, int is_pipe2)
1150
{
1151
    int host_pipe[2];
1152
    abi_long ret;
1153
    ret = flags ? do_pipe2(host_pipe, flags) : pipe(host_pipe);
1154

    
1155
    if (is_error(ret))
1156
        return get_errno(ret);
1157

    
1158
    /* Several targets have special calling conventions for the original
1159
       pipe syscall, but didn't replicate this into the pipe2 syscall.  */
1160
    if (!is_pipe2) {
1161
#if defined(TARGET_ALPHA)
1162
        ((CPUAlphaState *)cpu_env)->ir[IR_A4] = host_pipe[1];
1163
        return host_pipe[0];
1164
#elif defined(TARGET_MIPS)
1165
        ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1];
1166
        return host_pipe[0];
1167
#elif defined(TARGET_SH4)
1168
        ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
1169
        return host_pipe[0];
1170
#endif
1171
    }
1172

    
1173
    if (put_user_s32(host_pipe[0], pipedes)
1174
        || put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0])))
1175
        return -TARGET_EFAULT;
1176
    return get_errno(ret);
1177
}
1178

    
1179
static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn,
1180
                                              abi_ulong target_addr,
1181
                                              socklen_t len)
1182
{
1183
    struct target_ip_mreqn *target_smreqn;
1184

    
1185
    target_smreqn = lock_user(VERIFY_READ, target_addr, len, 1);
1186
    if (!target_smreqn)
1187
        return -TARGET_EFAULT;
1188
    mreqn->imr_multiaddr.s_addr = target_smreqn->imr_multiaddr.s_addr;
1189
    mreqn->imr_address.s_addr = target_smreqn->imr_address.s_addr;
1190
    if (len == sizeof(struct target_ip_mreqn))
1191
        mreqn->imr_ifindex = tswapal(target_smreqn->imr_ifindex);
1192
    unlock_user(target_smreqn, target_addr, 0);
1193

    
1194
    return 0;
1195
}
1196

    
1197
static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
1198
                                               abi_ulong target_addr,
1199
                                               socklen_t len)
1200
{
1201
    const socklen_t unix_maxlen = sizeof (struct sockaddr_un);
1202
    sa_family_t sa_family;
1203
    struct target_sockaddr *target_saddr;
1204

    
1205
    target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
1206
    if (!target_saddr)
1207
        return -TARGET_EFAULT;
1208

    
1209
    sa_family = tswap16(target_saddr->sa_family);
1210

    
1211
    /* Oops. The caller might send a incomplete sun_path; sun_path
1212
     * must be terminated by \0 (see the manual page), but
1213
     * unfortunately it is quite common to specify sockaddr_un
1214
     * length as "strlen(x->sun_path)" while it should be
1215
     * "strlen(...) + 1". We'll fix that here if needed.
1216
     * Linux kernel has a similar feature.
1217
     */
1218

    
1219
    if (sa_family == AF_UNIX) {
1220
        if (len < unix_maxlen && len > 0) {
1221
            char *cp = (char*)target_saddr;
1222

    
1223
            if ( cp[len-1] && !cp[len] )
1224
                len++;
1225
        }
1226
        if (len > unix_maxlen)
1227
            len = unix_maxlen;
1228
    }
1229

    
1230
    memcpy(addr, target_saddr, len);
1231
    addr->sa_family = sa_family;
1232
    unlock_user(target_saddr, target_addr, 0);
1233

    
1234
    return 0;
1235
}
1236

    
1237
static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
1238
                                               struct sockaddr *addr,
1239
                                               socklen_t len)
1240
{
1241
    struct target_sockaddr *target_saddr;
1242

    
1243
    target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
1244
    if (!target_saddr)
1245
        return -TARGET_EFAULT;
1246
    memcpy(target_saddr, addr, len);
1247
    target_saddr->sa_family = tswap16(addr->sa_family);
1248
    unlock_user(target_saddr, target_addr, len);
1249

    
1250
    return 0;
1251
}
1252

    
1253
/* ??? Should this also swap msgh->name?  */
1254
static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
1255
                                           struct target_msghdr *target_msgh)
1256
{
1257
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1258
    abi_long msg_controllen;
1259
    abi_ulong target_cmsg_addr;
1260
    struct target_cmsghdr *target_cmsg;
1261
    socklen_t space = 0;
1262
    
1263
    msg_controllen = tswapal(target_msgh->msg_controllen);
1264
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1265
        goto the_end;
1266
    target_cmsg_addr = tswapal(target_msgh->msg_control);
1267
    target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
1268
    if (!target_cmsg)
1269
        return -TARGET_EFAULT;
1270

    
1271
    while (cmsg && target_cmsg) {
1272
        void *data = CMSG_DATA(cmsg);
1273
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
1274

    
1275
        int len = tswapal(target_cmsg->cmsg_len)
1276
                  - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
1277

    
1278
        space += CMSG_SPACE(len);
1279
        if (space > msgh->msg_controllen) {
1280
            space -= CMSG_SPACE(len);
1281
            gemu_log("Host cmsg overflow\n");
1282
            break;
1283
        }
1284

    
1285
        cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
1286
        cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
1287
        cmsg->cmsg_len = CMSG_LEN(len);
1288

    
1289
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1290
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1291
            memcpy(data, target_data, len);
1292
        } else {
1293
            int *fd = (int *)data;
1294
            int *target_fd = (int *)target_data;
1295
            int i, numfds = len / sizeof(int);
1296

    
1297
            for (i = 0; i < numfds; i++)
1298
                fd[i] = tswap32(target_fd[i]);
1299
        }
1300

    
1301
        cmsg = CMSG_NXTHDR(msgh, cmsg);
1302
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1303
    }
1304
    unlock_user(target_cmsg, target_cmsg_addr, 0);
1305
 the_end:
1306
    msgh->msg_controllen = space;
1307
    return 0;
1308
}
1309

    
1310
/* ??? Should this also swap msgh->name?  */
1311
static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
1312
                                           struct msghdr *msgh)
1313
{
1314
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1315
    abi_long msg_controllen;
1316
    abi_ulong target_cmsg_addr;
1317
    struct target_cmsghdr *target_cmsg;
1318
    socklen_t space = 0;
1319

    
1320
    msg_controllen = tswapal(target_msgh->msg_controllen);
1321
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1322
        goto the_end;
1323
    target_cmsg_addr = tswapal(target_msgh->msg_control);
1324
    target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
1325
    if (!target_cmsg)
1326
        return -TARGET_EFAULT;
1327

    
1328
    while (cmsg && target_cmsg) {
1329
        void *data = CMSG_DATA(cmsg);
1330
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
1331

    
1332
        int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
1333

    
1334
        space += TARGET_CMSG_SPACE(len);
1335
        if (space > msg_controllen) {
1336
            space -= TARGET_CMSG_SPACE(len);
1337
            gemu_log("Target cmsg overflow\n");
1338
            break;
1339
        }
1340

    
1341
        target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
1342
        target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
1343
        target_cmsg->cmsg_len = tswapal(TARGET_CMSG_LEN(len));
1344

    
1345
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1346
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1347
            memcpy(target_data, data, len);
1348
        } else {
1349
            int *fd = (int *)data;
1350
            int *target_fd = (int *)target_data;
1351
            int i, numfds = len / sizeof(int);
1352

    
1353
            for (i = 0; i < numfds; i++)
1354
                target_fd[i] = tswap32(fd[i]);
1355
        }
1356

    
1357
        cmsg = CMSG_NXTHDR(msgh, cmsg);
1358
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1359
    }
1360
    unlock_user(target_cmsg, target_cmsg_addr, space);
1361
 the_end:
1362
    target_msgh->msg_controllen = tswapal(space);
1363
    return 0;
1364
}
1365

    
1366
/* do_setsockopt() Must return target values and target errnos. */
1367
static abi_long do_setsockopt(int sockfd, int level, int optname,
1368
                              abi_ulong optval_addr, socklen_t optlen)
1369
{
1370
    abi_long ret;
1371
    int val;
1372
    struct ip_mreqn *ip_mreq;
1373
    struct ip_mreq_source *ip_mreq_source;
1374

    
1375
    switch(level) {
1376
    case SOL_TCP:
1377
        /* TCP options all take an 'int' value.  */
1378
        if (optlen < sizeof(uint32_t))
1379
            return -TARGET_EINVAL;
1380

    
1381
        if (get_user_u32(val, optval_addr))
1382
            return -TARGET_EFAULT;
1383
        ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1384
        break;
1385
    case SOL_IP:
1386
        switch(optname) {
1387
        case IP_TOS:
1388
        case IP_TTL:
1389
        case IP_HDRINCL:
1390
        case IP_ROUTER_ALERT:
1391
        case IP_RECVOPTS:
1392
        case IP_RETOPTS:
1393
        case IP_PKTINFO:
1394
        case IP_MTU_DISCOVER:
1395
        case IP_RECVERR:
1396
        case IP_RECVTOS:
1397
#ifdef IP_FREEBIND
1398
        case IP_FREEBIND:
1399
#endif
1400
        case IP_MULTICAST_TTL:
1401
        case IP_MULTICAST_LOOP:
1402
            val = 0;
1403
            if (optlen >= sizeof(uint32_t)) {
1404
                if (get_user_u32(val, optval_addr))
1405
                    return -TARGET_EFAULT;
1406
            } else if (optlen >= 1) {
1407
                if (get_user_u8(val, optval_addr))
1408
                    return -TARGET_EFAULT;
1409
            }
1410
            ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1411
            break;
1412
        case IP_ADD_MEMBERSHIP:
1413
        case IP_DROP_MEMBERSHIP:
1414
            if (optlen < sizeof (struct target_ip_mreq) ||
1415
                optlen > sizeof (struct target_ip_mreqn))
1416
                return -TARGET_EINVAL;
1417

    
1418
            ip_mreq = (struct ip_mreqn *) alloca(optlen);
1419
            target_to_host_ip_mreq(ip_mreq, optval_addr, optlen);
1420
            ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq, optlen));
1421
            break;
1422

    
1423
        case IP_BLOCK_SOURCE:
1424
        case IP_UNBLOCK_SOURCE:
1425
        case IP_ADD_SOURCE_MEMBERSHIP:
1426
        case IP_DROP_SOURCE_MEMBERSHIP:
1427
            if (optlen != sizeof (struct target_ip_mreq_source))
1428
                return -TARGET_EINVAL;
1429

    
1430
            ip_mreq_source = lock_user(VERIFY_READ, optval_addr, optlen, 1);
1431
            ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq_source, optlen));
1432
            unlock_user (ip_mreq_source, optval_addr, 0);
1433
            break;
1434

    
1435
        default:
1436
            goto unimplemented;
1437
        }
1438
        break;
1439
    case TARGET_SOL_SOCKET:
1440
        switch (optname) {
1441
            /* Options with 'int' argument.  */
1442
        case TARGET_SO_DEBUG:
1443
                optname = SO_DEBUG;
1444
                break;
1445
        case TARGET_SO_REUSEADDR:
1446
                optname = SO_REUSEADDR;
1447
                break;
1448
        case TARGET_SO_TYPE:
1449
                optname = SO_TYPE;
1450
                break;
1451
        case TARGET_SO_ERROR:
1452
                optname = SO_ERROR;
1453
                break;
1454
        case TARGET_SO_DONTROUTE:
1455
                optname = SO_DONTROUTE;
1456
                break;
1457
        case TARGET_SO_BROADCAST:
1458
                optname = SO_BROADCAST;
1459
                break;
1460
        case TARGET_SO_SNDBUF:
1461
                optname = SO_SNDBUF;
1462
                break;
1463
        case TARGET_SO_RCVBUF:
1464
                optname = SO_RCVBUF;
1465
                break;
1466
        case TARGET_SO_KEEPALIVE:
1467
                optname = SO_KEEPALIVE;
1468
                break;
1469
        case TARGET_SO_OOBINLINE:
1470
                optname = SO_OOBINLINE;
1471
                break;
1472
        case TARGET_SO_NO_CHECK:
1473
                optname = SO_NO_CHECK;
1474
                break;
1475
        case TARGET_SO_PRIORITY:
1476
                optname = SO_PRIORITY;
1477
                break;
1478
#ifdef SO_BSDCOMPAT
1479
        case TARGET_SO_BSDCOMPAT:
1480
                optname = SO_BSDCOMPAT;
1481
                break;
1482
#endif
1483
        case TARGET_SO_PASSCRED:
1484
                optname = SO_PASSCRED;
1485
                break;
1486
        case TARGET_SO_TIMESTAMP:
1487
                optname = SO_TIMESTAMP;
1488
                break;
1489
        case TARGET_SO_RCVLOWAT:
1490
                optname = SO_RCVLOWAT;
1491
                break;
1492
        case TARGET_SO_RCVTIMEO:
1493
                optname = SO_RCVTIMEO;
1494
                break;
1495
        case TARGET_SO_SNDTIMEO:
1496
                optname = SO_SNDTIMEO;
1497
                break;
1498
            break;
1499
        default:
1500
            goto unimplemented;
1501
        }
1502
        if (optlen < sizeof(uint32_t))
1503
            return -TARGET_EINVAL;
1504

    
1505
        if (get_user_u32(val, optval_addr))
1506
            return -TARGET_EFAULT;
1507
        ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
1508
        break;
1509
    default:
1510
    unimplemented:
1511
        gemu_log("Unsupported setsockopt level=%d optname=%d\n", level, optname);
1512
        ret = -TARGET_ENOPROTOOPT;
1513
    }
1514
    return ret;
1515
}
1516

    
1517
/* do_getsockopt() Must return target values and target errnos. */
1518
static abi_long do_getsockopt(int sockfd, int level, int optname,
1519
                              abi_ulong optval_addr, abi_ulong optlen)
1520
{
1521
    abi_long ret;
1522
    int len, val;
1523
    socklen_t lv;
1524

    
1525
    switch(level) {
1526
    case TARGET_SOL_SOCKET:
1527
        level = SOL_SOCKET;
1528
        switch (optname) {
1529
        /* These don't just return a single integer */
1530
        case TARGET_SO_LINGER:
1531
        case TARGET_SO_RCVTIMEO:
1532
        case TARGET_SO_SNDTIMEO:
1533
        case TARGET_SO_PEERCRED:
1534
        case TARGET_SO_PEERNAME:
1535
            goto unimplemented;
1536
        /* Options with 'int' argument.  */
1537
        case TARGET_SO_DEBUG:
1538
            optname = SO_DEBUG;
1539
            goto int_case;
1540
        case TARGET_SO_REUSEADDR:
1541
            optname = SO_REUSEADDR;
1542
            goto int_case;
1543
        case TARGET_SO_TYPE:
1544
            optname = SO_TYPE;
1545
            goto int_case;
1546
        case TARGET_SO_ERROR:
1547
            optname = SO_ERROR;
1548
            goto int_case;
1549
        case TARGET_SO_DONTROUTE:
1550
            optname = SO_DONTROUTE;
1551
            goto int_case;
1552
        case TARGET_SO_BROADCAST:
1553
            optname = SO_BROADCAST;
1554
            goto int_case;
1555
        case TARGET_SO_SNDBUF:
1556
            optname = SO_SNDBUF;
1557
            goto int_case;
1558
        case TARGET_SO_RCVBUF:
1559
            optname = SO_RCVBUF;
1560
            goto int_case;
1561
        case TARGET_SO_KEEPALIVE:
1562
            optname = SO_KEEPALIVE;
1563
            goto int_case;
1564
        case TARGET_SO_OOBINLINE:
1565
            optname = SO_OOBINLINE;
1566
            goto int_case;
1567
        case TARGET_SO_NO_CHECK:
1568
            optname = SO_NO_CHECK;
1569
            goto int_case;
1570
        case TARGET_SO_PRIORITY:
1571
            optname = SO_PRIORITY;
1572
            goto int_case;
1573
#ifdef SO_BSDCOMPAT
1574
        case TARGET_SO_BSDCOMPAT:
1575
            optname = SO_BSDCOMPAT;
1576
            goto int_case;
1577
#endif
1578
        case TARGET_SO_PASSCRED:
1579
            optname = SO_PASSCRED;
1580
            goto int_case;
1581
        case TARGET_SO_TIMESTAMP:
1582
            optname = SO_TIMESTAMP;
1583
            goto int_case;
1584
        case TARGET_SO_RCVLOWAT:
1585
            optname = SO_RCVLOWAT;
1586
            goto int_case;
1587
        default:
1588
            goto int_case;
1589
        }
1590
        break;
1591
    case SOL_TCP:
1592
        /* TCP options all take an 'int' value.  */
1593
    int_case:
1594
        if (get_user_u32(len, optlen))
1595
            return -TARGET_EFAULT;
1596
        if (len < 0)
1597
            return -TARGET_EINVAL;
1598
        lv = sizeof(lv);
1599
        ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1600
        if (ret < 0)
1601
            return ret;
1602
        if (len > lv)
1603
            len = lv;
1604
        if (len == 4) {
1605
            if (put_user_u32(val, optval_addr))
1606
                return -TARGET_EFAULT;
1607
        } else {
1608
            if (put_user_u8(val, optval_addr))
1609
                return -TARGET_EFAULT;
1610
        }
1611
        if (put_user_u32(len, optlen))
1612
            return -TARGET_EFAULT;
1613
        break;
1614
    case SOL_IP:
1615
        switch(optname) {
1616
        case IP_TOS:
1617
        case IP_TTL:
1618
        case IP_HDRINCL:
1619
        case IP_ROUTER_ALERT:
1620
        case IP_RECVOPTS:
1621
        case IP_RETOPTS:
1622
        case IP_PKTINFO:
1623
        case IP_MTU_DISCOVER:
1624
        case IP_RECVERR:
1625
        case IP_RECVTOS:
1626
#ifdef IP_FREEBIND
1627
        case IP_FREEBIND:
1628
#endif
1629
        case IP_MULTICAST_TTL:
1630
        case IP_MULTICAST_LOOP:
1631
            if (get_user_u32(len, optlen))
1632
                return -TARGET_EFAULT;
1633
            if (len < 0)
1634
                return -TARGET_EINVAL;
1635
            lv = sizeof(lv);
1636
            ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1637
            if (ret < 0)
1638
                return ret;
1639
            if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
1640
                len = 1;
1641
                if (put_user_u32(len, optlen)
1642
                    || put_user_u8(val, optval_addr))
1643
                    return -TARGET_EFAULT;
1644
            } else {
1645
                if (len > sizeof(int))
1646
                    len = sizeof(int);
1647
                if (put_user_u32(len, optlen)
1648
                    || put_user_u32(val, optval_addr))
1649
                    return -TARGET_EFAULT;
1650
            }
1651
            break;
1652
        default:
1653
            ret = -TARGET_ENOPROTOOPT;
1654
            break;
1655
        }
1656
        break;
1657
    default:
1658
    unimplemented:
1659
        gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1660
                 level, optname);
1661
        ret = -TARGET_EOPNOTSUPP;
1662
        break;
1663
    }
1664
    return ret;
1665
}
1666

    
1667
/* FIXME
1668
 * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1669
 * other lock functions have a return code of 0 for failure.
1670
 */
1671
static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1672
                           int count, int copy)
1673
{
1674
    struct target_iovec *target_vec;
1675
    abi_ulong base;
1676
    int i;
1677

    
1678
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1679
    if (!target_vec)
1680
        return -TARGET_EFAULT;
1681
    for(i = 0;i < count; i++) {
1682
        base = tswapal(target_vec[i].iov_base);
1683
        vec[i].iov_len = tswapal(target_vec[i].iov_len);
1684
        if (vec[i].iov_len != 0) {
1685
            vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
1686
            /* Don't check lock_user return value. We must call writev even
1687
               if a element has invalid base address. */
1688
        } else {
1689
            /* zero length pointer is ignored */
1690
            vec[i].iov_base = NULL;
1691
        }
1692
    }
1693
    unlock_user (target_vec, target_addr, 0);
1694
    return 0;
1695
}
1696

    
1697
static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1698
                             int count, int copy)
1699
{
1700
    struct target_iovec *target_vec;
1701
    abi_ulong base;
1702
    int i;
1703

    
1704
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1705
    if (!target_vec)
1706
        return -TARGET_EFAULT;
1707
    for(i = 0;i < count; i++) {
1708
        if (target_vec[i].iov_base) {
1709
            base = tswapal(target_vec[i].iov_base);
1710
            unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1711
        }
1712
    }
1713
    unlock_user (target_vec, target_addr, 0);
1714

    
1715
    return 0;
1716
}
1717

    
1718
/* do_socket() Must return target values and target errnos. */
1719
static abi_long do_socket(int domain, int type, int protocol)
1720
{
1721
#if defined(TARGET_MIPS)
1722
    switch(type) {
1723
    case TARGET_SOCK_DGRAM:
1724
        type = SOCK_DGRAM;
1725
        break;
1726
    case TARGET_SOCK_STREAM:
1727
        type = SOCK_STREAM;
1728
        break;
1729
    case TARGET_SOCK_RAW:
1730
        type = SOCK_RAW;
1731
        break;
1732
    case TARGET_SOCK_RDM:
1733
        type = SOCK_RDM;
1734
        break;
1735
    case TARGET_SOCK_SEQPACKET:
1736
        type = SOCK_SEQPACKET;
1737
        break;
1738
    case TARGET_SOCK_PACKET:
1739
        type = SOCK_PACKET;
1740
        break;
1741
    }
1742
#endif
1743
    if (domain == PF_NETLINK)
1744
        return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1745
    return get_errno(socket(domain, type, protocol));
1746
}
1747

    
1748
/* do_bind() Must return target values and target errnos. */
1749
static abi_long do_bind(int sockfd, abi_ulong target_addr,
1750
                        socklen_t addrlen)
1751
{
1752
    void *addr;
1753
    abi_long ret;
1754

    
1755
    if ((int)addrlen < 0) {
1756
        return -TARGET_EINVAL;
1757
    }
1758

    
1759
    addr = alloca(addrlen+1);
1760

    
1761
    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1762
    if (ret)
1763
        return ret;
1764

    
1765
    return get_errno(bind(sockfd, addr, addrlen));
1766
}
1767

    
1768
/* do_connect() Must return target values and target errnos. */
1769
static abi_long do_connect(int sockfd, abi_ulong target_addr,
1770
                           socklen_t addrlen)
1771
{
1772
    void *addr;
1773
    abi_long ret;
1774

    
1775
    if ((int)addrlen < 0) {
1776
        return -TARGET_EINVAL;
1777
    }
1778

    
1779
    addr = alloca(addrlen);
1780

    
1781
    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1782
    if (ret)
1783
        return ret;
1784

    
1785
    return get_errno(connect(sockfd, addr, addrlen));
1786
}
1787

    
1788
/* do_sendrecvmsg() Must return target values and target errnos. */
1789
static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1790
                               int flags, int send)
1791
{
1792
    abi_long ret, len;
1793
    struct target_msghdr *msgp;
1794
    struct msghdr msg;
1795
    int count;
1796
    struct iovec *vec;
1797
    abi_ulong target_vec;
1798

    
1799
    /* FIXME */
1800
    if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1801
                          msgp,
1802
                          target_msg,
1803
                          send ? 1 : 0))
1804
        return -TARGET_EFAULT;
1805
    if (msgp->msg_name) {
1806
        msg.msg_namelen = tswap32(msgp->msg_namelen);
1807
        msg.msg_name = alloca(msg.msg_namelen);
1808
        ret = target_to_host_sockaddr(msg.msg_name, tswapal(msgp->msg_name),
1809
                                msg.msg_namelen);
1810
        if (ret) {
1811
            unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1812
            return ret;
1813
        }
1814
    } else {
1815
        msg.msg_name = NULL;
1816
        msg.msg_namelen = 0;
1817
    }
1818
    msg.msg_controllen = 2 * tswapal(msgp->msg_controllen);
1819
    msg.msg_control = alloca(msg.msg_controllen);
1820
    msg.msg_flags = tswap32(msgp->msg_flags);
1821

    
1822
    count = tswapal(msgp->msg_iovlen);
1823
    vec = alloca(count * sizeof(struct iovec));
1824
    target_vec = tswapal(msgp->msg_iov);
1825
    lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1826
    msg.msg_iovlen = count;
1827
    msg.msg_iov = vec;
1828

    
1829
    if (send) {
1830
        ret = target_to_host_cmsg(&msg, msgp);
1831
        if (ret == 0)
1832
            ret = get_errno(sendmsg(fd, &msg, flags));
1833
    } else {
1834
        ret = get_errno(recvmsg(fd, &msg, flags));
1835
        if (!is_error(ret)) {
1836
            len = ret;
1837
            ret = host_to_target_cmsg(msgp, &msg);
1838
            if (!is_error(ret))
1839
                ret = len;
1840
        }
1841
    }
1842
    unlock_iovec(vec, target_vec, count, !send);
1843
    unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1844
    return ret;
1845
}
1846

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

    
1855
    if (target_addr == 0)
1856
       return get_errno(accept(fd, NULL, NULL));
1857

    
1858
    /* linux returns EINVAL if addrlen pointer is invalid */
1859
    if (get_user_u32(addrlen, target_addrlen_addr))
1860
        return -TARGET_EINVAL;
1861

    
1862
    if ((int)addrlen < 0) {
1863
        return -TARGET_EINVAL;
1864
    }
1865

    
1866
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1867
        return -TARGET_EINVAL;
1868

    
1869
    addr = alloca(addrlen);
1870

    
1871
    ret = get_errno(accept(fd, addr, &addrlen));
1872
    if (!is_error(ret)) {
1873
        host_to_target_sockaddr(target_addr, addr, addrlen);
1874
        if (put_user_u32(addrlen, target_addrlen_addr))
1875
            ret = -TARGET_EFAULT;
1876
    }
1877
    return ret;
1878
}
1879

    
1880
/* do_getpeername() Must return target values and target errnos. */
1881
static abi_long do_getpeername(int fd, abi_ulong target_addr,
1882
                               abi_ulong target_addrlen_addr)
1883
{
1884
    socklen_t addrlen;
1885
    void *addr;
1886
    abi_long ret;
1887

    
1888
    if (get_user_u32(addrlen, target_addrlen_addr))
1889
        return -TARGET_EFAULT;
1890

    
1891
    if ((int)addrlen < 0) {
1892
        return -TARGET_EINVAL;
1893
    }
1894

    
1895
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1896
        return -TARGET_EFAULT;
1897

    
1898
    addr = alloca(addrlen);
1899

    
1900
    ret = get_errno(getpeername(fd, addr, &addrlen));
1901
    if (!is_error(ret)) {
1902
        host_to_target_sockaddr(target_addr, addr, addrlen);
1903
        if (put_user_u32(addrlen, target_addrlen_addr))
1904
            ret = -TARGET_EFAULT;
1905
    }
1906
    return ret;
1907
}
1908

    
1909
/* do_getsockname() Must return target values and target errnos. */
1910
static abi_long do_getsockname(int fd, abi_ulong target_addr,
1911
                               abi_ulong target_addrlen_addr)
1912
{
1913
    socklen_t addrlen;
1914
    void *addr;
1915
    abi_long ret;
1916

    
1917
    if (get_user_u32(addrlen, target_addrlen_addr))
1918
        return -TARGET_EFAULT;
1919

    
1920
    if ((int)addrlen < 0) {
1921
        return -TARGET_EINVAL;
1922
    }
1923

    
1924
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1925
        return -TARGET_EFAULT;
1926

    
1927
    addr = alloca(addrlen);
1928

    
1929
    ret = get_errno(getsockname(fd, addr, &addrlen));
1930
    if (!is_error(ret)) {
1931
        host_to_target_sockaddr(target_addr, addr, addrlen);
1932
        if (put_user_u32(addrlen, target_addrlen_addr))
1933
            ret = -TARGET_EFAULT;
1934
    }
1935
    return ret;
1936
}
1937

    
1938
/* do_socketpair() Must return target values and target errnos. */
1939
static abi_long do_socketpair(int domain, int type, int protocol,
1940
                              abi_ulong target_tab_addr)
1941
{
1942
    int tab[2];
1943
    abi_long ret;
1944

    
1945
    ret = get_errno(socketpair(domain, type, protocol, tab));
1946
    if (!is_error(ret)) {
1947
        if (put_user_s32(tab[0], target_tab_addr)
1948
            || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1949
            ret = -TARGET_EFAULT;
1950
    }
1951
    return ret;
1952
}
1953

    
1954
/* do_sendto() Must return target values and target errnos. */
1955
static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
1956
                          abi_ulong target_addr, socklen_t addrlen)
1957
{
1958
    void *addr;
1959
    void *host_msg;
1960
    abi_long ret;
1961

    
1962
    if ((int)addrlen < 0) {
1963
        return -TARGET_EINVAL;
1964
    }
1965

    
1966
    host_msg = lock_user(VERIFY_READ, msg, len, 1);
1967
    if (!host_msg)
1968
        return -TARGET_EFAULT;
1969
    if (target_addr) {
1970
        addr = alloca(addrlen);
1971
        ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1972
        if (ret) {
1973
            unlock_user(host_msg, msg, 0);
1974
            return ret;
1975
        }
1976
        ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
1977
    } else {
1978
        ret = get_errno(send(fd, host_msg, len, flags));
1979
    }
1980
    unlock_user(host_msg, msg, 0);
1981
    return ret;
1982
}
1983

    
1984
/* do_recvfrom() Must return target values and target errnos. */
1985
static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
1986
                            abi_ulong target_addr,
1987
                            abi_ulong target_addrlen)
1988
{
1989
    socklen_t addrlen;
1990
    void *addr;
1991
    void *host_msg;
1992
    abi_long ret;
1993

    
1994
    host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
1995
    if (!host_msg)
1996
        return -TARGET_EFAULT;
1997
    if (target_addr) {
1998
        if (get_user_u32(addrlen, target_addrlen)) {
1999
            ret = -TARGET_EFAULT;
2000
            goto fail;
2001
        }
2002
        if ((int)addrlen < 0) {
2003
            ret = -TARGET_EINVAL;
2004
            goto fail;
2005
        }
2006
        addr = alloca(addrlen);
2007
        ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
2008
    } else {
2009
        addr = NULL; /* To keep compiler quiet.  */
2010
        ret = get_errno(qemu_recv(fd, host_msg, len, flags));
2011
    }
2012
    if (!is_error(ret)) {
2013
        if (target_addr) {
2014
            host_to_target_sockaddr(target_addr, addr, addrlen);
2015
            if (put_user_u32(addrlen, target_addrlen)) {
2016
                ret = -TARGET_EFAULT;
2017
                goto fail;
2018
            }
2019
        }
2020
        unlock_user(host_msg, msg, len);
2021
    } else {
2022
fail:
2023
        unlock_user(host_msg, msg, 0);
2024
    }
2025
    return ret;
2026
}
2027

    
2028
#ifdef TARGET_NR_socketcall
2029
/* do_socketcall() Must return target values and target errnos. */
2030
static abi_long do_socketcall(int num, abi_ulong vptr)
2031
{
2032
    abi_long ret;
2033
    const int n = sizeof(abi_ulong);
2034

    
2035
    switch(num) {
2036
    case SOCKOP_socket:
2037
        {
2038
            abi_ulong domain, type, protocol;
2039

    
2040
            if (get_user_ual(domain, vptr)
2041
                || get_user_ual(type, vptr + n)
2042
                || get_user_ual(protocol, vptr + 2 * n))
2043
                return -TARGET_EFAULT;
2044

    
2045
            ret = do_socket(domain, type, protocol);
2046
        }
2047
        break;
2048
    case SOCKOP_bind:
2049
        {
2050
            abi_ulong sockfd;
2051
            abi_ulong target_addr;
2052
            socklen_t addrlen;
2053

    
2054
            if (get_user_ual(sockfd, vptr)
2055
                || get_user_ual(target_addr, vptr + n)
2056
                || get_user_ual(addrlen, vptr + 2 * n))
2057
                return -TARGET_EFAULT;
2058

    
2059
            ret = do_bind(sockfd, target_addr, addrlen);
2060
        }
2061
        break;
2062
    case SOCKOP_connect:
2063
        {
2064
            abi_ulong sockfd;
2065
            abi_ulong target_addr;
2066
            socklen_t addrlen;
2067

    
2068
            if (get_user_ual(sockfd, vptr)
2069
                || get_user_ual(target_addr, vptr + n)
2070
                || get_user_ual(addrlen, vptr + 2 * n))
2071
                return -TARGET_EFAULT;
2072

    
2073
            ret = do_connect(sockfd, target_addr, addrlen);
2074
        }
2075
        break;
2076
    case SOCKOP_listen:
2077
        {
2078
            abi_ulong sockfd, backlog;
2079

    
2080
            if (get_user_ual(sockfd, vptr)
2081
                || get_user_ual(backlog, vptr + n))
2082
                return -TARGET_EFAULT;
2083

    
2084
            ret = get_errno(listen(sockfd, backlog));
2085
        }
2086
        break;
2087
    case SOCKOP_accept:
2088
        {
2089
            abi_ulong sockfd;
2090
            abi_ulong target_addr, target_addrlen;
2091

    
2092
            if (get_user_ual(sockfd, vptr)
2093
                || get_user_ual(target_addr, vptr + n)
2094
                || get_user_ual(target_addrlen, vptr + 2 * n))
2095
                return -TARGET_EFAULT;
2096

    
2097
            ret = do_accept(sockfd, target_addr, target_addrlen);
2098
        }
2099
        break;
2100
    case SOCKOP_getsockname:
2101
        {
2102
            abi_ulong sockfd;
2103
            abi_ulong target_addr, target_addrlen;
2104

    
2105
            if (get_user_ual(sockfd, vptr)
2106
                || get_user_ual(target_addr, vptr + n)
2107
                || get_user_ual(target_addrlen, vptr + 2 * n))
2108
                return -TARGET_EFAULT;
2109

    
2110
            ret = do_getsockname(sockfd, target_addr, target_addrlen);
2111
        }
2112
        break;
2113
    case SOCKOP_getpeername:
2114
        {
2115
            abi_ulong sockfd;
2116
            abi_ulong target_addr, target_addrlen;
2117

    
2118
            if (get_user_ual(sockfd, vptr)
2119
                || get_user_ual(target_addr, vptr + n)
2120
                || get_user_ual(target_addrlen, vptr + 2 * n))
2121
                return -TARGET_EFAULT;
2122

    
2123
            ret = do_getpeername(sockfd, target_addr, target_addrlen);
2124
        }
2125
        break;
2126
    case SOCKOP_socketpair:
2127
        {
2128
            abi_ulong domain, type, protocol;
2129
            abi_ulong tab;
2130

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

    
2137
            ret = do_socketpair(domain, type, protocol, tab);
2138
        }
2139
        break;
2140
    case SOCKOP_send:
2141
        {
2142
            abi_ulong sockfd;
2143
            abi_ulong msg;
2144
            size_t len;
2145
            abi_ulong flags;
2146

    
2147
            if (get_user_ual(sockfd, vptr)
2148
                || get_user_ual(msg, vptr + n)
2149
                || get_user_ual(len, vptr + 2 * n)
2150
                || get_user_ual(flags, vptr + 3 * n))
2151
                return -TARGET_EFAULT;
2152

    
2153
            ret = do_sendto(sockfd, msg, len, flags, 0, 0);
2154
        }
2155
        break;
2156
    case SOCKOP_recv:
2157
        {
2158
            abi_ulong sockfd;
2159
            abi_ulong msg;
2160
            size_t len;
2161
            abi_ulong flags;
2162

    
2163
            if (get_user_ual(sockfd, vptr)
2164
                || get_user_ual(msg, vptr + n)
2165
                || get_user_ual(len, vptr + 2 * n)
2166
                || get_user_ual(flags, vptr + 3 * n))
2167
                return -TARGET_EFAULT;
2168

    
2169
            ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
2170
        }
2171
        break;
2172
    case SOCKOP_sendto:
2173
        {
2174
            abi_ulong sockfd;
2175
            abi_ulong msg;
2176
            size_t len;
2177
            abi_ulong flags;
2178
            abi_ulong addr;
2179
            socklen_t addrlen;
2180

    
2181
            if (get_user_ual(sockfd, vptr)
2182
                || get_user_ual(msg, vptr + n)
2183
                || get_user_ual(len, vptr + 2 * n)
2184
                || get_user_ual(flags, vptr + 3 * n)
2185
                || get_user_ual(addr, vptr + 4 * n)
2186
                || get_user_ual(addrlen, vptr + 5 * n))
2187
                return -TARGET_EFAULT;
2188

    
2189
            ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
2190
        }
2191
        break;
2192
    case SOCKOP_recvfrom:
2193
        {
2194
            abi_ulong sockfd;
2195
            abi_ulong msg;
2196
            size_t len;
2197
            abi_ulong flags;
2198
            abi_ulong addr;
2199
            socklen_t addrlen;
2200

    
2201
            if (get_user_ual(sockfd, vptr)
2202
                || get_user_ual(msg, vptr + n)
2203
                || get_user_ual(len, vptr + 2 * n)
2204
                || get_user_ual(flags, vptr + 3 * n)
2205
                || get_user_ual(addr, vptr + 4 * n)
2206
                || get_user_ual(addrlen, vptr + 5 * n))
2207
                return -TARGET_EFAULT;
2208

    
2209
            ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
2210
        }
2211
        break;
2212
    case SOCKOP_shutdown:
2213
        {
2214
            abi_ulong sockfd, how;
2215

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

    
2220
            ret = get_errno(shutdown(sockfd, how));
2221
        }
2222
        break;
2223
    case SOCKOP_sendmsg:
2224
    case SOCKOP_recvmsg:
2225
        {
2226
            abi_ulong fd;
2227
            abi_ulong target_msg;
2228
            abi_ulong flags;
2229

    
2230
            if (get_user_ual(fd, vptr)
2231
                || get_user_ual(target_msg, vptr + n)
2232
                || get_user_ual(flags, vptr + 2 * n))
2233
                return -TARGET_EFAULT;
2234

    
2235
            ret = do_sendrecvmsg(fd, target_msg, flags,
2236
                                 (num == SOCKOP_sendmsg));
2237
        }
2238
        break;
2239
    case SOCKOP_setsockopt:
2240
        {
2241
            abi_ulong sockfd;
2242
            abi_ulong level;
2243
            abi_ulong optname;
2244
            abi_ulong optval;
2245
            socklen_t optlen;
2246

    
2247
            if (get_user_ual(sockfd, vptr)
2248
                || get_user_ual(level, vptr + n)
2249
                || get_user_ual(optname, vptr + 2 * n)
2250
                || get_user_ual(optval, vptr + 3 * n)
2251
                || get_user_ual(optlen, vptr + 4 * n))
2252
                return -TARGET_EFAULT;
2253

    
2254
            ret = do_setsockopt(sockfd, level, optname, optval, optlen);
2255
        }
2256
        break;
2257
    case SOCKOP_getsockopt:
2258
        {
2259
            abi_ulong sockfd;
2260
            abi_ulong level;
2261
            abi_ulong optname;
2262
            abi_ulong optval;
2263
            socklen_t optlen;
2264

    
2265
            if (get_user_ual(sockfd, vptr)
2266
                || get_user_ual(level, vptr + n)
2267
                || get_user_ual(optname, vptr + 2 * n)
2268
                || get_user_ual(optval, vptr + 3 * n)
2269
                || get_user_ual(optlen, vptr + 4 * n))
2270
                return -TARGET_EFAULT;
2271

    
2272
            ret = do_getsockopt(sockfd, level, optname, optval, optlen);
2273
        }
2274
        break;
2275
    default:
2276
        gemu_log("Unsupported socketcall: %d\n", num);
2277
        ret = -TARGET_ENOSYS;
2278
        break;
2279
    }
2280
    return ret;
2281
}
2282
#endif
2283

    
2284
#define N_SHM_REGIONS        32
2285

    
2286
static struct shm_region {
2287
    abi_ulong        start;
2288
    abi_ulong        size;
2289
} shm_regions[N_SHM_REGIONS];
2290

    
2291
struct target_ipc_perm
2292
{
2293
    abi_long __key;
2294
    abi_ulong uid;
2295
    abi_ulong gid;
2296
    abi_ulong cuid;
2297
    abi_ulong cgid;
2298
    unsigned short int mode;
2299
    unsigned short int __pad1;
2300
    unsigned short int __seq;
2301
    unsigned short int __pad2;
2302
    abi_ulong __unused1;
2303
    abi_ulong __unused2;
2304
};
2305

    
2306
struct target_semid_ds
2307
{
2308
  struct target_ipc_perm sem_perm;
2309
  abi_ulong sem_otime;
2310
  abi_ulong __unused1;
2311
  abi_ulong sem_ctime;
2312
  abi_ulong __unused2;
2313
  abi_ulong sem_nsems;
2314
  abi_ulong __unused3;
2315
  abi_ulong __unused4;
2316
};
2317

    
2318
static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
2319
                                               abi_ulong target_addr)
2320
{
2321
    struct target_ipc_perm *target_ip;
2322
    struct target_semid_ds *target_sd;
2323

    
2324
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2325
        return -TARGET_EFAULT;
2326
    target_ip = &(target_sd->sem_perm);
2327
    host_ip->__key = tswapal(target_ip->__key);
2328
    host_ip->uid = tswapal(target_ip->uid);
2329
    host_ip->gid = tswapal(target_ip->gid);
2330
    host_ip->cuid = tswapal(target_ip->cuid);
2331
    host_ip->cgid = tswapal(target_ip->cgid);
2332
    host_ip->mode = tswap16(target_ip->mode);
2333
    unlock_user_struct(target_sd, target_addr, 0);
2334
    return 0;
2335
}
2336

    
2337
static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
2338
                                               struct ipc_perm *host_ip)
2339
{
2340
    struct target_ipc_perm *target_ip;
2341
    struct target_semid_ds *target_sd;
2342

    
2343
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2344
        return -TARGET_EFAULT;
2345
    target_ip = &(target_sd->sem_perm);
2346
    target_ip->__key = tswapal(host_ip->__key);
2347
    target_ip->uid = tswapal(host_ip->uid);
2348
    target_ip->gid = tswapal(host_ip->gid);
2349
    target_ip->cuid = tswapal(host_ip->cuid);
2350
    target_ip->cgid = tswapal(host_ip->cgid);
2351
    target_ip->mode = tswap16(host_ip->mode);
2352
    unlock_user_struct(target_sd, target_addr, 1);
2353
    return 0;
2354
}
2355

    
2356
static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
2357
                                               abi_ulong target_addr)
2358
{
2359
    struct target_semid_ds *target_sd;
2360

    
2361
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2362
        return -TARGET_EFAULT;
2363
    if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr))
2364
        return -TARGET_EFAULT;
2365
    host_sd->sem_nsems = tswapal(target_sd->sem_nsems);
2366
    host_sd->sem_otime = tswapal(target_sd->sem_otime);
2367
    host_sd->sem_ctime = tswapal(target_sd->sem_ctime);
2368
    unlock_user_struct(target_sd, target_addr, 0);
2369
    return 0;
2370
}
2371

    
2372
static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
2373
                                               struct semid_ds *host_sd)
2374
{
2375
    struct target_semid_ds *target_sd;
2376

    
2377
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2378
        return -TARGET_EFAULT;
2379
    if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
2380
        return -TARGET_EFAULT;;
2381
    target_sd->sem_nsems = tswapal(host_sd->sem_nsems);
2382
    target_sd->sem_otime = tswapal(host_sd->sem_otime);
2383
    target_sd->sem_ctime = tswapal(host_sd->sem_ctime);
2384
    unlock_user_struct(target_sd, target_addr, 1);
2385
    return 0;
2386
}
2387

    
2388
struct target_seminfo {
2389
    int semmap;
2390
    int semmni;
2391
    int semmns;
2392
    int semmnu;
2393
    int semmsl;
2394
    int semopm;
2395
    int semume;
2396
    int semusz;
2397
    int semvmx;
2398
    int semaem;
2399
};
2400

    
2401
static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
2402
                                              struct seminfo *host_seminfo)
2403
{
2404
    struct target_seminfo *target_seminfo;
2405
    if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
2406
        return -TARGET_EFAULT;
2407
    __put_user(host_seminfo->semmap, &target_seminfo->semmap);
2408
    __put_user(host_seminfo->semmni, &target_seminfo->semmni);
2409
    __put_user(host_seminfo->semmns, &target_seminfo->semmns);
2410
    __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
2411
    __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
2412
    __put_user(host_seminfo->semopm, &target_seminfo->semopm);
2413
    __put_user(host_seminfo->semume, &target_seminfo->semume);
2414
    __put_user(host_seminfo->semusz, &target_seminfo->semusz);
2415
    __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
2416
    __put_user(host_seminfo->semaem, &target_seminfo->semaem);
2417
    unlock_user_struct(target_seminfo, target_addr, 1);
2418
    return 0;
2419
}
2420

    
2421
union semun {
2422
        int val;
2423
        struct semid_ds *buf;
2424
        unsigned short *array;
2425
        struct seminfo *__buf;
2426
};
2427

    
2428
union target_semun {
2429
        int val;
2430
        abi_ulong buf;
2431
        abi_ulong array;
2432
        abi_ulong __buf;
2433
};
2434

    
2435
static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
2436
                                               abi_ulong target_addr)
2437
{
2438
    int nsems;
2439
    unsigned short *array;
2440
    union semun semun;
2441
    struct semid_ds semid_ds;
2442
    int i, ret;
2443

    
2444
    semun.buf = &semid_ds;
2445

    
2446
    ret = semctl(semid, 0, IPC_STAT, semun);
2447
    if (ret == -1)
2448
        return get_errno(ret);
2449

    
2450
    nsems = semid_ds.sem_nsems;
2451

    
2452
    *host_array = malloc(nsems*sizeof(unsigned short));
2453
    array = lock_user(VERIFY_READ, target_addr,
2454
                      nsems*sizeof(unsigned short), 1);
2455
    if (!array)
2456
        return -TARGET_EFAULT;
2457

    
2458
    for(i=0; i<nsems; i++) {
2459
        __get_user((*host_array)[i], &array[i]);
2460
    }
2461
    unlock_user(array, target_addr, 0);
2462

    
2463
    return 0;
2464
}
2465

    
2466
static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
2467
                                               unsigned short **host_array)
2468
{
2469
    int nsems;
2470
    unsigned short *array;
2471
    union semun semun;
2472
    struct semid_ds semid_ds;
2473
    int i, ret;
2474

    
2475
    semun.buf = &semid_ds;
2476

    
2477
    ret = semctl(semid, 0, IPC_STAT, semun);
2478
    if (ret == -1)
2479
        return get_errno(ret);
2480

    
2481
    nsems = semid_ds.sem_nsems;
2482

    
2483
    array = lock_user(VERIFY_WRITE, target_addr,
2484
                      nsems*sizeof(unsigned short), 0);
2485
    if (!array)
2486
        return -TARGET_EFAULT;
2487

    
2488
    for(i=0; i<nsems; i++) {
2489
        __put_user((*host_array)[i], &array[i]);
2490
    }
2491
    free(*host_array);
2492
    unlock_user(array, target_addr, 1);
2493

    
2494
    return 0;
2495
}
2496

    
2497
static inline abi_long do_semctl(int semid, int semnum, int cmd,
2498
                                 union target_semun target_su)
2499
{
2500
    union semun arg;
2501
    struct semid_ds dsarg;
2502
    unsigned short *array = NULL;
2503
    struct seminfo seminfo;
2504
    abi_long ret = -TARGET_EINVAL;
2505
    abi_long err;
2506
    cmd &= 0xff;
2507

    
2508
    switch( cmd ) {
2509
        case GETVAL:
2510
        case SETVAL:
2511
            arg.val = tswap32(target_su.val);
2512
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2513
            target_su.val = tswap32(arg.val);
2514
            break;
2515
        case GETALL:
2516
        case SETALL:
2517
            err = target_to_host_semarray(semid, &array, target_su.array);
2518
            if (err)
2519
                return err;
2520
            arg.array = array;
2521
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2522
            err = host_to_target_semarray(semid, target_su.array, &array);
2523
            if (err)
2524
                return err;
2525
            break;
2526
        case IPC_STAT:
2527
        case IPC_SET:
2528
        case SEM_STAT:
2529
            err = target_to_host_semid_ds(&dsarg, target_su.buf);
2530
            if (err)
2531
                return err;
2532
            arg.buf = &dsarg;
2533
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2534
            err = host_to_target_semid_ds(target_su.buf, &dsarg);
2535
            if (err)
2536
                return err;
2537
            break;
2538
        case IPC_INFO:
2539
        case SEM_INFO:
2540
            arg.__buf = &seminfo;
2541
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2542
            err = host_to_target_seminfo(target_su.__buf, &seminfo);
2543
            if (err)
2544
                return err;
2545
            break;
2546
        case IPC_RMID:
2547
        case GETPID:
2548
        case GETNCNT:
2549
        case GETZCNT:
2550
            ret = get_errno(semctl(semid, semnum, cmd, NULL));
2551
            break;
2552
    }
2553

    
2554
    return ret;
2555
}
2556

    
2557
struct target_sembuf {
2558
    unsigned short sem_num;
2559
    short sem_op;
2560
    short sem_flg;
2561
};
2562

    
2563
static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
2564
                                             abi_ulong target_addr,
2565
                                             unsigned nsops)
2566
{
2567
    struct target_sembuf *target_sembuf;
2568
    int i;
2569

    
2570
    target_sembuf = lock_user(VERIFY_READ, target_addr,
2571
                              nsops*sizeof(struct target_sembuf), 1);
2572
    if (!target_sembuf)
2573
        return -TARGET_EFAULT;
2574

    
2575
    for(i=0; i<nsops; i++) {
2576
        __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
2577
        __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
2578
        __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
2579
    }
2580

    
2581
    unlock_user(target_sembuf, target_addr, 0);
2582

    
2583
    return 0;
2584
}
2585

    
2586
static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
2587
{
2588
    struct sembuf sops[nsops];
2589

    
2590
    if (target_to_host_sembuf(sops, ptr, nsops))
2591
        return -TARGET_EFAULT;
2592

    
2593
    return semop(semid, sops, nsops);
2594
}
2595

    
2596
struct target_msqid_ds
2597
{
2598
    struct target_ipc_perm msg_perm;
2599
    abi_ulong msg_stime;
2600
#if TARGET_ABI_BITS == 32
2601
    abi_ulong __unused1;
2602
#endif
2603
    abi_ulong msg_rtime;
2604
#if TARGET_ABI_BITS == 32
2605
    abi_ulong __unused2;
2606
#endif
2607
    abi_ulong msg_ctime;
2608
#if TARGET_ABI_BITS == 32
2609
    abi_ulong __unused3;
2610
#endif
2611
    abi_ulong __msg_cbytes;
2612
    abi_ulong msg_qnum;
2613
    abi_ulong msg_qbytes;
2614
    abi_ulong msg_lspid;
2615
    abi_ulong msg_lrpid;
2616
    abi_ulong __unused4;
2617
    abi_ulong __unused5;
2618
};
2619

    
2620
static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
2621
                                               abi_ulong target_addr)
2622
{
2623
    struct target_msqid_ds *target_md;
2624

    
2625
    if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
2626
        return -TARGET_EFAULT;
2627
    if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
2628
        return -TARGET_EFAULT;
2629
    host_md->msg_stime = tswapal(target_md->msg_stime);
2630
    host_md->msg_rtime = tswapal(target_md->msg_rtime);
2631
    host_md->msg_ctime = tswapal(target_md->msg_ctime);
2632
    host_md->__msg_cbytes = tswapal(target_md->__msg_cbytes);
2633
    host_md->msg_qnum = tswapal(target_md->msg_qnum);
2634
    host_md->msg_qbytes = tswapal(target_md->msg_qbytes);
2635
    host_md->msg_lspid = tswapal(target_md->msg_lspid);
2636
    host_md->msg_lrpid = tswapal(target_md->msg_lrpid);
2637
    unlock_user_struct(target_md, target_addr, 0);
2638
    return 0;
2639
}
2640

    
2641
static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
2642
                                               struct msqid_ds *host_md)
2643
{
2644
    struct target_msqid_ds *target_md;
2645

    
2646
    if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
2647
        return -TARGET_EFAULT;
2648
    if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
2649
        return -TARGET_EFAULT;
2650
    target_md->msg_stime = tswapal(host_md->msg_stime);
2651
    target_md->msg_rtime = tswapal(host_md->msg_rtime);
2652
    target_md->msg_ctime = tswapal(host_md->msg_ctime);
2653
    target_md->__msg_cbytes = tswapal(host_md->__msg_cbytes);
2654
    target_md->msg_qnum = tswapal(host_md->msg_qnum);
2655
    target_md->msg_qbytes = tswapal(host_md->msg_qbytes);
2656
    target_md->msg_lspid = tswapal(host_md->msg_lspid);
2657
    target_md->msg_lrpid = tswapal(host_md->msg_lrpid);
2658
    unlock_user_struct(target_md, target_addr, 1);
2659
    return 0;
2660
}
2661

    
2662
struct target_msginfo {
2663
    int msgpool;
2664
    int msgmap;
2665
    int msgmax;
2666
    int msgmnb;
2667
    int msgmni;
2668
    int msgssz;
2669
    int msgtql;
2670
    unsigned short int msgseg;
2671
};
2672

    
2673
static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
2674
                                              struct msginfo *host_msginfo)
2675
{
2676
    struct target_msginfo *target_msginfo;
2677
    if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
2678
        return -TARGET_EFAULT;
2679
    __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
2680
    __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
2681
    __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
2682
    __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
2683
    __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
2684
    __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
2685
    __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
2686
    __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
2687
    unlock_user_struct(target_msginfo, target_addr, 1);
2688
    return 0;
2689
}
2690

    
2691
static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
2692
{
2693
    struct msqid_ds dsarg;
2694
    struct msginfo msginfo;
2695
    abi_long ret = -TARGET_EINVAL;
2696

    
2697
    cmd &= 0xff;
2698

    
2699
    switch (cmd) {
2700
    case IPC_STAT:
2701
    case IPC_SET:
2702
    case MSG_STAT:
2703
        if (target_to_host_msqid_ds(&dsarg,ptr))
2704
            return -TARGET_EFAULT;
2705
        ret = get_errno(msgctl(msgid, cmd, &dsarg));
2706
        if (host_to_target_msqid_ds(ptr,&dsarg))
2707
            return -TARGET_EFAULT;
2708
        break;
2709
    case IPC_RMID:
2710
        ret = get_errno(msgctl(msgid, cmd, NULL));
2711
        break;
2712
    case IPC_INFO:
2713
    case MSG_INFO:
2714
        ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
2715
        if (host_to_target_msginfo(ptr, &msginfo))
2716
            return -TARGET_EFAULT;
2717
        break;
2718
    }
2719

    
2720
    return ret;
2721
}
2722

    
2723
struct target_msgbuf {
2724
    abi_long mtype;
2725
    char        mtext[1];
2726
};
2727

    
2728
static inline abi_long do_msgsnd(int msqid, abi_long msgp,
2729
                                 unsigned int msgsz, int msgflg)
2730
{
2731
    struct target_msgbuf *target_mb;
2732
    struct msgbuf *host_mb;
2733
    abi_long ret = 0;
2734

    
2735
    if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
2736
        return -TARGET_EFAULT;
2737
    host_mb = malloc(msgsz+sizeof(long));
2738
    host_mb->mtype = (abi_long) tswapal(target_mb->mtype);
2739
    memcpy(host_mb->mtext, target_mb->mtext, msgsz);
2740
    ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
2741
    free(host_mb);
2742
    unlock_user_struct(target_mb, msgp, 0);
2743

    
2744
    return ret;
2745
}
2746

    
2747
static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2748
                                 unsigned int msgsz, abi_long msgtyp,
2749
                                 int msgflg)
2750
{
2751
    struct target_msgbuf *target_mb;
2752
    char *target_mtext;
2753
    struct msgbuf *host_mb;
2754
    abi_long ret = 0;
2755

    
2756
    if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2757
        return -TARGET_EFAULT;
2758

    
2759
    host_mb = malloc(msgsz+sizeof(long));
2760
    ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapal(msgtyp), msgflg));
2761

    
2762
    if (ret > 0) {
2763
        abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2764
        target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2765
        if (!target_mtext) {
2766
            ret = -TARGET_EFAULT;
2767
            goto end;
2768
        }
2769
        memcpy(target_mb->mtext, host_mb->mtext, ret);
2770
        unlock_user(target_mtext, target_mtext_addr, ret);
2771
    }
2772

    
2773
    target_mb->mtype = tswapal(host_mb->mtype);
2774
    free(host_mb);
2775

    
2776
end:
2777
    if (target_mb)
2778
        unlock_user_struct(target_mb, msgp, 1);
2779
    return ret;
2780
}
2781

    
2782
struct target_shmid_ds
2783
{
2784
    struct target_ipc_perm shm_perm;
2785
    abi_ulong shm_segsz;
2786
    abi_ulong shm_atime;
2787
#if TARGET_ABI_BITS == 32
2788
    abi_ulong __unused1;
2789
#endif
2790
    abi_ulong shm_dtime;
2791
#if TARGET_ABI_BITS == 32
2792
    abi_ulong __unused2;
2793
#endif
2794
    abi_ulong shm_ctime;
2795
#if TARGET_ABI_BITS == 32
2796
    abi_ulong __unused3;
2797
#endif
2798
    int shm_cpid;
2799
    int shm_lpid;
2800
    abi_ulong shm_nattch;
2801
    unsigned long int __unused4;
2802
    unsigned long int __unused5;
2803
};
2804

    
2805
static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
2806
                                               abi_ulong target_addr)
2807
{
2808
    struct target_shmid_ds *target_sd;
2809

    
2810
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2811
        return -TARGET_EFAULT;
2812
    if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr))
2813
        return -TARGET_EFAULT;
2814
    __get_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2815
    __get_user(host_sd->shm_atime, &target_sd->shm_atime);
2816
    __get_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2817
    __get_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2818
    __get_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2819
    __get_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2820
    __get_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2821
    unlock_user_struct(target_sd, target_addr, 0);
2822
    return 0;
2823
}
2824

    
2825
static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
2826
                                               struct shmid_ds *host_sd)
2827
{
2828
    struct target_shmid_ds *target_sd;
2829

    
2830
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2831
        return -TARGET_EFAULT;
2832
    if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm)))
2833
        return -TARGET_EFAULT;
2834
    __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2835
    __put_user(host_sd->shm_atime, &target_sd->shm_atime);
2836
    __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2837
    __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2838
    __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2839
    __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2840
    __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2841
    unlock_user_struct(target_sd, target_addr, 1);
2842
    return 0;
2843
}
2844

    
2845
struct  target_shminfo {
2846
    abi_ulong shmmax;
2847
    abi_ulong shmmin;
2848
    abi_ulong shmmni;
2849
    abi_ulong shmseg;
2850
    abi_ulong shmall;
2851
};
2852

    
2853
static inline abi_long host_to_target_shminfo(abi_ulong target_addr,
2854
                                              struct shminfo *host_shminfo)
2855
{
2856
    struct target_shminfo *target_shminfo;
2857
    if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0))
2858
        return -TARGET_EFAULT;
2859
    __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
2860
    __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
2861
    __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
2862
    __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
2863
    __put_user(host_shminfo->shmall, &target_shminfo->shmall);
2864
    unlock_user_struct(target_shminfo, target_addr, 1);
2865
    return 0;
2866
}
2867

    
2868
struct target_shm_info {
2869
    int used_ids;
2870
    abi_ulong shm_tot;
2871
    abi_ulong shm_rss;
2872
    abi_ulong shm_swp;
2873
    abi_ulong swap_attempts;
2874
    abi_ulong swap_successes;
2875
};
2876

    
2877
static inline abi_long host_to_target_shm_info(abi_ulong target_addr,
2878
                                               struct shm_info *host_shm_info)
2879
{
2880
    struct target_shm_info *target_shm_info;
2881
    if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0))
2882
        return -TARGET_EFAULT;
2883
    __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
2884
    __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
2885
    __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
2886
    __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
2887
    __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts);
2888
    __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes);
2889
    unlock_user_struct(target_shm_info, target_addr, 1);
2890
    return 0;
2891
}
2892

    
2893
static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
2894
{
2895
    struct shmid_ds dsarg;
2896
    struct shminfo shminfo;
2897
    struct shm_info shm_info;
2898
    abi_long ret = -TARGET_EINVAL;
2899

    
2900
    cmd &= 0xff;
2901

    
2902
    switch(cmd) {
2903
    case IPC_STAT:
2904
    case IPC_SET:
2905
    case SHM_STAT:
2906
        if (target_to_host_shmid_ds(&dsarg, buf))
2907
            return -TARGET_EFAULT;
2908
        ret = get_errno(shmctl(shmid, cmd, &dsarg));
2909
        if (host_to_target_shmid_ds(buf, &dsarg))
2910
            return -TARGET_EFAULT;
2911
        break;
2912
    case IPC_INFO:
2913
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
2914
        if (host_to_target_shminfo(buf, &shminfo))
2915
            return -TARGET_EFAULT;
2916
        break;
2917
    case SHM_INFO:
2918
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
2919
        if (host_to_target_shm_info(buf, &shm_info))
2920
            return -TARGET_EFAULT;
2921
        break;
2922
    case IPC_RMID:
2923
    case SHM_LOCK:
2924
    case SHM_UNLOCK:
2925
        ret = get_errno(shmctl(shmid, cmd, NULL));
2926
        break;
2927
    }
2928

    
2929
    return ret;
2930
}
2931

    
2932
static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
2933
{
2934
    abi_long raddr;
2935
    void *host_raddr;
2936
    struct shmid_ds shm_info;
2937
    int i,ret;
2938

    
2939
    /* find out the length of the shared memory segment */
2940
    ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
2941
    if (is_error(ret)) {
2942
        /* can't get length, bail out */
2943
        return ret;
2944
    }
2945

    
2946
    mmap_lock();
2947

    
2948
    if (shmaddr)
2949
        host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
2950
    else {
2951
        abi_ulong mmap_start;
2952

    
2953
        mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
2954

    
2955
        if (mmap_start == -1) {
2956
            errno = ENOMEM;
2957
            host_raddr = (void *)-1;
2958
        } else
2959
            host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);
2960
    }
2961

    
2962
    if (host_raddr == (void *)-1) {
2963
        mmap_unlock();
2964
        return get_errno((long)host_raddr);
2965
    }
2966
    raddr=h2g((unsigned long)host_raddr);
2967

    
2968
    page_set_flags(raddr, raddr + shm_info.shm_segsz,
2969
                   PAGE_VALID | PAGE_READ |
2970
                   ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
2971

    
2972
    for (i = 0; i < N_SHM_REGIONS; i++) {
2973
        if (shm_regions[i].start == 0) {
2974
            shm_regions[i].start = raddr;
2975
            shm_regions[i].size = shm_info.shm_segsz;
2976
            break;
2977
        }
2978
    }
2979

    
2980
    mmap_unlock();
2981
    return raddr;
2982

    
2983
}
2984

    
2985
static inline abi_long do_shmdt(abi_ulong shmaddr)
2986
{
2987
    int i;
2988

    
2989
    for (i = 0; i < N_SHM_REGIONS; ++i) {
2990
        if (shm_regions[i].start == shmaddr) {
2991
            shm_regions[i].start = 0;
2992
            page_set_flags(shmaddr, shmaddr + shm_regions[i].size, 0);
2993
            break;
2994
        }
2995
    }
2996

    
2997
    return get_errno(shmdt(g2h(shmaddr)));
2998
}
2999

    
3000
#ifdef TARGET_NR_ipc
3001
/* ??? This only works with linear mappings.  */
3002
/* do_ipc() must return target values and target errnos. */
3003
static abi_long do_ipc(unsigned int call, int first,
3004
                       int second, int third,
3005
                       abi_long ptr, abi_long fifth)
3006
{
3007
    int version;
3008
    abi_long ret = 0;
3009

    
3010
    version = call >> 16;
3011
    call &= 0xffff;
3012

    
3013
    switch (call) {
3014
    case IPCOP_semop:
3015
        ret = do_semop(first, ptr, second);
3016
        break;
3017

    
3018
    case IPCOP_semget:
3019
        ret = get_errno(semget(first, second, third));
3020
        break;
3021

    
3022
    case IPCOP_semctl:
3023
        ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr);
3024
        break;
3025

    
3026
    case IPCOP_msgget:
3027
        ret = get_errno(msgget(first, second));
3028
        break;
3029

    
3030
    case IPCOP_msgsnd:
3031
        ret = do_msgsnd(first, ptr, second, third);
3032
        break;
3033

    
3034
    case IPCOP_msgctl:
3035
        ret = do_msgctl(first, second, ptr);
3036
        break;
3037

    
3038
    case IPCOP_msgrcv:
3039
        switch (version) {
3040
        case 0:
3041
            {
3042
                struct target_ipc_kludge {
3043
                    abi_long msgp;
3044
                    abi_long msgtyp;
3045
                } *tmp;
3046

    
3047
                if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
3048
                    ret = -TARGET_EFAULT;
3049
                    break;
3050
                }
3051

    
3052
                ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
3053

    
3054
                unlock_user_struct(tmp, ptr, 0);
3055
                break;
3056
            }
3057
        default:
3058
            ret = do_msgrcv(first, ptr, second, fifth, third);
3059
        }
3060
        break;
3061

    
3062
    case IPCOP_shmat:
3063
        switch (version) {
3064
        default:
3065
        {
3066
            abi_ulong raddr;
3067
            raddr = do_shmat(first, ptr, second);
3068
            if (is_error(raddr))
3069
                return get_errno(raddr);
3070
            if (put_user_ual(raddr, third))
3071
                return -TARGET_EFAULT;
3072
            break;
3073
        }
3074
        case 1:
3075
            ret = -TARGET_EINVAL;
3076
            break;
3077
        }
3078
        break;
3079
    case IPCOP_shmdt:
3080
        ret = do_shmdt(ptr);
3081
        break;
3082

    
3083
    case IPCOP_shmget:
3084
        /* IPC_* flag values are the same on all linux platforms */
3085
        ret = get_errno(shmget(first, second, third));
3086
        break;
3087

    
3088
        /* IPC_* and SHM_* command values are the same on all linux platforms */
3089
    case IPCOP_shmctl:
3090
        ret = do_shmctl(first, second, third);
3091
        break;
3092
    default:
3093
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
3094
        ret = -TARGET_ENOSYS;
3095
        break;
3096
    }
3097
    return ret;
3098
}
3099
#endif
3100

    
3101
/* kernel structure types definitions */
3102

    
3103
#define STRUCT(name, ...) STRUCT_ ## name,
3104
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
3105
enum {
3106
#include "syscall_types.h"
3107
};
3108
#undef STRUCT
3109
#undef STRUCT_SPECIAL
3110

    
3111
#define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = {  __VA_ARGS__, TYPE_NULL };
3112
#define STRUCT_SPECIAL(name)
3113
#include "syscall_types.h"
3114
#undef STRUCT
3115
#undef STRUCT_SPECIAL
3116

    
3117
typedef struct IOCTLEntry IOCTLEntry;
3118

    
3119
typedef abi_long do_ioctl_fn(const IOCTLEntry *ie, uint8_t *buf_temp,
3120
                             int fd, abi_long cmd, abi_long arg);
3121

    
3122
struct IOCTLEntry {
3123
    unsigned int target_cmd;
3124
    unsigned int host_cmd;
3125
    const char *name;
3126
    int access;
3127
    do_ioctl_fn *do_ioctl;
3128
    const argtype arg_type[5];
3129
};
3130

    
3131
#define IOC_R 0x0001
3132
#define IOC_W 0x0002
3133
#define IOC_RW (IOC_R | IOC_W)
3134

    
3135
#define MAX_STRUCT_SIZE 4096
3136

    
3137
#ifdef CONFIG_FIEMAP
3138
/* So fiemap access checks don't overflow on 32 bit systems.
3139
 * This is very slightly smaller than the limit imposed by
3140
 * the underlying kernel.
3141
 */
3142
#define FIEMAP_MAX_EXTENTS ((UINT_MAX - sizeof(struct fiemap))  \
3143
                            / sizeof(struct fiemap_extent))
3144

    
3145
static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp,
3146
                                       int fd, abi_long cmd, abi_long arg)
3147
{
3148
    /* The parameter for this ioctl is a struct fiemap followed
3149
     * by an array of struct fiemap_extent whose size is set
3150
     * in fiemap->fm_extent_count. The array is filled in by the
3151
     * ioctl.
3152
     */
3153
    int target_size_in, target_size_out;
3154
    struct fiemap *fm;
3155
    const argtype *arg_type = ie->arg_type;
3156
    const argtype extent_arg_type[] = { MK_STRUCT(STRUCT_fiemap_extent) };
3157
    void *argptr, *p;
3158
    abi_long ret;
3159
    int i, extent_size = thunk_type_size(extent_arg_type, 0);
3160
    uint32_t outbufsz;
3161
    int free_fm = 0;
3162

    
3163
    assert(arg_type[0] == TYPE_PTR);
3164
    assert(ie->access == IOC_RW);
3165
    arg_type++;
3166
    target_size_in = thunk_type_size(arg_type, 0);
3167
    argptr = lock_user(VERIFY_READ, arg, target_size_in, 1);
3168
    if (!argptr) {
3169
        return -TARGET_EFAULT;
3170
    }
3171
    thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3172
    unlock_user(argptr, arg, 0);
3173
    fm = (struct fiemap *)buf_temp;
3174
    if (fm->fm_extent_count > FIEMAP_MAX_EXTENTS) {
3175
        return -TARGET_EINVAL;
3176
    }
3177

    
3178
    outbufsz = sizeof (*fm) +
3179
        (sizeof(struct fiemap_extent) * fm->fm_extent_count);
3180

    
3181
    if (outbufsz > MAX_STRUCT_SIZE) {
3182
        /* We can't fit all the extents into the fixed size buffer.
3183
         * Allocate one that is large enough and use it instead.
3184
         */
3185
        fm = malloc(outbufsz);
3186
        if (!fm) {
3187
            return -TARGET_ENOMEM;
3188
        }
3189
        memcpy(fm, buf_temp, sizeof(struct fiemap));
3190
        free_fm = 1;
3191
    }
3192
    ret = get_errno(ioctl(fd, ie->host_cmd, fm));
3193
    if (!is_error(ret)) {
3194
        target_size_out = target_size_in;
3195
        /* An extent_count of 0 means we were only counting the extents
3196
         * so there are no structs to copy
3197
         */
3198
        if (fm->fm_extent_count != 0) {
3199
            target_size_out += fm->fm_mapped_extents * extent_size;
3200
        }
3201
        argptr = lock_user(VERIFY_WRITE, arg, target_size_out, 0);
3202
        if (!argptr) {
3203
            ret = -TARGET_EFAULT;
3204
        } else {
3205
            /* Convert the struct fiemap */
3206
            thunk_convert(argptr, fm, arg_type, THUNK_TARGET);
3207
            if (fm->fm_extent_count != 0) {
3208
                p = argptr + target_size_in;
3209
                /* ...and then all the struct fiemap_extents */
3210
                for (i = 0; i < fm->fm_mapped_extents; i++) {
3211
                    thunk_convert(p, &fm->fm_extents[i], extent_arg_type,
3212
                                  THUNK_TARGET);
3213
                    p += extent_size;
3214
                }
3215
            }
3216
            unlock_user(argptr, arg, target_size_out);
3217
        }
3218
    }
3219
    if (free_fm) {
3220
        free(fm);
3221
    }
3222
    return ret;
3223
}
3224
#endif
3225

    
3226
static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp,
3227
                                int fd, abi_long cmd, abi_long arg)
3228
{
3229
    const argtype *arg_type = ie->arg_type;
3230
    int target_size;
3231
    void *argptr;
3232
    int ret;
3233
    struct ifconf *host_ifconf;
3234
    uint32_t outbufsz;
3235
    const argtype ifreq_arg_type[] = { MK_STRUCT(STRUCT_sockaddr_ifreq) };
3236
    int target_ifreq_size;
3237
    int nb_ifreq;
3238
    int free_buf = 0;
3239
    int i;
3240
    int target_ifc_len;
3241
    abi_long target_ifc_buf;
3242
    int host_ifc_len;
3243
    char *host_ifc_buf;
3244

    
3245
    assert(arg_type[0] == TYPE_PTR);
3246
    assert(ie->access == IOC_RW);
3247

    
3248
    arg_type++;
3249
    target_size = thunk_type_size(arg_type, 0);
3250

    
3251
    argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3252
    if (!argptr)
3253
        return -TARGET_EFAULT;
3254
    thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3255
    unlock_user(argptr, arg, 0);
3256

    
3257
    host_ifconf = (struct ifconf *)(unsigned long)buf_temp;
3258
    target_ifc_len = host_ifconf->ifc_len;
3259
    target_ifc_buf = (abi_long)(unsigned long)host_ifconf->ifc_buf;
3260

    
3261
    target_ifreq_size = thunk_type_size(ifreq_arg_type, 0);
3262
    nb_ifreq = target_ifc_len / target_ifreq_size;
3263
    host_ifc_len = nb_ifreq * sizeof(struct ifreq);
3264

    
3265
    outbufsz = sizeof(*host_ifconf) + host_ifc_len;
3266
    if (outbufsz > MAX_STRUCT_SIZE) {
3267
        /* We can't fit all the extents into the fixed size buffer.
3268
         * Allocate one that is large enough and use it instead.
3269
         */
3270
        host_ifconf = malloc(outbufsz);
3271
        if (!host_ifconf) {
3272
            return -TARGET_ENOMEM;
3273
        }
3274
        memcpy(host_ifconf, buf_temp, sizeof(*host_ifconf));
3275
        free_buf = 1;
3276
    }
3277
    host_ifc_buf = (char*)host_ifconf + sizeof(*host_ifconf);
3278

    
3279
    host_ifconf->ifc_len = host_ifc_len;
3280
    host_ifconf->ifc_buf = host_ifc_buf;
3281

    
3282
    ret = get_errno(ioctl(fd, ie->host_cmd, host_ifconf));
3283
    if (!is_error(ret)) {
3284
        /* convert host ifc_len to target ifc_len */
3285

    
3286
        nb_ifreq = host_ifconf->ifc_len / sizeof(struct ifreq);
3287
        target_ifc_len = nb_ifreq * target_ifreq_size;
3288
        host_ifconf->ifc_len = target_ifc_len;
3289

    
3290
        /* restore target ifc_buf */
3291

    
3292
        host_ifconf->ifc_buf = (char *)(unsigned long)target_ifc_buf;
3293

    
3294
        /* copy struct ifconf to target user */
3295

    
3296
        argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3297
        if (!argptr)
3298
            return -TARGET_EFAULT;
3299
        thunk_convert(argptr, host_ifconf, arg_type, THUNK_TARGET);
3300
        unlock_user(argptr, arg, target_size);
3301

    
3302
        /* copy ifreq[] to target user */
3303

    
3304
        argptr = lock_user(VERIFY_WRITE, target_ifc_buf, target_ifc_len, 0);
3305
        for (i = 0; i < nb_ifreq ; i++) {
3306
            thunk_convert(argptr + i * target_ifreq_size,
3307
                          host_ifc_buf + i * sizeof(struct ifreq),
3308
                          ifreq_arg_type, THUNK_TARGET);
3309
        }
3310
        unlock_user(argptr, target_ifc_buf, target_ifc_len);
3311
    }
3312

    
3313
    if (free_buf) {
3314
        free(host_ifconf);
3315
    }
3316

    
3317
    return ret;
3318
}
3319

    
3320
static IOCTLEntry ioctl_entries[] = {
3321
#define IOCTL(cmd, access, ...) \
3322
    { TARGET_ ## cmd, cmd, #cmd, access, 0, {  __VA_ARGS__ } },
3323
#define IOCTL_SPECIAL(cmd, access, dofn, ...)                      \
3324
    { TARGET_ ## cmd, cmd, #cmd, access, dofn, {  __VA_ARGS__ } },
3325
#include "ioctls.h"
3326
    { 0, 0, },
3327
};
3328

    
3329
/* ??? Implement proper locking for ioctls.  */
3330
/* do_ioctl() Must return target values and target errnos. */
3331
static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
3332
{
3333
    const IOCTLEntry *ie;
3334
    const argtype *arg_type;
3335
    abi_long ret;
3336
    uint8_t buf_temp[MAX_STRUCT_SIZE];
3337
    int target_size;
3338
    void *argptr;
3339

    
3340
    ie = ioctl_entries;
3341
    for(;;) {
3342
        if (ie->target_cmd == 0) {
3343
            gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
3344
            return -TARGET_ENOSYS;
3345
        }
3346
        if (ie->target_cmd == cmd)
3347
            break;
3348
        ie++;
3349
    }
3350
    arg_type = ie->arg_type;
3351
#if defined(DEBUG)
3352
    gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
3353
#endif
3354
    if (ie->do_ioctl) {
3355
        return ie->do_ioctl(ie, buf_temp, fd, cmd, arg);
3356
    }
3357

    
3358
    switch(arg_type[0]) {
3359
    case TYPE_NULL:
3360
        /* no argument */
3361
        ret = get_errno(ioctl(fd, ie->host_cmd));
3362
        break;
3363
    case TYPE_PTRVOID:
3364
    case TYPE_INT:
3365
        /* int argment */
3366
        ret = get_errno(ioctl(fd, ie->host_cmd, arg));
3367
        break;
3368
    case TYPE_PTR:
3369
        arg_type++;
3370
        target_size = thunk_type_size(arg_type, 0);
3371
        switch(ie->access) {
3372
        case IOC_R:
3373
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3374
            if (!is_error(ret)) {
3375
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3376
                if (!argptr)
3377
                    return -TARGET_EFAULT;
3378
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
3379
                unlock_user(argptr, arg, target_size);
3380
            }
3381
            break;
3382
        case IOC_W:
3383
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3384
            if (!argptr)
3385
                return -TARGET_EFAULT;
3386
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3387
            unlock_user(argptr, arg, 0);
3388
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3389
            break;
3390
        default:
3391
        case IOC_RW:
3392
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3393
            if (!argptr)
3394
                return -TARGET_EFAULT;
3395
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3396
            unlock_user(argptr, arg, 0);
3397
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3398
            if (!is_error(ret)) {
3399
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3400
                if (!argptr)
3401
                    return -TARGET_EFAULT;
3402
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
3403
                unlock_user(argptr, arg, target_size);
3404
            }
3405
            break;
3406
        }
3407
        break;
3408
    default:
3409
        gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
3410
                 (long)cmd, arg_type[0]);
3411
        ret = -TARGET_ENOSYS;
3412
        break;
3413
    }
3414
    return ret;
3415
}
3416

    
3417
static const bitmask_transtbl iflag_tbl[] = {
3418
        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
3419
        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
3420
        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
3421
        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
3422
        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
3423
        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
3424
        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
3425
        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
3426
        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
3427
        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
3428
        { TARGET_IXON, TARGET_IXON, IXON, IXON },
3429
        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
3430
        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
3431
        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
3432
        { 0, 0, 0, 0 }
3433
};
3434

    
3435
static const bitmask_transtbl oflag_tbl[] = {
3436
        { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
3437
        { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
3438
        { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
3439
        { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
3440
        { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
3441
        { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
3442
        { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
3443
        { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
3444
        { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
3445
        { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
3446
        { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
3447
        { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
3448
        { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
3449
        { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
3450
        { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
3451
        { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
3452
        { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
3453
        { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
3454
        { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
3455
        { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
3456
        { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
3457
        { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
3458
        { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
3459
        { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
3460
        { 0, 0, 0, 0 }
3461
};
3462

    
3463
static const bitmask_transtbl cflag_tbl[] = {
3464
        { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
3465
        { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
3466
        { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
3467
        { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
3468
        { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
3469
        { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
3470
        { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
3471
        { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
3472
        { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
3473
        { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
3474
        { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
3475
        { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
3476
        { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
3477
        { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
3478
        { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
3479
        { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
3480
        { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
3481
        { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
3482
        { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
3483
        { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
3484
        { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
3485
        { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
3486
        { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
3487
        { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
3488
        { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
3489
        { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
3490
        { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
3491
        { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
3492
        { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
3493
        { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
3494
        { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
3495
        { 0, 0, 0, 0 }
3496
};
3497

    
3498
static const bitmask_transtbl lflag_tbl[] = {
3499
        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
3500
        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
3501
        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
3502
        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
3503
        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
3504
        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
3505
        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
3506
        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
3507
        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
3508
        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
3509
        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
3510
        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
3511
        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
3512
        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
3513
        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
3514
        { 0, 0, 0, 0 }
3515
};
3516

    
3517
static void target_to_host_termios (void *dst, const void *src)
3518
{
3519
    struct host_termios *host = dst;
3520
    const struct target_termios *target = src;
3521

    
3522
    host->c_iflag =
3523
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
3524
    host->c_oflag =
3525
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
3526
    host->c_cflag =
3527
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
3528
    host->c_lflag =
3529
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
3530
    host->c_line = target->c_line;
3531

    
3532
    memset(host->c_cc, 0, sizeof(host->c_cc));
3533
    host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
3534
    host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
3535
    host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
3536
    host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
3537
    host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
3538
    host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
3539
    host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
3540
    host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
3541
    host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
3542
    host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
3543
    host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
3544
    host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
3545
    host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
3546
    host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
3547
    host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
3548
    host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
3549
    host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
3550
}
3551

    
3552
static void host_to_target_termios (void *dst, const void *src)
3553
{
3554
    struct target_termios *target = dst;
3555
    const struct host_termios *host = src;
3556

    
3557
    target->c_iflag =
3558
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
3559
    target->c_oflag =
3560
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
3561
    target->c_cflag =
3562
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
3563
    target->c_lflag =
3564
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
3565
    target->c_line = host->c_line;
3566

    
3567
    memset(target->c_cc, 0, sizeof(target->c_cc));
3568
    target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
3569
    target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
3570
    target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
3571
    target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
3572
    target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
3573
    target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
3574
    target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
3575
    target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
3576
    target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
3577
    target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
3578
    target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
3579
    target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
3580
    target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
3581
    target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
3582
    target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
3583
    target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
3584
    target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
3585
}
3586

    
3587
static const StructEntry struct_termios_def = {
3588
    .convert = { host_to_target_termios, target_to_host_termios },
3589
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
3590
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
3591
};
3592

    
3593
static bitmask_transtbl mmap_flags_tbl[] = {
3594
        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
3595
        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
3596
        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
3597
        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
3598
        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
3599
        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
3600
        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
3601
        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
3602
        { 0, 0, 0, 0 }
3603
};
3604

    
3605
#if defined(TARGET_I386)
3606

    
3607
/* NOTE: there is really one LDT for all the threads */
3608
static uint8_t *ldt_table;
3609

    
3610
static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
3611
{
3612
    int size;
3613
    void *p;
3614

    
3615
    if (!ldt_table)
3616
        return 0;
3617
    size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
3618
    if (size > bytecount)
3619
        size = bytecount;
3620
    p = lock_user(VERIFY_WRITE, ptr, size, 0);
3621
    if (!p)
3622
        return -TARGET_EFAULT;
3623
    /* ??? Should this by byteswapped?  */
3624
    memcpy(p, ldt_table, size);
3625
    unlock_user(p, ptr, size);
3626
    return size;
3627
}
3628

    
3629
/* XXX: add locking support */
3630
static abi_long write_ldt(CPUX86State *env,
3631
                          abi_ulong ptr, unsigned long bytecount, int oldmode)
3632
{
3633
    struct target_modify_ldt_ldt_s ldt_info;
3634
    struct target_modify_ldt_ldt_s *target_ldt_info;
3635
    int seg_32bit, contents, read_exec_only, limit_in_pages;
3636
    int seg_not_present, useable, lm;
3637
    uint32_t *lp, entry_1, entry_2;
3638

    
3639
    if (bytecount != sizeof(ldt_info))
3640
        return -TARGET_EINVAL;
3641
    if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
3642
        return -TARGET_EFAULT;
3643
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3644
    ldt_info.base_addr = tswapal(target_ldt_info->base_addr);
3645
    ldt_info.limit = tswap32(target_ldt_info->limit);
3646
    ldt_info.flags = tswap32(target_ldt_info->flags);
3647
    unlock_user_struct(target_ldt_info, ptr, 0);
3648

    
3649
    if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
3650
        return -TARGET_EINVAL;
3651
    seg_32bit = ldt_info.flags & 1;
3652
    contents = (ldt_info.flags >> 1) & 3;
3653
    read_exec_only = (ldt_info.flags >> 3) & 1;
3654
    limit_in_pages = (ldt_info.flags >> 4) & 1;
3655
    seg_not_present = (ldt_info.flags >> 5) & 1;
3656
    useable = (ldt_info.flags >> 6) & 1;
3657
#ifdef TARGET_ABI32
3658
    lm = 0;
3659
#else
3660
    lm = (ldt_info.flags >> 7) & 1;
3661
#endif
3662
    if (contents == 3) {
3663
        if (oldmode)
3664
            return -TARGET_EINVAL;
3665
        if (seg_not_present == 0)
3666
            return -TARGET_EINVAL;
3667
    }
3668
    /* allocate the LDT */
3669
    if (!ldt_table) {
3670
        env->ldt.base = target_mmap(0,
3671
                                    TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
3672
                                    PROT_READ|PROT_WRITE,
3673
                                    MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
3674
        if (env->ldt.base == -1)
3675
            return -TARGET_ENOMEM;
3676
        memset(g2h(env->ldt.base), 0,
3677
               TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
3678
        env->ldt.limit = 0xffff;
3679
        ldt_table = g2h(env->ldt.base);
3680
    }
3681

    
3682
    /* NOTE: same code as Linux kernel */
3683
    /* Allow LDTs to be cleared by the user. */
3684
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3685
        if (oldmode ||
3686
            (contents == 0                &&
3687
             read_exec_only == 1        &&
3688
             seg_32bit == 0                &&
3689
             limit_in_pages == 0        &&
3690
             seg_not_present == 1        &&
3691
             useable == 0 )) {
3692
            entry_1 = 0;
3693
            entry_2 = 0;
3694
            goto install;
3695
        }
3696
    }
3697

    
3698
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
3699
        (ldt_info.limit & 0x0ffff);
3700
    entry_2 = (ldt_info.base_addr & 0xff000000) |
3701
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3702
        (ldt_info.limit & 0xf0000) |
3703
        ((read_exec_only ^ 1) << 9) |
3704
        (contents << 10) |
3705
        ((seg_not_present ^ 1) << 15) |
3706
        (seg_32bit << 22) |
3707
        (limit_in_pages << 23) |
3708
        (lm << 21) |
3709
        0x7000;
3710
    if (!oldmode)
3711
        entry_2 |= (useable << 20);
3712

    
3713
    /* Install the new entry ...  */
3714
install:
3715
    lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
3716
    lp[0] = tswap32(entry_1);
3717
    lp[1] = tswap32(entry_2);
3718
    return 0;
3719
}
3720

    
3721
/* specific and weird i386 syscalls */
3722
static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
3723
                              unsigned long bytecount)
3724
{
3725
    abi_long ret;
3726

    
3727
    switch (func) {
3728
    case 0:
3729
        ret = read_ldt(ptr, bytecount);
3730
        break;
3731
    case 1:
3732
        ret = write_ldt(env, ptr, bytecount, 1);
3733
        break;
3734
    case 0x11:
3735
        ret = write_ldt(env, ptr, bytecount, 0);
3736
        break;
3737
    default:
3738
        ret = -TARGET_ENOSYS;
3739
        break;
3740
    }
3741
    return ret;
3742
}
3743

    
3744
#if defined(TARGET_I386) && defined(TARGET_ABI32)
3745
static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
3746
{
3747
    uint64_t *gdt_table = g2h(env->gdt.base);
3748
    struct target_modify_ldt_ldt_s ldt_info;
3749
    struct target_modify_ldt_ldt_s *target_ldt_info;
3750
    int seg_32bit, contents, read_exec_only, limit_in_pages;
3751
    int seg_not_present, useable, lm;
3752
    uint32_t *lp, entry_1, entry_2;
3753
    int i;
3754

    
3755
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3756
    if (!target_ldt_info)
3757
        return -TARGET_EFAULT;
3758
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3759
    ldt_info.base_addr = tswapal(target_ldt_info->base_addr);
3760
    ldt_info.limit = tswap32(target_ldt_info->limit);
3761
    ldt_info.flags = tswap32(target_ldt_info->flags);
3762
    if (ldt_info.entry_number == -1) {
3763
        for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
3764
            if (gdt_table[i] == 0) {
3765
                ldt_info.entry_number = i;
3766
                target_ldt_info->entry_number = tswap32(i);
3767
                break;
3768
            }
3769
        }
3770
    }
3771
    unlock_user_struct(target_ldt_info, ptr, 1);
3772

    
3773
    if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || 
3774
        ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
3775
           return -TARGET_EINVAL;
3776
    seg_32bit = ldt_info.flags & 1;
3777
    contents = (ldt_info.flags >> 1) & 3;
3778
    read_exec_only = (ldt_info.flags >> 3) & 1;
3779
    limit_in_pages = (ldt_info.flags >> 4) & 1;
3780
    seg_not_present = (ldt_info.flags >> 5) & 1;
3781
    useable = (ldt_info.flags >> 6) & 1;
3782
#ifdef TARGET_ABI32
3783
    lm = 0;
3784
#else
3785
    lm = (ldt_info.flags >> 7) & 1;
3786
#endif
3787

    
3788
    if (contents == 3) {
3789
        if (seg_not_present == 0)
3790
            return -TARGET_EINVAL;
3791
    }
3792

    
3793
    /* NOTE: same code as Linux kernel */
3794
    /* Allow LDTs to be cleared by the user. */
3795
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3796
        if ((contents == 0             &&
3797
             read_exec_only == 1       &&
3798
             seg_32bit == 0            &&
3799
             limit_in_pages == 0       &&
3800
             seg_not_present == 1      &&
3801
             useable == 0 )) {
3802
            entry_1 = 0;
3803
            entry_2 = 0;
3804
            goto install;
3805
        }
3806
    }
3807

    
3808
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
3809
        (ldt_info.limit & 0x0ffff);
3810
    entry_2 = (ldt_info.base_addr & 0xff000000) |
3811
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3812
        (ldt_info.limit & 0xf0000) |
3813
        ((read_exec_only ^ 1) << 9) |
3814
        (contents << 10) |
3815
        ((seg_not_present ^ 1) << 15) |
3816
        (seg_32bit << 22) |
3817
        (limit_in_pages << 23) |
3818
        (useable << 20) |
3819
        (lm << 21) |
3820
        0x7000;
3821

    
3822
    /* Install the new entry ...  */
3823
install:
3824
    lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
3825
    lp[0] = tswap32(entry_1);
3826
    lp[1] = tswap32(entry_2);
3827
    return 0;
3828
}
3829

    
3830
static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
3831
{
3832
    struct target_modify_ldt_ldt_s *target_ldt_info;
3833
    uint64_t *gdt_table = g2h(env->gdt.base);
3834
    uint32_t base_addr, limit, flags;
3835
    int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
3836
    int seg_not_present, useable, lm;
3837
    uint32_t *lp, entry_1, entry_2;
3838

    
3839
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3840
    if (!target_ldt_info)
3841
        return -TARGET_EFAULT;
3842
    idx = tswap32(target_ldt_info->entry_number);
3843
    if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
3844
        idx > TARGET_GDT_ENTRY_TLS_MAX) {
3845
        unlock_user_struct(target_ldt_info, ptr, 1);
3846
        return -TARGET_EINVAL;
3847
    }
3848
    lp = (uint32_t *)(gdt_table + idx);
3849
    entry_1 = tswap32(lp[0]);
3850
    entry_2 = tswap32(lp[1]);
3851
    
3852
    read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
3853
    contents = (entry_2 >> 10) & 3;
3854
    seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
3855
    seg_32bit = (entry_2 >> 22) & 1;
3856
    limit_in_pages = (entry_2 >> 23) & 1;
3857
    useable = (entry_2 >> 20) & 1;
3858
#ifdef TARGET_ABI32
3859
    lm = 0;
3860
#else
3861
    lm = (entry_2 >> 21) & 1;
3862
#endif
3863
    flags = (seg_32bit << 0) | (contents << 1) |
3864
        (read_exec_only << 3) | (limit_in_pages << 4) |
3865
        (seg_not_present << 5) | (useable << 6) | (lm << 7);
3866
    limit = (entry_1 & 0xffff) | (entry_2  & 0xf0000);
3867
    base_addr = (entry_1 >> 16) | 
3868
        (entry_2 & 0xff000000) | 
3869
        ((entry_2 & 0xff) << 16);
3870
    target_ldt_info->base_addr = tswapal(base_addr);
3871
    target_ldt_info->limit = tswap32(limit);
3872
    target_ldt_info->flags = tswap32(flags);
3873
    unlock_user_struct(target_ldt_info, ptr, 1);
3874
    return 0;
3875
}
3876
#endif /* TARGET_I386 && TARGET_ABI32 */
3877

    
3878
#ifndef TARGET_ABI32
3879
static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
3880
{
3881
    abi_long ret = 0;
3882
    abi_ulong val;
3883
    int idx;
3884

    
3885
    switch(code) {
3886
    case TARGET_ARCH_SET_GS:
3887
    case TARGET_ARCH_SET_FS:
3888
        if (code == TARGET_ARCH_SET_GS)
3889
            idx = R_GS;
3890
        else
3891
            idx = R_FS;
3892
        cpu_x86_load_seg(env, idx, 0);
3893
        env->segs[idx].base = addr;
3894
        break;
3895
    case TARGET_ARCH_GET_GS:
3896
    case TARGET_ARCH_GET_FS:
3897
        if (code == TARGET_ARCH_GET_GS)
3898
            idx = R_GS;
3899
        else
3900
            idx = R_FS;
3901
        val = env->segs[idx].base;
3902
        if (put_user(val, addr, abi_ulong))
3903
            ret = -TARGET_EFAULT;
3904
        break;
3905
    default:
3906
        ret = -TARGET_EINVAL;
3907
        break;
3908
    }
3909
    return ret;
3910
}
3911
#endif
3912

    
3913
#endif /* defined(TARGET_I386) */
3914

    
3915
#define NEW_STACK_SIZE 0x40000
3916

    
3917
#if defined(CONFIG_USE_NPTL)
3918

    
3919
static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
3920
typedef struct {
3921
    CPUState *env;
3922
    pthread_mutex_t mutex;
3923
    pthread_cond_t cond;
3924
    pthread_t thread;
3925
    uint32_t tid;
3926
    abi_ulong child_tidptr;
3927
    abi_ulong parent_tidptr;
3928
    sigset_t sigmask;
3929
} new_thread_info;
3930

    
3931
static void *clone_func(void *arg)
3932
{
3933
    new_thread_info *info = arg;
3934
    CPUState *env;
3935
    TaskState *ts;
3936

    
3937
    env = info->env;
3938
    thread_env = env;
3939
    ts = (TaskState *)thread_env->opaque;
3940
    info->tid = gettid();
3941
    env->host_tid = info->tid;
3942
    task_settid(ts);
3943
    if (info->child_tidptr)
3944
        put_user_u32(info->tid, info->child_tidptr);
3945
    if (info->parent_tidptr)
3946
        put_user_u32(info->tid, info->parent_tidptr);
3947
    /* Enable signals.  */
3948
    sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
3949
    /* Signal to the parent that we're ready.  */
3950
    pthread_mutex_lock(&info->mutex);
3951
    pthread_cond_broadcast(&info->cond);
3952
    pthread_mutex_unlock(&info->mutex);
3953
    /* Wait until the parent has finshed initializing the tls state.  */
3954
    pthread_mutex_lock(&clone_lock);
3955
    pthread_mutex_unlock(&clone_lock);
3956
    cpu_loop(env);
3957
    /* never exits */
3958
    return NULL;
3959
}
3960
#else
3961

    
3962
static int clone_func(void *arg)
3963
{
3964
    CPUState *env = arg;
3965
    cpu_loop(env);
3966
    /* never exits */
3967
    return 0;
3968
}
3969
#endif
3970

    
3971
/* do_fork() Must return host values and target errnos (unlike most
3972
   do_*() functions). */
3973
static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
3974
                   abi_ulong parent_tidptr, target_ulong newtls,
3975
                   abi_ulong child_tidptr)
3976
{
3977
    int ret;
3978
    TaskState *ts;
3979
    CPUState *new_env;
3980
#if defined(CONFIG_USE_NPTL)
3981
    unsigned int nptl_flags;
3982
    sigset_t sigmask;
3983
#else
3984
    uint8_t *new_stack;
3985
#endif
3986

    
3987
    /* Emulate vfork() with fork() */
3988
    if (flags & CLONE_VFORK)
3989
        flags &= ~(CLONE_VFORK | CLONE_VM);
3990

    
3991
    if (flags & CLONE_VM) {
3992
        TaskState *parent_ts = (TaskState *)env->opaque;
3993
#if defined(CONFIG_USE_NPTL)
3994
        new_thread_info info;
3995
        pthread_attr_t attr;
3996
#endif
3997
        ts = g_malloc0(sizeof(TaskState));
3998
        init_task_state(ts);
3999
        /* we create a new CPU instance. */
4000
        new_env = cpu_copy(env);
4001
#if defined(TARGET_I386) || defined(TARGET_SPARC) || defined(TARGET_PPC)
4002
        cpu_reset(new_env);
4003
#endif
4004
        /* Init regs that differ from the parent.  */
4005
        cpu_clone_regs(new_env, newsp);
4006
        new_env->opaque = ts;
4007
        ts->bprm = parent_ts->bprm;
4008
        ts->info = parent_ts->info;
4009
#if defined(CONFIG_USE_NPTL)
4010
        nptl_flags = flags;
4011
        flags &= ~CLONE_NPTL_FLAGS2;
4012

    
4013
        if (nptl_flags & CLONE_CHILD_CLEARTID) {
4014
            ts->child_tidptr = child_tidptr;
4015
        }
4016

    
4017
        if (nptl_flags & CLONE_SETTLS)
4018
            cpu_set_tls (new_env, newtls);
4019

    
4020
        /* Grab a mutex so that thread setup appears atomic.  */
4021
        pthread_mutex_lock(&clone_lock);
4022

    
4023
        memset(&info, 0, sizeof(info));
4024
        pthread_mutex_init(&info.mutex, NULL);
4025
        pthread_mutex_lock(&info.mutex);
4026
        pthread_cond_init(&info.cond, NULL);
4027
        info.env = new_env;
4028
        if (nptl_flags & CLONE_CHILD_SETTID)
4029
            info.child_tidptr = child_tidptr;
4030
        if (nptl_flags & CLONE_PARENT_SETTID)
4031
            info.parent_tidptr = parent_tidptr;
4032

    
4033
        ret = pthread_attr_init(&attr);
4034
        ret = pthread_attr_setstacksize(&attr, NEW_STACK_SIZE);
4035
        ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
4036
        /* It is not safe to deliver signals until the child has finished
4037
           initializing, so temporarily block all signals.  */
4038
        sigfillset(&sigmask);
4039
        sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
4040

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

    
4044
        sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
4045
        pthread_attr_destroy(&attr);
4046
        if (ret == 0) {
4047
            /* Wait for the child to initialize.  */
4048
            pthread_cond_wait(&info.cond, &info.mutex);
4049
            ret = info.tid;
4050
            if (flags & CLONE_PARENT_SETTID)
4051
                put_user_u32(ret, parent_tidptr);
4052
        } else {
4053
            ret = -1;
4054
        }
4055
        pthread_mutex_unlock(&info.mutex);
4056
        pthread_cond_destroy(&info.cond);
4057
        pthread_mutex_destroy(&info.mutex);
4058
        pthread_mutex_unlock(&clone_lock);
4059
#else
4060
        if (flags & CLONE_NPTL_FLAGS2)
4061
            return -EINVAL;
4062
        /* This is probably going to die very quickly, but do it anyway.  */
4063
        new_stack = g_malloc0 (NEW_STACK_SIZE);
4064
#ifdef __ia64__
4065
        ret = __clone2(clone_func, new_stack, NEW_STACK_SIZE, flags, new_env);
4066
#else
4067
        ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
4068
#endif
4069
#endif
4070
    } else {
4071
        /* if no CLONE_VM, we consider it is a fork */
4072
        if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
4073
            return -EINVAL;
4074
        fork_start();
4075
        ret = fork();
4076
        if (ret == 0) {
4077
            /* Child Process.  */
4078
            cpu_clone_regs(env, newsp);
4079
            fork_end(1);
4080
#if defined(CONFIG_USE_NPTL)
4081
            /* There is a race condition here.  The parent process could
4082
               theoretically read the TID in the child process before the child
4083
               tid is set.  This would require using either ptrace
4084
               (not implemented) or having *_tidptr to point at a shared memory
4085
               mapping.  We can't repeat the spinlock hack used above because
4086
               the child process gets its own copy of the lock.  */
4087
            if (flags & CLONE_CHILD_SETTID)
4088
                put_user_u32(gettid(), child_tidptr);
4089
            if (flags & CLONE_PARENT_SETTID)
4090
                put_user_u32(gettid(), parent_tidptr);
4091
            ts = (TaskState *)env->opaque;
4092
            if (flags & CLONE_SETTLS)
4093
                cpu_set_tls (env, newtls);
4094
            if (flags & CLONE_CHILD_CLEARTID)
4095
                ts->child_tidptr = child_tidptr;
4096
#endif
4097
        } else {
4098
            fork_end(0);
4099
        }
4100
    }
4101
    return ret;
4102
}
4103

    
4104
/* warning : doesn't handle linux specific flags... */
4105
static int target_to_host_fcntl_cmd(int cmd)
4106
{
4107
    switch(cmd) {
4108
        case TARGET_F_DUPFD:
4109
        case TARGET_F_GETFD:
4110
        case TARGET_F_SETFD:
4111
        case TARGET_F_GETFL:
4112
        case TARGET_F_SETFL:
4113
            return cmd;
4114
        case TARGET_F_GETLK:
4115
            return F_GETLK;
4116
        case TARGET_F_SETLK:
4117
            return F_SETLK;
4118
        case TARGET_F_SETLKW:
4119
            return F_SETLKW;
4120
        case TARGET_F_GETOWN:
4121
            return F_GETOWN;
4122
        case TARGET_F_SETOWN:
4123
            return F_SETOWN;
4124
        case TARGET_F_GETSIG:
4125
            return F_GETSIG;
4126
        case TARGET_F_SETSIG:
4127
            return F_SETSIG;
4128
#if TARGET_ABI_BITS == 32
4129
        case TARGET_F_GETLK64:
4130
            return F_GETLK64;
4131
        case TARGET_F_SETLK64:
4132
            return F_SETLK64;
4133
        case TARGET_F_SETLKW64:
4134
            return F_SETLKW64;
4135
#endif
4136
        case TARGET_F_SETLEASE:
4137
            return F_SETLEASE;
4138
        case TARGET_F_GETLEASE:
4139
            return F_GETLEASE;
4140
#ifdef F_DUPFD_CLOEXEC
4141
        case TARGET_F_DUPFD_CLOEXEC:
4142
            return F_DUPFD_CLOEXEC;
4143
#endif
4144
        case TARGET_F_NOTIFY:
4145
            return F_NOTIFY;
4146
        default:
4147
            return -TARGET_EINVAL;
4148
    }
4149
    return -TARGET_EINVAL;
4150
}
4151

    
4152
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
4153
{
4154
    struct flock fl;
4155
    struct target_flock *target_fl;
4156
    struct flock64 fl64;
4157
    struct target_flock64 *target_fl64;
4158
    abi_long ret;
4159
    int host_cmd = target_to_host_fcntl_cmd(cmd);
4160

    
4161
    if (host_cmd == -TARGET_EINVAL)
4162
            return host_cmd;
4163

    
4164
    switch(cmd) {
4165
    case TARGET_F_GETLK:
4166
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
4167
            return -TARGET_EFAULT;
4168
        fl.l_type = tswap16(target_fl->l_type);
4169
        fl.l_whence = tswap16(target_fl->l_whence);
4170
        fl.l_start = tswapal(target_fl->l_start);
4171
        fl.l_len = tswapal(target_fl->l_len);
4172
        fl.l_pid = tswap32(target_fl->l_pid);
4173
        unlock_user_struct(target_fl, arg, 0);
4174
        ret = get_errno(fcntl(fd, host_cmd, &fl));
4175
        if (ret == 0) {
4176
            if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
4177
                return -TARGET_EFAULT;
4178
            target_fl->l_type = tswap16(fl.l_type);
4179
            target_fl->l_whence = tswap16(fl.l_whence);
4180
            target_fl->l_start = tswapal(fl.l_start);
4181
            target_fl->l_len = tswapal(fl.l_len);
4182
            target_fl->l_pid = tswap32(fl.l_pid);
4183
            unlock_user_struct(target_fl, arg, 1);
4184
        }
4185
        break;
4186

    
4187
    case TARGET_F_SETLK:
4188
    case TARGET_F_SETLKW:
4189
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
4190
            return -TARGET_EFAULT;
4191
        fl.l_type = tswap16(target_fl->l_type);
4192
        fl.l_whence = tswap16(target_fl->l_whence);
4193
        fl.l_start = tswapal(target_fl->l_start);
4194
        fl.l_len = tswapal(target_fl->l_len);
4195
        fl.l_pid = tswap32(target_fl->l_pid);
4196
        unlock_user_struct(target_fl, arg, 0);
4197
        ret = get_errno(fcntl(fd, host_cmd, &fl));
4198
        break;
4199

    
4200
    case TARGET_F_GETLK64:
4201
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
4202
            return -TARGET_EFAULT;
4203
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
4204
        fl64.l_whence = tswap16(target_fl64->l_whence);
4205
        fl64.l_start = tswap64(target_fl64->l_start);
4206
        fl64.l_len = tswap64(target_fl64->l_len);
4207
        fl64.l_pid = tswap32(target_fl64->l_pid);
4208
        unlock_user_struct(target_fl64, arg, 0);
4209
        ret = get_errno(fcntl(fd, host_cmd, &fl64));
4210
        if (ret == 0) {
4211
            if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
4212
                return -TARGET_EFAULT;
4213
            target_fl64->l_type = tswap16(fl64.l_type) >> 1;
4214
            target_fl64->l_whence = tswap16(fl64.l_whence);
4215
            target_fl64->l_start = tswap64(fl64.l_start);
4216
            target_fl64->l_len = tswap64(fl64.l_len);
4217
            target_fl64->l_pid = tswap32(fl64.l_pid);
4218
            unlock_user_struct(target_fl64, arg, 1);
4219
        }
4220
        break;
4221
    case TARGET_F_SETLK64:
4222
    case TARGET_F_SETLKW64:
4223
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
4224
            return -TARGET_EFAULT;
4225
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
4226
        fl64.l_whence = tswap16(target_fl64->l_whence);
4227
        fl64.l_start = tswap64(target_fl64->l_start);
4228
        fl64.l_len = tswap64(target_fl64->l_len);
4229
        fl64.l_pid = tswap32(target_fl64->l_pid);
4230
        unlock_user_struct(target_fl64, arg, 0);
4231
        ret = get_errno(fcntl(fd, host_cmd, &fl64));
4232
        break;
4233

    
4234
    case TARGET_F_GETFL:
4235
        ret = get_errno(fcntl(fd, host_cmd, arg));
4236
        if (ret >= 0) {
4237
            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
4238
        }
4239
        break;
4240

    
4241
    case TARGET_F_SETFL:
4242
        ret = get_errno(fcntl(fd, host_cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
4243
        break;
4244

    
4245
    case TARGET_F_SETOWN:
4246
    case TARGET_F_GETOWN:
4247
    case TARGET_F_SETSIG:
4248
    case TARGET_F_GETSIG:
4249
    case TARGET_F_SETLEASE:
4250
    case TARGET_F_GETLEASE:
4251
        ret = get_errno(fcntl(fd, host_cmd, arg));
4252
        break;
4253

    
4254
    default:
4255
        ret = get_errno(fcntl(fd, cmd, arg));
4256
        break;
4257
    }
4258
    return ret;
4259
}
4260

    
4261
#ifdef USE_UID16
4262

    
4263
static inline int high2lowuid(int uid)
4264
{
4265
    if (uid > 65535)
4266
        return 65534;
4267
    else
4268
        return uid;
4269
}
4270

    
4271
static inline int high2lowgid(int gid)
4272
{
4273
    if (gid > 65535)
4274
        return 65534;
4275
    else
4276
        return gid;
4277
}
4278

    
4279
static inline int low2highuid(int uid)
4280
{
4281
    if ((int16_t)uid == -1)
4282
        return -1;
4283
    else
4284
        return uid;
4285
}
4286

    
4287
static inline int low2highgid(int gid)
4288
{
4289
    if ((int16_t)gid == -1)
4290
        return -1;
4291
    else
4292
        return gid;
4293
}
4294
static inline int tswapid(int id)
4295
{
4296
    return tswap16(id);
4297
}
4298
#else /* !USE_UID16 */
4299
static inline int high2lowuid(int uid)
4300
{
4301
    return uid;
4302
}
4303
static inline int high2lowgid(int gid)
4304
{
4305
    return gid;
4306
}
4307
static inline int low2highuid(int uid)
4308
{
4309
    return uid;
4310
}
4311
static inline int low2highgid(int gid)
4312
{
4313
    return gid;
4314
}
4315
static inline int tswapid(int id)
4316
{
4317
    return tswap32(id);
4318
}
4319
#endif /* USE_UID16 */
4320

    
4321
void syscall_init(void)
4322
{
4323
    IOCTLEntry *ie;
4324
    const argtype *arg_type;
4325
    int size;
4326
    int i;
4327

    
4328
#define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
4329
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
4330
#include "syscall_types.h"
4331
#undef STRUCT
4332
#undef STRUCT_SPECIAL
4333

    
4334
    /* we patch the ioctl size if necessary. We rely on the fact that
4335
       no ioctl has all the bits at '1' in the size field */
4336
    ie = ioctl_entries;
4337
    while (ie->target_cmd != 0) {
4338
        if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
4339
            TARGET_IOC_SIZEMASK) {
4340
            arg_type = ie->arg_type;
4341
            if (arg_type[0] != TYPE_PTR) {
4342
                fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
4343
                        ie->target_cmd);
4344
                exit(1);
4345
            }
4346
            arg_type++;
4347
            size = thunk_type_size(arg_type, 0);
4348
            ie->target_cmd = (ie->target_cmd &
4349
                              ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
4350
                (size << TARGET_IOC_SIZESHIFT);
4351
        }
4352

    
4353
        /* Build target_to_host_errno_table[] table from
4354
         * host_to_target_errno_table[]. */
4355
        for (i=0; i < ERRNO_TABLE_SIZE; i++)
4356
                target_to_host_errno_table[host_to_target_errno_table[i]] = i;
4357

    
4358
        /* automatic consistency check if same arch */
4359
#if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
4360
    (defined(__x86_64__) && defined(TARGET_X86_64))
4361
        if (unlikely(ie->target_cmd != ie->host_cmd)) {
4362
            fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
4363
                    ie->name, ie->target_cmd, ie->host_cmd);
4364
        }
4365
#endif
4366
        ie++;
4367
    }
4368
}
4369

    
4370
#if TARGET_ABI_BITS == 32
4371
static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
4372
{
4373
#ifdef TARGET_WORDS_BIGENDIAN
4374
    return ((uint64_t)word0 << 32) | word1;
4375
#else
4376
    return ((uint64_t)word1 << 32) | word0;
4377
#endif
4378
}
4379
#else /* TARGET_ABI_BITS == 32 */
4380
static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
4381
{
4382
    return word0;
4383
}
4384
#endif /* TARGET_ABI_BITS != 32 */
4385

    
4386
#ifdef TARGET_NR_truncate64
4387
static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
4388
                                         abi_long arg2,
4389
                                         abi_long arg3,
4390
                                         abi_long arg4)
4391
{
4392
    if (regpairs_aligned(cpu_env)) {
4393
        arg2 = arg3;
4394
        arg3 = arg4;
4395
    }
4396
    return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
4397
}
4398
#endif
4399

    
4400
#ifdef TARGET_NR_ftruncate64
4401
static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
4402
                                          abi_long arg2,
4403
                                          abi_long arg3,
4404
                                          abi_long arg4)
4405
{
4406
    if (regpairs_aligned(cpu_env)) {
4407
        arg2 = arg3;
4408
        arg3 = arg4;
4409
    }
4410
    return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
4411
}
4412
#endif
4413

    
4414
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
4415
                                               abi_ulong target_addr)
4416
{
4417
    struct target_timespec *target_ts;
4418

    
4419
    if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
4420
        return -TARGET_EFAULT;
4421
    host_ts->tv_sec = tswapal(target_ts->tv_sec);
4422
    host_ts->tv_nsec = tswapal(target_ts->tv_nsec);
4423
    unlock_user_struct(target_ts, target_addr, 0);
4424
    return 0;
4425
}
4426

    
4427
static inline abi_long host_to_target_timespec(abi_ulong target_addr,
4428
                                               struct timespec *host_ts)
4429
{
4430
    struct target_timespec *target_ts;
4431

    
4432
    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
4433
        return -TARGET_EFAULT;
4434
    target_ts->tv_sec = tswapal(host_ts->tv_sec);
4435
    target_ts->tv_nsec = tswapal(host_ts->tv_nsec);
4436
    unlock_user_struct(target_ts, target_addr, 1);
4437
    return 0;
4438
}
4439

    
4440
#if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
4441
static inline abi_long host_to_target_stat64(void *cpu_env,
4442
                                             abi_ulong target_addr,
4443
                                             struct stat *host_st)
4444
{
4445
#ifdef TARGET_ARM
4446
    if (((CPUARMState *)cpu_env)->eabi) {
4447
        struct target_eabi_stat64 *target_st;
4448

    
4449
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
4450
            return -TARGET_EFAULT;
4451
        memset(target_st, 0, sizeof(struct target_eabi_stat64));
4452
        __put_user(host_st->st_dev, &target_st->st_dev);
4453
        __put_user(host_st->st_ino, &target_st->st_ino);
4454
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4455
        __put_user(host_st->st_ino, &target_st->__st_ino);
4456
#endif
4457
        __put_user(host_st->st_mode, &target_st->st_mode);
4458
        __put_user(host_st->st_nlink, &target_st->st_nlink);
4459
        __put_user(host_st->st_uid, &target_st->st_uid);
4460
        __put_user(host_st->st_gid, &target_st->st_gid);
4461
        __put_user(host_st->st_rdev, &target_st->st_rdev);
4462
        __put_user(host_st->st_size, &target_st->st_size);
4463
        __put_user(host_st->st_blksize, &target_st->st_blksize);
4464
        __put_user(host_st->st_blocks, &target_st->st_blocks);
4465
        __put_user(host_st->st_atime, &target_st->target_st_atime);
4466
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
4467
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
4468
        unlock_user_struct(target_st, target_addr, 1);
4469
    } else
4470
#endif
4471
    {
4472
#if TARGET_ABI_BITS == 64 && !defined(TARGET_ALPHA)
4473
        struct target_stat *target_st;
4474
#else
4475
        struct target_stat64 *target_st;
4476
#endif
4477

    
4478
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
4479
            return -TARGET_EFAULT;
4480
        memset(target_st, 0, sizeof(*target_st));
4481
        __put_user(host_st->st_dev, &target_st->st_dev);
4482
        __put_user(host_st->st_ino, &target_st->st_ino);
4483
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4484
        __put_user(host_st->st_ino, &target_st->__st_ino);
4485
#endif
4486
        __put_user(host_st->st_mode, &target_st->st_mode);
4487
        __put_user(host_st->st_nlink, &target_st->st_nlink);
4488
        __put_user(host_st->st_uid, &target_st->st_uid);
4489
        __put_user(host_st->st_gid, &target_st->st_gid);
4490
        __put_user(host_st->st_rdev, &target_st->st_rdev);
4491
        /* XXX: better use of kernel struct */
4492
        __put_user(host_st->st_size, &target_st->st_size);
4493
        __put_user(host_st->st_blksize, &target_st->st_blksize);
4494
        __put_user(host_st->st_blocks, &target_st->st_blocks);
4495
        __put_user(host_st->st_atime, &target_st->target_st_atime);
4496
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
4497
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
4498
        unlock_user_struct(target_st, target_addr, 1);
4499
    }
4500

    
4501
    return 0;
4502
}
4503
#endif
4504

    
4505
#if defined(CONFIG_USE_NPTL)
4506
/* ??? Using host futex calls even when target atomic operations
4507
   are not really atomic probably breaks things.  However implementing
4508
   futexes locally would make futexes shared between multiple processes
4509
   tricky.  However they're probably useless because guest atomic
4510
   operations won't work either.  */
4511
static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
4512
                    target_ulong uaddr2, int val3)
4513
{
4514
    struct timespec ts, *pts;
4515
    int base_op;
4516

    
4517
    /* ??? We assume FUTEX_* constants are the same on both host
4518
       and target.  */
4519
#ifdef FUTEX_CMD_MASK
4520
    base_op = op & FUTEX_CMD_MASK;
4521
#else
4522
    base_op = op;
4523
#endif
4524
    switch (base_op) {
4525
    case FUTEX_WAIT:
4526
        if (timeout) {
4527
            pts = &ts;
4528
            target_to_host_timespec(pts, timeout);
4529
        } else {
4530
            pts = NULL;
4531
        }
4532
        return get_errno(sys_futex(g2h(uaddr), op, tswap32(val),
4533
                         pts, NULL, 0));
4534
    case FUTEX_WAKE:
4535
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4536
    case FUTEX_FD:
4537
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4538
    case FUTEX_REQUEUE:
4539
    case FUTEX_CMP_REQUEUE:
4540
    case FUTEX_WAKE_OP:
4541
        /* For FUTEX_REQUEUE, FUTEX_CMP_REQUEUE, and FUTEX_WAKE_OP, the
4542
           TIMEOUT parameter is interpreted as a uint32_t by the kernel.
4543
           But the prototype takes a `struct timespec *'; insert casts
4544
           to satisfy the compiler.  We do not need to tswap TIMEOUT
4545
           since it's not compared to guest memory.  */
4546
        pts = (struct timespec *)(uintptr_t) timeout;
4547
        return get_errno(sys_futex(g2h(uaddr), op, val, pts,
4548
                                   g2h(uaddr2),
4549
                                   (base_op == FUTEX_CMP_REQUEUE
4550
                                    ? tswap32(val3)
4551
                                    : val3)));
4552
    default:
4553
        return -TARGET_ENOSYS;
4554
    }
4555
}
4556
#endif
4557

    
4558
/* Map host to target signal numbers for the wait family of syscalls.
4559
   Assume all other status bits are the same.  */
4560
static int host_to_target_waitstatus(int status)
4561
{
4562
    if (WIFSIGNALED(status)) {
4563
        return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f);
4564
    }
4565
    if (WIFSTOPPED(status)) {
4566
        return (host_to_target_signal(WSTOPSIG(status)) << 8)
4567
               | (status & 0xff);
4568
    }
4569
    return status;
4570
}
4571

    
4572
int get_osversion(void)
4573
{
4574
    static int osversion;
4575
    struct new_utsname buf;
4576
    const char *s;
4577
    int i, n, tmp;
4578
    if (osversion)
4579
        return osversion;
4580
    if (qemu_uname_release && *qemu_uname_release) {
4581
        s = qemu_uname_release;
4582
    } else {
4583
        if (sys_uname(&buf))
4584
            return 0;
4585
        s = buf.release;
4586
    }
4587
    tmp = 0;
4588
    for (i = 0; i < 3; i++) {
4589
        n = 0;
4590
        while (*s >= '0' && *s <= '9') {
4591
            n *= 10;
4592
            n += *s - '0';
4593
            s++;
4594
        }
4595
        tmp = (tmp << 8) + n;
4596
        if (*s == '.')
4597
            s++;
4598
    }
4599
    osversion = tmp;
4600
    return osversion;
4601
}
4602

    
4603
/* do_syscall() should always have a single exit point at the end so
4604
   that actions, such as logging of syscall results, can be performed.
4605
   All errnos that do_syscall() returns must be -TARGET_<errcode>. */
4606
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4607
                    abi_long arg2, abi_long arg3, abi_long arg4,
4608
                    abi_long arg5, abi_long arg6, abi_long arg7,
4609
                    abi_long arg8)
4610
{
4611
    abi_long ret;
4612
    struct stat st;
4613
    struct statfs stfs;
4614
    void *p;
4615

    
4616
#ifdef DEBUG
4617
    gemu_log("syscall %d", num);
4618
#endif
4619
    if(do_strace)
4620
        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
4621

    
4622
    switch(num) {
4623
    case TARGET_NR_exit:
4624
#ifdef CONFIG_USE_NPTL
4625
      /* In old applications this may be used to implement _exit(2).
4626
         However in threaded applictions it is used for thread termination,
4627
         and _exit_group is used for application termination.
4628
         Do thread termination if we have more then one thread.  */
4629
      /* FIXME: This probably breaks if a signal arrives.  We should probably
4630
         be disabling signals.  */
4631
      if (first_cpu->next_cpu) {
4632
          TaskState *ts;
4633
          CPUState **lastp;
4634
          CPUState *p;
4635

    
4636
          cpu_list_lock();
4637
          lastp = &first_cpu;
4638
          p = first_cpu;
4639
          while (p && p != (CPUState *)cpu_env) {
4640
              lastp = &p->next_cpu;
4641
              p = p->next_cpu;
4642
          }
4643
          /* If we didn't find the CPU for this thread then something is
4644
             horribly wrong.  */
4645
          if (!p)
4646
              abort();
4647
          /* Remove the CPU from the list.  */
4648
          *lastp = p->next_cpu;
4649
          cpu_list_unlock();
4650
          ts = ((CPUState *)cpu_env)->opaque;
4651
          if (ts->child_tidptr) {
4652
              put_user_u32(0, ts->child_tidptr);
4653
              sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
4654
                        NULL, NULL, 0);
4655
          }
4656
          thread_env = NULL;
4657
          g_free(cpu_env);
4658
          g_free(ts);
4659
          pthread_exit(NULL);
4660
      }
4661
#endif
4662
#ifdef TARGET_GPROF
4663
        _mcleanup();
4664
#endif
4665
        gdb_exit(cpu_env, arg1);
4666
        _exit(arg1);
4667
        ret = 0; /* avoid warning */
4668
        break;
4669
    case TARGET_NR_read:
4670
        if (arg3 == 0)
4671
            ret = 0;
4672
        else {
4673
            if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
4674
                goto efault;
4675
            ret = get_errno(read(arg1, p, arg3));
4676
            unlock_user(p, arg2, ret);
4677
        }
4678
        break;
4679
    case TARGET_NR_write:
4680
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
4681
            goto efault;
4682
        ret = get_errno(write(arg1, p, arg3));
4683
        unlock_user(p, arg2, 0);
4684
        break;
4685
    case TARGET_NR_open:
4686
        if (!(p = lock_user_string(arg1)))
4687
            goto efault;
4688
        ret = get_errno(open(path(p),
4689
                             target_to_host_bitmask(arg2, fcntl_flags_tbl),
4690
                             arg3));
4691
        unlock_user(p, arg1, 0);
4692
        break;
4693
#if defined(TARGET_NR_openat) && defined(__NR_openat)
4694
    case TARGET_NR_openat:
4695
        if (!(p = lock_user_string(arg2)))
4696
            goto efault;
4697
        ret = get_errno(sys_openat(arg1,
4698
                                   path(p),
4699
                                   target_to_host_bitmask(arg3, fcntl_flags_tbl),
4700
                                   arg4));
4701
        unlock_user(p, arg2, 0);
4702
        break;
4703
#endif
4704
    case TARGET_NR_close:
4705
        ret = get_errno(close(arg1));
4706
        break;
4707
    case TARGET_NR_brk:
4708
        ret = do_brk(arg1);
4709
        break;
4710
    case TARGET_NR_fork:
4711
        ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
4712
        break;
4713
#ifdef TARGET_NR_waitpid
4714
    case TARGET_NR_waitpid:
4715
        {
4716
            int status;
4717
            ret = get_errno(waitpid(arg1, &status, arg3));
4718
            if (!is_error(ret) && arg2
4719
                && put_user_s32(host_to_target_waitstatus(status), arg2))
4720
                goto efault;
4721
        }
4722
        break;
4723
#endif
4724
#ifdef TARGET_NR_waitid
4725
    case TARGET_NR_waitid:
4726
        {
4727
            siginfo_t info;
4728
            info.si_pid = 0;
4729
            ret = get_errno(waitid(arg1, arg2, &info, arg4));
4730
            if (!is_error(ret) && arg3 && info.si_pid != 0) {
4731
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
4732
                    goto efault;
4733
                host_to_target_siginfo(p, &info);
4734
                unlock_user(p, arg3, sizeof(target_siginfo_t));
4735
            }
4736
        }
4737
        break;
4738
#endif
4739
#ifdef TARGET_NR_creat /* not on alpha */
4740
    case TARGET_NR_creat:
4741
        if (!(p = lock_user_string(arg1)))
4742
            goto efault;
4743
        ret = get_errno(creat(p, arg2));
4744
        unlock_user(p, arg1, 0);
4745
        break;
4746
#endif
4747
    case TARGET_NR_link:
4748
        {
4749
            void * p2;
4750
            p = lock_user_string(arg1);
4751
            p2 = lock_user_string(arg2);
4752
            if (!p || !p2)
4753
                ret = -TARGET_EFAULT;
4754
            else
4755
                ret = get_errno(link(p, p2));
4756
            unlock_user(p2, arg2, 0);
4757
            unlock_user(p, arg1, 0);
4758
        }
4759
        break;
4760
#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
4761
    case TARGET_NR_linkat:
4762
        {
4763
            void * p2 = NULL;
4764
            if (!arg2 || !arg4)
4765
                goto efault;
4766
            p  = lock_user_string(arg2);
4767
            p2 = lock_user_string(arg4);
4768
            if (!p || !p2)
4769
                ret = -TARGET_EFAULT;
4770
            else
4771
                ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
4772
            unlock_user(p, arg2, 0);
4773
            unlock_user(p2, arg4, 0);
4774
        }
4775
        break;
4776
#endif
4777
    case TARGET_NR_unlink:
4778
        if (!(p = lock_user_string(arg1)))
4779
            goto efault;
4780
        ret = get_errno(unlink(p));
4781
        unlock_user(p, arg1, 0);
4782
        break;
4783
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
4784
    case TARGET_NR_unlinkat:
4785
        if (!(p = lock_user_string(arg2)))
4786
            goto efault;
4787
        ret = get_errno(sys_unlinkat(arg1, p, arg3));
4788
        unlock_user(p, arg2, 0);
4789
        break;
4790
#endif
4791
    case TARGET_NR_execve:
4792
        {
4793
            char **argp, **envp;
4794
            int argc, envc;
4795
            abi_ulong gp;
4796
            abi_ulong guest_argp;
4797
            abi_ulong guest_envp;
4798
            abi_ulong addr;
4799
            char **q;
4800

    
4801
            argc = 0;
4802
            guest_argp = arg2;
4803
            for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
4804
                if (get_user_ual(addr, gp))
4805
                    goto efault;
4806
                if (!addr)
4807
                    break;
4808
                argc++;
4809
            }
4810
            envc = 0;
4811
            guest_envp = arg3;
4812
            for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
4813
                if (get_user_ual(addr, gp))
4814
                    goto efault;
4815
                if (!addr)
4816
                    break;
4817
                envc++;
4818
            }
4819

    
4820
            argp = alloca((argc + 1) * sizeof(void *));
4821
            envp = alloca((envc + 1) * sizeof(void *));
4822

    
4823
            for (gp = guest_argp, q = argp; gp;
4824
                  gp += sizeof(abi_ulong), q++) {
4825
                if (get_user_ual(addr, gp))
4826
                    goto execve_efault;
4827
                if (!addr)
4828
                    break;
4829
                if (!(*q = lock_user_string(addr)))
4830
                    goto execve_efault;
4831
            }
4832
            *q = NULL;
4833

    
4834
            for (gp = guest_envp, q = envp; gp;
4835
                  gp += sizeof(abi_ulong), q++) {
4836
                if (get_user_ual(addr, gp))
4837
                    goto execve_efault;
4838
                if (!addr)
4839
                    break;
4840
                if (!(*q = lock_user_string(addr)))
4841
                    goto execve_efault;
4842
            }
4843
            *q = NULL;
4844

    
4845
            if (!(p = lock_user_string(arg1)))
4846
                goto execve_efault;
4847
            ret = get_errno(execve(p, argp, envp));
4848
            unlock_user(p, arg1, 0);
4849

    
4850
            goto execve_end;
4851

    
4852
        execve_efault:
4853
            ret = -TARGET_EFAULT;
4854

    
4855
        execve_end:
4856
            for (gp = guest_argp, q = argp; *q;
4857
                  gp += sizeof(abi_ulong), q++) {
4858
                if (get_user_ual(addr, gp)
4859
                    || !addr)
4860
                    break;
4861
                unlock_user(*q, addr, 0);
4862
            }
4863
            for (gp = guest_envp, q = envp; *q;
4864
                  gp += sizeof(abi_ulong), q++) {
4865
                if (get_user_ual(addr, gp)
4866
                    || !addr)
4867
                    break;
4868
                unlock_user(*q, addr, 0);
4869
            }
4870
        }
4871
        break;
4872
    case TARGET_NR_chdir:
4873
        if (!(p = lock_user_string(arg1)))
4874
            goto efault;
4875
        ret = get_errno(chdir(p));
4876
        unlock_user(p, arg1, 0);
4877
        break;
4878
#ifdef TARGET_NR_time
4879
    case TARGET_NR_time:
4880
        {
4881
            time_t host_time;
4882
            ret = get_errno(time(&host_time));
4883
            if (!is_error(ret)
4884
                && arg1
4885
                && put_user_sal(host_time, arg1))
4886
                goto efault;
4887
        }
4888
        break;
4889
#endif
4890
    case TARGET_NR_mknod:
4891
        if (!(p = lock_user_string(arg1)))
4892
            goto efault;
4893
        ret = get_errno(mknod(p, arg2, arg3));
4894
        unlock_user(p, arg1, 0);
4895
        break;
4896
#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
4897
    case TARGET_NR_mknodat:
4898
        if (!(p = lock_user_string(arg2)))
4899
            goto efault;
4900
        ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
4901
        unlock_user(p, arg2, 0);
4902
        break;
4903
#endif
4904
    case TARGET_NR_chmod:
4905
        if (!(p = lock_user_string(arg1)))
4906
            goto efault;
4907
        ret = get_errno(chmod(p, arg2));
4908
        unlock_user(p, arg1, 0);
4909
        break;
4910
#ifdef TARGET_NR_break
4911
    case TARGET_NR_break:
4912
        goto unimplemented;
4913
#endif
4914
#ifdef TARGET_NR_oldstat
4915
    case TARGET_NR_oldstat:
4916
        goto unimplemented;
4917
#endif
4918
    case TARGET_NR_lseek:
4919
        ret = get_errno(lseek(arg1, arg2, arg3));
4920
        break;
4921
#if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA)
4922
    /* Alpha specific */
4923
    case TARGET_NR_getxpid:
4924
        ((CPUAlphaState *)cpu_env)->ir[IR_A4] = getppid();
4925
        ret = get_errno(getpid());
4926
        break;
4927
#endif
4928
#ifdef TARGET_NR_getpid
4929
    case TARGET_NR_getpid:
4930
        ret = get_errno(getpid());
4931
        break;
4932
#endif
4933
    case TARGET_NR_mount:
4934
                {
4935
                        /* need to look at the data field */
4936
                        void *p2, *p3;
4937
                        p = lock_user_string(arg1);
4938
                        p2 = lock_user_string(arg2);
4939
                        p3 = lock_user_string(arg3);
4940
                        if (!p || !p2 || !p3)
4941
                            ret = -TARGET_EFAULT;
4942
                        else {
4943
                            /* FIXME - arg5 should be locked, but it isn't clear how to
4944
                             * do that since it's not guaranteed to be a NULL-terminated
4945
                             * string.
4946
                             */
4947
                            if ( ! arg5 )
4948
                                ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, NULL));
4949
                            else
4950
                                ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
4951
                        }
4952
                        unlock_user(p, arg1, 0);
4953
                        unlock_user(p2, arg2, 0);
4954
                        unlock_user(p3, arg3, 0);
4955
                        break;
4956
                }
4957
#ifdef TARGET_NR_umount
4958
    case TARGET_NR_umount:
4959
        if (!(p = lock_user_string(arg1)))
4960
            goto efault;
4961
        ret = get_errno(umount(p));
4962
        unlock_user(p, arg1, 0);
4963
        break;
4964
#endif
4965
#ifdef TARGET_NR_stime /* not on alpha */
4966
    case TARGET_NR_stime:
4967
        {
4968
            time_t host_time;
4969
            if (get_user_sal(host_time, arg1))
4970
                goto efault;
4971
            ret = get_errno(stime(&host_time));
4972
        }
4973
        break;
4974
#endif
4975
    case TARGET_NR_ptrace:
4976
        goto unimplemented;
4977
#ifdef TARGET_NR_alarm /* not on alpha */
4978
    case TARGET_NR_alarm:
4979
        ret = alarm(arg1);
4980
        break;
4981
#endif
4982
#ifdef TARGET_NR_oldfstat
4983
    case TARGET_NR_oldfstat:
4984
        goto unimplemented;
4985
#endif
4986
#ifdef TARGET_NR_pause /* not on alpha */
4987
    case TARGET_NR_pause:
4988
        ret = get_errno(pause());
4989
        break;
4990
#endif
4991
#ifdef TARGET_NR_utime
4992
    case TARGET_NR_utime:
4993
        {
4994
            struct utimbuf tbuf, *host_tbuf;
4995
            struct target_utimbuf *target_tbuf;
4996
            if (arg2) {
4997
                if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
4998
                    goto efault;
4999
                tbuf.actime = tswapal(target_tbuf->actime);
5000
                tbuf.modtime = tswapal(target_tbuf->modtime);
5001
                unlock_user_struct(target_tbuf, arg2, 0);
5002
                host_tbuf = &tbuf;
5003
            } else {
5004
                host_tbuf = NULL;
5005
            }
5006
            if (!(p = lock_user_string(arg1)))
5007
                goto efault;
5008
            ret = get_errno(utime(p, host_tbuf));
5009
            unlock_user(p, arg1, 0);
5010
        }
5011
        break;
5012
#endif
5013
    case TARGET_NR_utimes:
5014
        {
5015
            struct timeval *tvp, tv[2];
5016
            if (arg2) {
5017
                if (copy_from_user_timeval(&tv[0], arg2)
5018
                    || copy_from_user_timeval(&tv[1],
5019
                                              arg2 + sizeof(struct target_timeval)))
5020
                    goto efault;
5021
                tvp = tv;
5022
            } else {
5023
                tvp = NULL;
5024
            }
5025
            if (!(p = lock_user_string(arg1)))
5026
                goto efault;
5027
            ret = get_errno(utimes(p, tvp));
5028
            unlock_user(p, arg1, 0);
5029
        }
5030
        break;
5031
#if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
5032
    case TARGET_NR_futimesat:
5033
        {
5034
            struct timeval *tvp, tv[2];
5035
            if (arg3) {
5036
                if (copy_from_user_timeval(&tv[0], arg3)
5037
                    || copy_from_user_timeval(&tv[1],
5038
                                              arg3 + sizeof(struct target_timeval)))
5039
                    goto efault;
5040
                tvp = tv;
5041
            } else {
5042
                tvp = NULL;
5043
            }
5044
            if (!(p = lock_user_string(arg2)))
5045
                goto efault;
5046
            ret = get_errno(sys_futimesat(arg1, path(p), tvp));
5047
            unlock_user(p, arg2, 0);
5048
        }
5049
        break;
5050
#endif
5051
#ifdef TARGET_NR_stty
5052
    case TARGET_NR_stty:
5053
        goto unimplemented;
5054
#endif
5055
#ifdef TARGET_NR_gtty
5056
    case TARGET_NR_gtty:
5057
        goto unimplemented;
5058
#endif
5059
    case TARGET_NR_access:
5060
        if (!(p = lock_user_string(arg1)))
5061
            goto efault;
5062
        ret = get_errno(access(path(p), arg2));
5063
        unlock_user(p, arg1, 0);
5064
        break;
5065
#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
5066
    case TARGET_NR_faccessat:
5067
        if (!(p = lock_user_string(arg2)))
5068
            goto efault;
5069
        ret = get_errno(sys_faccessat(arg1, p, arg3));
5070
        unlock_user(p, arg2, 0);
5071
        break;
5072
#endif
5073
#ifdef TARGET_NR_nice /* not on alpha */
5074
    case TARGET_NR_nice:
5075
        ret = get_errno(nice(arg1));
5076
        break;
5077
#endif
5078
#ifdef TARGET_NR_ftime
5079
    case TARGET_NR_ftime:
5080
        goto unimplemented;
5081
#endif
5082
    case TARGET_NR_sync:
5083
        sync();
5084
        ret = 0;
5085
        break;
5086
    case TARGET_NR_kill:
5087
        ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
5088
        break;
5089
    case TARGET_NR_rename:
5090
        {
5091
            void *p2;
5092
            p = lock_user_string(arg1);
5093
            p2 = lock_user_string(arg2);
5094
            if (!p || !p2)
5095
                ret = -TARGET_EFAULT;
5096
            else
5097
                ret = get_errno(rename(p, p2));
5098
            unlock_user(p2, arg2, 0);
5099
            unlock_user(p, arg1, 0);
5100
        }
5101
        break;
5102
#if defined(TARGET_NR_renameat) && defined(__NR_renameat)
5103
    case TARGET_NR_renameat:
5104
        {
5105
            void *p2;
5106
            p  = lock_user_string(arg2);
5107
            p2 = lock_user_string(arg4);
5108
            if (!p || !p2)
5109
                ret = -TARGET_EFAULT;
5110
            else
5111
                ret = get_errno(sys_renameat(arg1, p, arg3, p2));
5112
            unlock_user(p2, arg4, 0);
5113
            unlock_user(p, arg2, 0);
5114
        }
5115
        break;
5116
#endif
5117
    case TARGET_NR_mkdir:
5118
        if (!(p = lock_user_string(arg1)))
5119
            goto efault;
5120
        ret = get_errno(mkdir(p, arg2));
5121
        unlock_user(p, arg1, 0);
5122
        break;
5123
#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
5124
    case TARGET_NR_mkdirat:
5125
        if (!(p = lock_user_string(arg2)))
5126
            goto efault;
5127
        ret = get_errno(sys_mkdirat(arg1, p, arg3));
5128
        unlock_user(p, arg2, 0);
5129
        break;
5130
#endif
5131
    case TARGET_NR_rmdir:
5132
        if (!(p = lock_user_string(arg1)))
5133
            goto efault;
5134
        ret = get_errno(rmdir(p));
5135
        unlock_user(p, arg1, 0);
5136
        break;
5137
    case TARGET_NR_dup:
5138
        ret = get_errno(dup(arg1));
5139
        break;
5140
    case TARGET_NR_pipe:
5141
        ret = do_pipe(cpu_env, arg1, 0, 0);
5142
        break;
5143
#ifdef TARGET_NR_pipe2
5144
    case TARGET_NR_pipe2:
5145
        ret = do_pipe(cpu_env, arg1, arg2, 1);
5146
        break;
5147
#endif
5148
    case TARGET_NR_times:
5149
        {
5150
            struct target_tms *tmsp;
5151
            struct tms tms;
5152
            ret = get_errno(times(&tms));
5153
            if (arg1) {
5154
                tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
5155
                if (!tmsp)
5156
                    goto efault;
5157
                tmsp->tms_utime = tswapal(host_to_target_clock_t(tms.tms_utime));
5158
                tmsp->tms_stime = tswapal(host_to_target_clock_t(tms.tms_stime));
5159
                tmsp->tms_cutime = tswapal(host_to_target_clock_t(tms.tms_cutime));
5160
                tmsp->tms_cstime = tswapal(host_to_target_clock_t(tms.tms_cstime));
5161
            }
5162
            if (!is_error(ret))
5163
                ret = host_to_target_clock_t(ret);
5164
        }
5165
        break;
5166
#ifdef TARGET_NR_prof
5167
    case TARGET_NR_prof:
5168
        goto unimplemented;
5169
#endif
5170
#ifdef TARGET_NR_signal
5171
    case TARGET_NR_signal:
5172
        goto unimplemented;
5173
#endif
5174
    case TARGET_NR_acct:
5175
        if (arg1 == 0) {
5176
            ret = get_errno(acct(NULL));
5177
        } else {
5178
            if (!(p = lock_user_string(arg1)))
5179
                goto efault;
5180
            ret = get_errno(acct(path(p)));
5181
            unlock_user(p, arg1, 0);
5182
        }
5183
        break;
5184
#ifdef TARGET_NR_umount2 /* not on alpha */
5185
    case TARGET_NR_umount2:
5186
        if (!(p = lock_user_string(arg1)))
5187
            goto efault;
5188
        ret = get_errno(umount2(p, arg2));
5189
        unlock_user(p, arg1, 0);
5190
        break;
5191
#endif
5192
#ifdef TARGET_NR_lock
5193
    case TARGET_NR_lock:
5194
        goto unimplemented;
5195
#endif
5196
    case TARGET_NR_ioctl:
5197
        ret = do_ioctl(arg1, arg2, arg3);
5198
        break;
5199
    case TARGET_NR_fcntl:
5200
        ret = do_fcntl(arg1, arg2, arg3);
5201
        break;
5202
#ifdef TARGET_NR_mpx
5203
    case TARGET_NR_mpx:
5204
        goto unimplemented;
5205
#endif
5206
    case TARGET_NR_setpgid:
5207
        ret = get_errno(setpgid(arg1, arg2));
5208
        break;
5209
#ifdef TARGET_NR_ulimit
5210
    case TARGET_NR_ulimit:
5211
        goto unimplemented;
5212
#endif
5213
#ifdef TARGET_NR_oldolduname
5214
    case TARGET_NR_oldolduname:
5215
        goto unimplemented;
5216
#endif
5217
    case TARGET_NR_umask:
5218
        ret = get_errno(umask(arg1));
5219
        break;
5220
    case TARGET_NR_chroot:
5221
        if (!(p = lock_user_string(arg1)))
5222
            goto efault;
5223
        ret = get_errno(chroot(p));
5224
        unlock_user(p, arg1, 0);
5225
        break;
5226
    case TARGET_NR_ustat:
5227
        goto unimplemented;
5228
    case TARGET_NR_dup2:
5229
        ret = get_errno(dup2(arg1, arg2));
5230
        break;
5231
#if defined(CONFIG_DUP3) && defined(TARGET_NR_dup3)
5232
    case TARGET_NR_dup3:
5233
        ret = get_errno(dup3(arg1, arg2, arg3));
5234
        break;
5235
#endif
5236
#ifdef TARGET_NR_getppid /* not on alpha */
5237
    case TARGET_NR_getppid:
5238
        ret = get_errno(getppid());
5239
        break;
5240
#endif
5241
    case TARGET_NR_getpgrp:
5242
        ret = get_errno(getpgrp());
5243
        break;
5244
    case TARGET_NR_setsid:
5245
        ret = get_errno(setsid());
5246
        break;
5247
#ifdef TARGET_NR_sigaction
5248
    case TARGET_NR_sigaction:
5249
        {
5250
#if defined(TARGET_ALPHA)
5251
            struct target_sigaction act, oact, *pact = 0;
5252
            struct target_old_sigaction *old_act;
5253
            if (arg2) {
5254
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
5255
                    goto efault;
5256
                act._sa_handler = old_act->_sa_handler;
5257
                target_siginitset(&act.sa_mask, old_act->sa_mask);
5258
                act.sa_flags = old_act->sa_flags;
5259
                act.sa_restorer = 0;
5260
                unlock_user_struct(old_act, arg2, 0);
5261
                pact = &act;
5262
            }
5263
            ret = get_errno(do_sigaction(arg1, pact, &oact));
5264
            if (!is_error(ret) && arg3) {
5265
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
5266
                    goto efault;
5267
                old_act->_sa_handler = oact._sa_handler;
5268
                old_act->sa_mask = oact.sa_mask.sig[0];
5269
                old_act->sa_flags = oact.sa_flags;
5270
                unlock_user_struct(old_act, arg3, 1);
5271
            }
5272
#elif defined(TARGET_MIPS)
5273
            struct target_sigaction act, oact, *pact, *old_act;
5274

    
5275
            if (arg2) {
5276
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
5277
                    goto efault;
5278
                act._sa_handler = old_act->_sa_handler;
5279
                target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
5280
                act.sa_flags = old_act->sa_flags;
5281
                unlock_user_struct(old_act, arg2, 0);
5282
                pact = &act;
5283
            } else {
5284
                pact = NULL;
5285
            }
5286

    
5287
            ret = get_errno(do_sigaction(arg1, pact, &oact));
5288

    
5289
            if (!is_error(ret) && arg3) {
5290
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
5291
                    goto efault;
5292
                old_act->_sa_handler = oact._sa_handler;
5293
                old_act->sa_flags = oact.sa_flags;
5294
                old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
5295
                old_act->sa_mask.sig[1] = 0;
5296
                old_act->sa_mask.sig[2] = 0;
5297
                old_act->sa_mask.sig[3] = 0;
5298
                unlock_user_struct(old_act, arg3, 1);
5299
            }
5300
#else
5301
            struct target_old_sigaction *old_act;
5302
            struct target_sigaction act, oact, *pact;
5303
            if (arg2) {
5304
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
5305
                    goto efault;
5306
                act._sa_handler = old_act->_sa_handler;
5307
                target_siginitset(&act.sa_mask, old_act->sa_mask);
5308
                act.sa_flags = old_act->sa_flags;
5309
                act.sa_restorer = old_act->sa_restorer;
5310
                unlock_user_struct(old_act, arg2, 0);
5311
                pact = &act;
5312
            } else {
5313
                pact = NULL;
5314
            }
5315
            ret = get_errno(do_sigaction(arg1, pact, &oact));
5316
            if (!is_error(ret) && arg3) {
5317
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
5318
                    goto efault;
5319
                old_act->_sa_handler = oact._sa_handler;
5320
                old_act->sa_mask = oact.sa_mask.sig[0];
5321
                old_act->sa_flags = oact.sa_flags;
5322
                old_act->sa_restorer = oact.sa_restorer;
5323
                unlock_user_struct(old_act, arg3, 1);
5324
            }
5325
#endif
5326
        }
5327
        break;
5328
#endif
5329
    case TARGET_NR_rt_sigaction:
5330
        {
5331
#if defined(TARGET_ALPHA)
5332
            struct target_sigaction act, oact, *pact = 0;
5333
            struct target_rt_sigaction *rt_act;
5334
            /* ??? arg4 == sizeof(sigset_t).  */
5335
            if (arg2) {
5336
                if (!lock_user_struct(VERIFY_READ, rt_act, arg2, 1))
5337
                    goto efault;
5338
                act._sa_handler = rt_act->_sa_handler;
5339
                act.sa_mask = rt_act->sa_mask;
5340
                act.sa_flags = rt_act->sa_flags;
5341
                act.sa_restorer = arg5;
5342
                unlock_user_struct(rt_act, arg2, 0);
5343
                pact = &act;
5344
            }
5345
            ret = get_errno(do_sigaction(arg1, pact, &oact));
5346
            if (!is_error(ret) && arg3) {
5347
                if (!lock_user_struct(VERIFY_WRITE, rt_act, arg3, 0))
5348
                    goto efault;
5349
                rt_act->_sa_handler = oact._sa_handler;
5350
                rt_act->sa_mask = oact.sa_mask;
5351
                rt_act->sa_flags = oact.sa_flags;
5352
                unlock_user_struct(rt_act, arg3, 1);
5353
            }
5354
#else
5355
            struct target_sigaction *act;
5356
            struct target_sigaction *oact;
5357

    
5358
            if (arg2) {
5359
                if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
5360
                    goto efault;
5361
            } else
5362
                act = NULL;
5363
            if (arg3) {
5364
                if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
5365
                    ret = -TARGET_EFAULT;
5366
                    goto rt_sigaction_fail;
5367
                }
5368
            } else
5369
                oact = NULL;
5370
            ret = get_errno(do_sigaction(arg1, act, oact));
5371
        rt_sigaction_fail:
5372
            if (act)
5373
                unlock_user_struct(act, arg2, 0);
5374
            if (oact)
5375
                unlock_user_struct(oact, arg3, 1);
5376
#endif
5377
        }
5378
        break;
5379
#ifdef TARGET_NR_sgetmask /* not on alpha */
5380
    case TARGET_NR_sgetmask:
5381
        {
5382
            sigset_t cur_set;
5383
            abi_ulong target_set;
5384
            sigprocmask(0, NULL, &cur_set);
5385
            host_to_target_old_sigset(&target_set, &cur_set);
5386
            ret = target_set;
5387
        }
5388
        break;
5389
#endif
5390
#ifdef TARGET_NR_ssetmask /* not on alpha */
5391
    case TARGET_NR_ssetmask:
5392
        {
5393
            sigset_t set, oset, cur_set;
5394
            abi_ulong target_set = arg1;
5395
            sigprocmask(0, NULL, &cur_set);
5396
            target_to_host_old_sigset(&set, &target_set);
5397
            sigorset(&set, &set, &cur_set);
5398
            sigprocmask(SIG_SETMASK, &set, &oset);
5399
            host_to_target_old_sigset(&target_set, &oset);
5400
            ret = target_set;
5401
        }
5402
        break;
5403
#endif
5404
#ifdef TARGET_NR_sigprocmask
5405
    case TARGET_NR_sigprocmask:
5406
        {
5407
#if defined(TARGET_ALPHA)
5408
            sigset_t set, oldset;
5409
            abi_ulong mask;
5410
            int how;
5411

    
5412
            switch (arg1) {
5413
            case TARGET_SIG_BLOCK:
5414
                how = SIG_BLOCK;
5415
                break;
5416
            case TARGET_SIG_UNBLOCK:
5417
                how = SIG_UNBLOCK;
5418
                break;
5419
            case TARGET_SIG_SETMASK:
5420
                how = SIG_SETMASK;
5421
                break;
5422
            default:
5423
                ret = -TARGET_EINVAL;
5424
                goto fail;
5425
            }
5426
            mask = arg2;
5427
            target_to_host_old_sigset(&set, &mask);
5428

    
5429
            ret = get_errno(sigprocmask(how, &set, &oldset));
5430

    
5431
            if (!is_error(ret)) {
5432
                host_to_target_old_sigset(&mask, &oldset);
5433
                ret = mask;
5434
                ((CPUAlphaState *)cpu_env)->[IR_V0] = 0; /* force no error */
5435
            }
5436
#else
5437
            sigset_t set, oldset, *set_ptr;
5438
            int how;
5439

    
5440
            if (arg2) {
5441
                switch (arg1) {
5442
                case TARGET_SIG_BLOCK:
5443
                    how = SIG_BLOCK;
5444
                    break;
5445
                case TARGET_SIG_UNBLOCK:
5446
                    how = SIG_UNBLOCK;
5447
                    break;
5448
                case TARGET_SIG_SETMASK:
5449
                    how = SIG_SETMASK;
5450
                    break;
5451
                default:
5452
                    ret = -TARGET_EINVAL;
5453
                    goto fail;
5454
                }
5455
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
5456
                    goto efault;
5457
                target_to_host_old_sigset(&set, p);
5458
                unlock_user(p, arg2, 0);
5459
                set_ptr = &set;
5460
            } else {
5461
                how = 0;
5462
                set_ptr = NULL;
5463
            }
5464
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
5465
            if (!is_error(ret) && arg3) {
5466
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
5467
                    goto efault;
5468
                host_to_target_old_sigset(p, &oldset);
5469
                unlock_user(p, arg3, sizeof(target_sigset_t));
5470
            }
5471
#endif
5472
        }
5473
        break;
5474
#endif
5475
    case TARGET_NR_rt_sigprocmask:
5476
        {
5477
            int how = arg1;
5478
            sigset_t set, oldset, *set_ptr;
5479

    
5480
            if (arg2) {
5481
                switch(how) {
5482
                case TARGET_SIG_BLOCK:
5483
                    how = SIG_BLOCK;
5484
                    break;
5485
                case TARGET_SIG_UNBLOCK:
5486
                    how = SIG_UNBLOCK;
5487
                    break;
5488
                case TARGET_SIG_SETMASK:
5489
                    how = SIG_SETMASK;
5490
                    break;
5491
                default:
5492
                    ret = -TARGET_EINVAL;
5493
                    goto fail;
5494
                }
5495
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
5496
                    goto efault;
5497
                target_to_host_sigset(&set, p);
5498
                unlock_user(p, arg2, 0);
5499
                set_ptr = &set;
5500
            } else {
5501
                how = 0;
5502
                set_ptr = NULL;
5503
            }
5504
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
5505
            if (!is_error(ret) && arg3) {
5506
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
5507
                    goto efault;
5508
                host_to_target_sigset(p, &oldset);
5509
                unlock_user(p, arg3, sizeof(target_sigset_t));
5510
            }
5511
        }
5512
        break;
5513
#ifdef TARGET_NR_sigpending
5514
    case TARGET_NR_sigpending:
5515
        {
5516
            sigset_t set;
5517
            ret = get_errno(sigpending(&set));
5518
            if (!is_error(ret)) {
5519
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
5520
                    goto efault;
5521
                host_to_target_old_sigset(p, &set);
5522
                unlock_user(p, arg1, sizeof(target_sigset_t));
5523
            }
5524
        }
5525
        break;
5526
#endif
5527
    case TARGET_NR_rt_sigpending:
5528
        {
5529
            sigset_t set;
5530
            ret = get_errno(sigpending(&set));
5531
            if (!is_error(ret)) {
5532
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
5533
                    goto efault;
5534
                host_to_target_sigset(p, &set);
5535
                unlock_user(p, arg1, sizeof(target_sigset_t));
5536
            }
5537
        }
5538
        break;
5539
#ifdef TARGET_NR_sigsuspend
5540
    case TARGET_NR_sigsuspend:
5541
        {
5542
            sigset_t set;
5543
#if defined(TARGET_ALPHA)
5544
            abi_ulong mask = arg1;
5545
            target_to_host_old_sigset(&set, &mask);
5546
#else
5547
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
5548
                goto efault;
5549
            target_to_host_old_sigset(&set, p);
5550
            unlock_user(p, arg1, 0);
5551
#endif
5552
            ret = get_errno(sigsuspend(&set));
5553
        }
5554
        break;
5555
#endif
5556
    case TARGET_NR_rt_sigsuspend:
5557
        {
5558
            sigset_t set;
5559
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
5560
                goto efault;
5561
            target_to_host_sigset(&set, p);
5562
            unlock_user(p, arg1, 0);
5563
            ret = get_errno(sigsuspend(&set));
5564
        }
5565
        break;
5566
    case TARGET_NR_rt_sigtimedwait:
5567
        {
5568
            sigset_t set;
5569
            struct timespec uts, *puts;
5570
            siginfo_t uinfo;
5571

    
5572
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
5573
                goto efault;
5574
            target_to_host_sigset(&set, p);
5575
            unlock_user(p, arg1, 0);
5576
            if (arg3) {
5577
                puts = &uts;
5578
                target_to_host_timespec(puts, arg3);
5579
            } else {
5580
                puts = NULL;
5581
            }
5582
            ret = get_errno(sigtimedwait(&set, &uinfo, puts));
5583
            if (!is_error(ret) && arg2) {
5584
                if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
5585
                    goto efault;
5586
                host_to_target_siginfo(p, &uinfo);
5587
                unlock_user(p, arg2, sizeof(target_siginfo_t));
5588
            }
5589
        }
5590
        break;
5591
    case TARGET_NR_rt_sigqueueinfo:
5592
        {
5593
            siginfo_t uinfo;
5594
            if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
5595
                goto efault;
5596
            target_to_host_siginfo(&uinfo, p);
5597
            unlock_user(p, arg1, 0);
5598
            ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
5599
        }
5600
        break;
5601
#ifdef TARGET_NR_sigreturn
5602
    case TARGET_NR_sigreturn:
5603
        /* NOTE: ret is eax, so not transcoding must be done */
5604
        ret = do_sigreturn(cpu_env);
5605
        break;
5606
#endif
5607
    case TARGET_NR_rt_sigreturn:
5608
        /* NOTE: ret is eax, so not transcoding must be done */
5609
        ret = do_rt_sigreturn(cpu_env);
5610
        break;
5611
    case TARGET_NR_sethostname:
5612
        if (!(p = lock_user_string(arg1)))
5613
            goto efault;
5614
        ret = get_errno(sethostname(p, arg2));
5615
        unlock_user(p, arg1, 0);
5616
        break;
5617
    case TARGET_NR_setrlimit:
5618
        {
5619
            int resource = target_to_host_resource(arg1);
5620
            struct target_rlimit *target_rlim;
5621
            struct rlimit rlim;
5622
            if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
5623
                goto efault;
5624
            rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur);
5625
            rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max);
5626
            unlock_user_struct(target_rlim, arg2, 0);
5627
            ret = get_errno(setrlimit(resource, &rlim));
5628
        }
5629
        break;
5630
    case TARGET_NR_getrlimit:
5631
        {
5632
            int resource = target_to_host_resource(arg1);
5633
            struct target_rlimit *target_rlim;
5634
            struct rlimit rlim;
5635

    
5636
            ret = get_errno(getrlimit(resource, &rlim));
5637
            if (!is_error(ret)) {
5638
                if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
5639
                    goto efault;
5640
                target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
5641
                target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
5642
                unlock_user_struct(target_rlim, arg2, 1);
5643
            }
5644
        }
5645
        break;
5646
    case TARGET_NR_getrusage:
5647
        {
5648
            struct rusage rusage;
5649
            ret = get_errno(getrusage(arg1, &rusage));
5650
            if (!is_error(ret)) {
5651
                host_to_target_rusage(arg2, &rusage);
5652
            }
5653
        }
5654
        break;
5655
    case TARGET_NR_gettimeofday:
5656
        {
5657
            struct timeval tv;
5658
            ret = get_errno(gettimeofday(&tv, NULL));
5659
            if (!is_error(ret)) {
5660
                if (copy_to_user_timeval(arg1, &tv))
5661
                    goto efault;
5662
            }
5663
        }
5664
        break;
5665
    case TARGET_NR_settimeofday:
5666
        {
5667
            struct timeval tv;
5668
            if (copy_from_user_timeval(&tv, arg1))
5669
                goto efault;
5670
            ret = get_errno(settimeofday(&tv, NULL));
5671
        }
5672
        break;
5673
#if defined(TARGET_NR_select) && !defined(TARGET_S390X) && !defined(TARGET_S390)
5674
    case TARGET_NR_select:
5675
        {
5676
            struct target_sel_arg_struct *sel;
5677
            abi_ulong inp, outp, exp, tvp;
5678
            long nsel;
5679

    
5680
            if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
5681
                goto efault;
5682
            nsel = tswapal(sel->n);
5683
            inp = tswapal(sel->inp);
5684
            outp = tswapal(sel->outp);
5685
            exp = tswapal(sel->exp);
5686
            tvp = tswapal(sel->tvp);
5687
            unlock_user_struct(sel, arg1, 0);
5688
            ret = do_select(nsel, inp, outp, exp, tvp);
5689
        }
5690
        break;
5691
#endif
5692
#ifdef TARGET_NR_pselect6
5693
    case TARGET_NR_pselect6:
5694
        {
5695
            abi_long rfd_addr, wfd_addr, efd_addr, n, ts_addr;
5696
            fd_set rfds, wfds, efds;
5697
            fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
5698
            struct timespec ts, *ts_ptr;
5699

    
5700
            /*
5701
             * The 6th arg is actually two args smashed together,
5702
             * so we cannot use the C library.
5703
             */
5704
            sigset_t set;
5705
            struct {
5706
                sigset_t *set;
5707
                size_t size;
5708
            } sig, *sig_ptr;
5709

    
5710
            abi_ulong arg_sigset, arg_sigsize, *arg7;
5711
            target_sigset_t *target_sigset;
5712

    
5713
            n = arg1;
5714
            rfd_addr = arg2;
5715
            wfd_addr = arg3;
5716
            efd_addr = arg4;
5717
            ts_addr = arg5;
5718

    
5719
            ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
5720
            if (ret) {
5721
                goto fail;
5722
            }
5723
            ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
5724
            if (ret) {
5725
                goto fail;
5726
            }
5727
            ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
5728
            if (ret) {
5729
                goto fail;
5730
            }
5731

    
5732
            /*
5733
             * This takes a timespec, and not a timeval, so we cannot
5734
             * use the do_select() helper ...
5735
             */
5736
            if (ts_addr) {
5737
                if (target_to_host_timespec(&ts, ts_addr)) {
5738
                    goto efault;
5739
                }
5740
                ts_ptr = &ts;
5741
            } else {
5742
                ts_ptr = NULL;
5743
            }
5744

    
5745
            /* Extract the two packed args for the sigset */
5746
            if (arg6) {
5747
                sig_ptr = &sig;
5748
                sig.size = _NSIG / 8;
5749

    
5750
                arg7 = lock_user(VERIFY_READ, arg6, sizeof(*arg7) * 2, 1);
5751
                if (!arg7) {
5752
                    goto efault;
5753
                }
5754
                arg_sigset = tswapal(arg7[0]);
5755
                arg_sigsize = tswapal(arg7[1]);
5756
                unlock_user(arg7, arg6, 0);
5757

    
5758
                if (arg_sigset) {
5759
                    sig.set = &set;
5760
                    if (arg_sigsize != sizeof(*target_sigset)) {
5761
                        /* Like the kernel, we enforce correct size sigsets */
5762
                        ret = -TARGET_EINVAL;
5763
                        goto fail;
5764
                    }
5765
                    target_sigset = lock_user(VERIFY_READ, arg_sigset,
5766
                                              sizeof(*target_sigset), 1);
5767
                    if (!target_sigset) {
5768
                        goto efault;
5769
                    }
5770
                    target_to_host_sigset(&set, target_sigset);
5771
                    unlock_user(target_sigset, arg_sigset, 0);
5772
                } else {
5773
                    sig.set = NULL;
5774
                }
5775
            } else {
5776
                sig_ptr = NULL;
5777
            }
5778

    
5779
            ret = get_errno(sys_pselect6(n, rfds_ptr, wfds_ptr, efds_ptr,
5780
                                         ts_ptr, sig_ptr));
5781

    
5782
            if (!is_error(ret)) {
5783
                if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
5784
                    goto efault;
5785
                if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
5786
                    goto efault;
5787
                if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
5788
                    goto efault;
5789

    
5790
                if (ts_addr && host_to_target_timespec(ts_addr, &ts))
5791
                    goto efault;
5792
            }
5793
        }
5794
        break;
5795
#endif
5796
    case TARGET_NR_symlink:
5797
        {
5798
            void *p2;
5799
            p = lock_user_string(arg1);
5800
            p2 = lock_user_string(arg2);
5801
            if (!p || !p2)
5802
                ret = -TARGET_EFAULT;
5803
            else
5804
                ret = get_errno(symlink(p, p2));
5805
            unlock_user(p2, arg2, 0);
5806
            unlock_user(p, arg1, 0);
5807
        }
5808
        break;
5809
#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
5810
    case TARGET_NR_symlinkat:
5811
        {
5812
            void *p2;
5813
            p  = lock_user_string(arg1);
5814
            p2 = lock_user_string(arg3);
5815
            if (!p || !p2)
5816
                ret = -TARGET_EFAULT;
5817
            else
5818
                ret = get_errno(sys_symlinkat(p, arg2, p2));
5819
            unlock_user(p2, arg3, 0);
5820
            unlock_user(p, arg1, 0);
5821
        }
5822
        break;
5823
#endif
5824
#ifdef TARGET_NR_oldlstat
5825
    case TARGET_NR_oldlstat:
5826
        goto unimplemented;
5827
#endif
5828
    case TARGET_NR_readlink:
5829
        {
5830
            void *p2, *temp;
5831
            p = lock_user_string(arg1);
5832
            p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
5833
            if (!p || !p2)
5834
                ret = -TARGET_EFAULT;
5835
            else {
5836
                if (strncmp((const char *)p, "/proc/self/exe", 14) == 0) {
5837
                    char real[PATH_MAX];
5838
                    temp = realpath(exec_path,real);
5839
                    ret = (temp==NULL) ? get_errno(-1) : strlen(real) ;
5840
                    snprintf((char *)p2, arg3, "%s", real);
5841
                    }
5842
                else
5843
                    ret = get_errno(readlink(path(p), p2, arg3));
5844
            }
5845
            unlock_user(p2, arg2, ret);
5846
            unlock_user(p, arg1, 0);
5847
        }
5848
        break;
5849
#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
5850
    case TARGET_NR_readlinkat:
5851
        {
5852
            void *p2;
5853
            p  = lock_user_string(arg2);
5854
            p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
5855
            if (!p || !p2)
5856
                ret = -TARGET_EFAULT;
5857
            else
5858
                ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
5859
            unlock_user(p2, arg3, ret);
5860
            unlock_user(p, arg2, 0);
5861
        }
5862
        break;
5863
#endif
5864
#ifdef TARGET_NR_uselib
5865
    case TARGET_NR_uselib:
5866
        goto unimplemented;
5867
#endif
5868
#ifdef TARGET_NR_swapon
5869
    case TARGET_NR_swapon:
5870
        if (!(p = lock_user_string(arg1)))
5871
            goto efault;
5872
        ret = get_errno(swapon(p, arg2));
5873
        unlock_user(p, arg1, 0);
5874
        break;
5875
#endif
5876
    case TARGET_NR_reboot:
5877
        if (!(p = lock_user_string(arg4)))
5878
            goto efault;
5879
        ret = reboot(arg1, arg2, arg3, p);
5880
        unlock_user(p, arg4, 0);
5881
        break;
5882
#ifdef TARGET_NR_readdir
5883
    case TARGET_NR_readdir:
5884
        goto unimplemented;
5885
#endif
5886
#ifdef TARGET_NR_mmap
5887
    case TARGET_NR_mmap:
5888
#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || \
5889
    defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) \
5890
    || defined(TARGET_S390X)
5891
        {
5892
            abi_ulong *v;
5893
            abi_ulong v1, v2, v3, v4, v5, v6;
5894
            if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
5895
                goto efault;
5896
            v1 = tswapal(v[0]);
5897
            v2 = tswapal(v[1]);
5898
            v3 = tswapal(v[2]);
5899
            v4 = tswapal(v[3]);
5900
            v5 = tswapal(v[4]);
5901
            v6 = tswapal(v[5]);
5902
            unlock_user(v, arg1, 0);
5903
            ret = get_errno(target_mmap(v1, v2, v3,
5904
                                        target_to_host_bitmask(v4, mmap_flags_tbl),
5905
                                        v5, v6));
5906
        }
5907
#else
5908
        ret = get_errno(target_mmap(arg1, arg2, arg3,
5909
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
5910
                                    arg5,
5911
                                    arg6));
5912
#endif
5913
        break;
5914
#endif
5915
#ifdef TARGET_NR_mmap2
5916
    case TARGET_NR_mmap2:
5917
#ifndef MMAP_SHIFT
5918
#define MMAP_SHIFT 12
5919
#endif
5920
        ret = get_errno(target_mmap(arg1, arg2, arg3,
5921
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
5922
                                    arg5,
5923
                                    arg6 << MMAP_SHIFT));
5924
        break;
5925
#endif
5926
    case TARGET_NR_munmap:
5927
        ret = get_errno(target_munmap(arg1, arg2));
5928
        break;
5929
    case TARGET_NR_mprotect:
5930
        {
5931
            TaskState *ts = ((CPUState *)cpu_env)->opaque;
5932
            /* Special hack to detect libc making the stack executable.  */
5933
            if ((arg3 & PROT_GROWSDOWN)
5934
                && arg1 >= ts->info->stack_limit
5935
                && arg1 <= ts->info->start_stack) {
5936
                arg3 &= ~PROT_GROWSDOWN;
5937
                arg2 = arg2 + arg1 - ts->info->stack_limit;
5938
                arg1 = ts->info->stack_limit;
5939
            }
5940
        }
5941
        ret = get_errno(target_mprotect(arg1, arg2, arg3));
5942
        break;
5943
#ifdef TARGET_NR_mremap
5944
    case TARGET_NR_mremap:
5945
        ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
5946
        break;
5947
#endif
5948
        /* ??? msync/mlock/munlock are broken for softmmu.  */
5949
#ifdef TARGET_NR_msync
5950
    case TARGET_NR_msync:
5951
        ret = get_errno(msync(g2h(arg1), arg2, arg3));
5952
        break;
5953
#endif
5954
#ifdef TARGET_NR_mlock
5955
    case TARGET_NR_mlock:
5956
        ret = get_errno(mlock(g2h(arg1), arg2));
5957
        break;
5958
#endif
5959
#ifdef TARGET_NR_munlock
5960
    case TARGET_NR_munlock:
5961
        ret = get_errno(munlock(g2h(arg1), arg2));
5962
        break;
5963
#endif
5964
#ifdef TARGET_NR_mlockall
5965
    case TARGET_NR_mlockall:
5966
        ret = get_errno(mlockall(arg1));
5967
        break;
5968
#endif
5969
#ifdef TARGET_NR_munlockall
5970
    case TARGET_NR_munlockall:
5971
        ret = get_errno(munlockall());
5972
        break;
5973
#endif
5974
    case TARGET_NR_truncate:
5975
        if (!(p = lock_user_string(arg1)))
5976
            goto efault;
5977
        ret = get_errno(truncate(p, arg2));
5978
        unlock_user(p, arg1, 0);
5979
        break;
5980
    case TARGET_NR_ftruncate:
5981
        ret = get_errno(ftruncate(arg1, arg2));
5982
        break;
5983
    case TARGET_NR_fchmod:
5984
        ret = get_errno(fchmod(arg1, arg2));
5985
        break;
5986
#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
5987
    case TARGET_NR_fchmodat:
5988
        if (!(p = lock_user_string(arg2)))
5989
            goto efault;
5990
        ret = get_errno(sys_fchmodat(arg1, p, arg3));
5991
        unlock_user(p, arg2, 0);
5992
        break;
5993
#endif
5994
    case TARGET_NR_getpriority:
5995
        /* libc does special remapping of the return value of
5996
         * sys_getpriority() so it's just easiest to call
5997
         * sys_getpriority() directly rather than through libc. */
5998
        ret = get_errno(sys_getpriority(arg1, arg2));
5999
        break;
6000
    case TARGET_NR_setpriority:
6001
        ret = get_errno(setpriority(arg1, arg2, arg3));
6002
        break;
6003
#ifdef TARGET_NR_profil
6004
    case TARGET_NR_profil:
6005
        goto unimplemented;
6006
#endif
6007
    case TARGET_NR_statfs:
6008
        if (!(p = lock_user_string(arg1)))
6009
            goto efault;
6010
        ret = get_errno(statfs(path(p), &stfs));
6011
        unlock_user(p, arg1, 0);
6012
    convert_statfs:
6013
        if (!is_error(ret)) {
6014
            struct target_statfs *target_stfs;
6015

    
6016
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
6017
                goto efault;
6018
            __put_user(stfs.f_type, &target_stfs->f_type);
6019
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
6020
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
6021
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
6022
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
6023
            __put_user(stfs.f_files, &target_stfs->f_files);
6024
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
6025
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
6026
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
6027
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
6028
            unlock_user_struct(target_stfs, arg2, 1);
6029
        }
6030
        break;
6031
    case TARGET_NR_fstatfs:
6032
        ret = get_errno(fstatfs(arg1, &stfs));
6033
        goto convert_statfs;
6034
#ifdef TARGET_NR_statfs64
6035
    case TARGET_NR_statfs64:
6036
        if (!(p = lock_user_string(arg1)))
6037
            goto efault;
6038
        ret = get_errno(statfs(path(p), &stfs));
6039
        unlock_user(p, arg1, 0);
6040
    convert_statfs64:
6041
        if (!is_error(ret)) {
6042
            struct target_statfs64 *target_stfs;
6043

    
6044
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
6045
                goto efault;
6046
            __put_user(stfs.f_type, &target_stfs->f_type);
6047
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
6048
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
6049
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
6050
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
6051
            __put_user(stfs.f_files, &target_stfs->f_files);
6052
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
6053
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
6054
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
6055
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
6056
            unlock_user_struct(target_stfs, arg3, 1);
6057
        }
6058
        break;
6059
    case TARGET_NR_fstatfs64:
6060
        ret = get_errno(fstatfs(arg1, &stfs));
6061
        goto convert_statfs64;
6062
#endif
6063
#ifdef TARGET_NR_ioperm
6064
    case TARGET_NR_ioperm:
6065
        goto unimplemented;
6066
#endif
6067
#ifdef TARGET_NR_socketcall
6068
    case TARGET_NR_socketcall:
6069
        ret = do_socketcall(arg1, arg2);
6070
        break;
6071
#endif
6072
#ifdef TARGET_NR_accept
6073
    case TARGET_NR_accept:
6074
        ret = do_accept(arg1, arg2, arg3);
6075
        break;
6076
#endif
6077
#ifdef TARGET_NR_bind
6078
    case TARGET_NR_bind:
6079
        ret = do_bind(arg1, arg2, arg3);
6080
        break;
6081
#endif
6082
#ifdef TARGET_NR_connect
6083
    case TARGET_NR_connect:
6084
        ret = do_connect(arg1, arg2, arg3);
6085
        break;
6086
#endif
6087
#ifdef TARGET_NR_getpeername
6088
    case TARGET_NR_getpeername:
6089
        ret = do_getpeername(arg1, arg2, arg3);
6090
        break;
6091
#endif
6092
#ifdef TARGET_NR_getsockname
6093
    case TARGET_NR_getsockname:
6094
        ret = do_getsockname(arg1, arg2, arg3);
6095
        break;
6096
#endif
6097
#ifdef TARGET_NR_getsockopt
6098
    case TARGET_NR_getsockopt:
6099
        ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
6100
        break;
6101
#endif
6102
#ifdef TARGET_NR_listen
6103
    case TARGET_NR_listen:
6104
        ret = get_errno(listen(arg1, arg2));
6105
        break;
6106
#endif
6107
#ifdef TARGET_NR_recv
6108
    case TARGET_NR_recv:
6109
        ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
6110
        break;
6111
#endif
6112
#ifdef TARGET_NR_recvfrom
6113
    case TARGET_NR_recvfrom:
6114
        ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
6115
        break;
6116
#endif
6117
#ifdef TARGET_NR_recvmsg
6118
    case TARGET_NR_recvmsg:
6119
        ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
6120
        break;
6121
#endif
6122
#ifdef TARGET_NR_send
6123
    case TARGET_NR_send:
6124
        ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
6125
        break;
6126
#endif
6127
#ifdef TARGET_NR_sendmsg
6128
    case TARGET_NR_sendmsg:
6129
        ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
6130
        break;
6131
#endif
6132
#ifdef TARGET_NR_sendto
6133
    case TARGET_NR_sendto:
6134
        ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
6135
        break;
6136
#endif
6137
#ifdef TARGET_NR_shutdown
6138
    case TARGET_NR_shutdown:
6139
        ret = get_errno(shutdown(arg1, arg2));
6140
        break;
6141
#endif
6142
#ifdef TARGET_NR_socket
6143
    case TARGET_NR_socket:
6144
        ret = do_socket(arg1, arg2, arg3);
6145
        break;
6146
#endif
6147
#ifdef TARGET_NR_socketpair
6148
    case TARGET_NR_socketpair:
6149
        ret = do_socketpair(arg1, arg2, arg3, arg4);
6150
        break;
6151
#endif
6152
#ifdef TARGET_NR_setsockopt
6153
    case TARGET_NR_setsockopt:
6154
        ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
6155
        break;
6156
#endif
6157

    
6158
    case TARGET_NR_syslog:
6159
        if (!(p = lock_user_string(arg2)))
6160
            goto efault;
6161
        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
6162
        unlock_user(p, arg2, 0);
6163
        break;
6164

    
6165
    case TARGET_NR_setitimer:
6166
        {
6167
            struct itimerval value, ovalue, *pvalue;
6168

    
6169
            if (arg2) {
6170
                pvalue = &value;
6171
                if (copy_from_user_timeval(&pvalue->it_interval, arg2)
6172
                    || copy_from_user_timeval(&pvalue->it_value,
6173
                                              arg2 + sizeof(struct target_timeval)))
6174
                    goto efault;
6175
            } else {
6176
                pvalue = NULL;
6177
            }
6178
            ret = get_errno(setitimer(arg1, pvalue, &ovalue));
6179
            if (!is_error(ret) && arg3) {
6180
                if (copy_to_user_timeval(arg3,
6181
                                         &ovalue.it_interval)
6182
                    || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
6183
                                            &ovalue.it_value))
6184
                    goto efault;
6185
            }
6186
        }
6187
        break;
6188
    case TARGET_NR_getitimer:
6189
        {
6190
            struct itimerval value;
6191

    
6192
            ret = get_errno(getitimer(arg1, &value));
6193
            if (!is_error(ret) && arg2) {
6194
                if (copy_to_user_timeval(arg2,
6195
                                         &value.it_interval)
6196
                    || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
6197
                                            &value.it_value))
6198
                    goto efault;
6199
            }
6200
        }
6201
        break;
6202
    case TARGET_NR_stat:
6203
        if (!(p = lock_user_string(arg1)))
6204
            goto efault;
6205
        ret = get_errno(stat(path(p), &st));
6206
        unlock_user(p, arg1, 0);
6207
        goto do_stat;
6208
    case TARGET_NR_lstat:
6209
        if (!(p = lock_user_string(arg1)))
6210
            goto efault;
6211
        ret = get_errno(lstat(path(p), &st));
6212
        unlock_user(p, arg1, 0);
6213
        goto do_stat;
6214
    case TARGET_NR_fstat:
6215
        {
6216
            ret = get_errno(fstat(arg1, &st));
6217
        do_stat:
6218
            if (!is_error(ret)) {
6219
                struct target_stat *target_st;
6220

    
6221
                if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
6222
                    goto efault;
6223
                memset(target_st, 0, sizeof(*target_st));
6224
                __put_user(st.st_dev, &target_st->st_dev);
6225
                __put_user(st.st_ino, &target_st->st_ino);
6226
                __put_user(st.st_mode, &target_st->st_mode);
6227
                __put_user(st.st_uid, &target_st->st_uid);
6228
                __put_user(st.st_gid, &target_st->st_gid);
6229
                __put_user(st.st_nlink, &target_st->st_nlink);
6230
                __put_user(st.st_rdev, &target_st->st_rdev);
6231
                __put_user(st.st_size, &target_st->st_size);
6232
                __put_user(st.st_blksize, &target_st->st_blksize);
6233
                __put_user(st.st_blocks, &target_st->st_blocks);
6234
                __put_user(st.st_atime, &target_st->target_st_atime);
6235
                __put_user(st.st_mtime, &target_st->target_st_mtime);
6236
                __put_user(st.st_ctime, &target_st->target_st_ctime);
6237
                unlock_user_struct(target_st, arg2, 1);
6238
            }
6239
        }
6240
        break;
6241
#ifdef TARGET_NR_olduname
6242
    case TARGET_NR_olduname:
6243
        goto unimplemented;
6244
#endif
6245
#ifdef TARGET_NR_iopl
6246
    case TARGET_NR_iopl:
6247
        goto unimplemented;
6248
#endif
6249
    case TARGET_NR_vhangup:
6250
        ret = get_errno(vhangup());
6251
        break;
6252
#ifdef TARGET_NR_idle
6253
    case TARGET_NR_idle:
6254
        goto unimplemented;
6255
#endif
6256
#ifdef TARGET_NR_syscall
6257
    case TARGET_NR_syscall:
6258
        ret = do_syscall(cpu_env, arg1 & 0xffff, arg2, arg3, arg4, arg5,
6259
                         arg6, arg7, arg8, 0);
6260
        break;
6261
#endif
6262
    case TARGET_NR_wait4:
6263
        {
6264
            int status;
6265
            abi_long status_ptr = arg2;
6266
            struct rusage rusage, *rusage_ptr;
6267
            abi_ulong target_rusage = arg4;
6268
            if (target_rusage)
6269
                rusage_ptr = &rusage;
6270
            else
6271
                rusage_ptr = NULL;
6272
            ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
6273
            if (!is_error(ret)) {
6274
                if (status_ptr) {
6275
                    status = host_to_target_waitstatus(status);
6276
                    if (put_user_s32(status, status_ptr))
6277
                        goto efault;
6278
                }
6279
                if (target_rusage)
6280
                    host_to_target_rusage(target_rusage, &rusage);
6281
            }
6282
        }
6283
        break;
6284
#ifdef TARGET_NR_swapoff
6285
    case TARGET_NR_swapoff:
6286
        if (!(p = lock_user_string(arg1)))
6287
            goto efault;
6288
        ret = get_errno(swapoff(p));
6289
        unlock_user(p, arg1, 0);
6290
        break;
6291
#endif
6292
    case TARGET_NR_sysinfo:
6293
        {
6294
            struct target_sysinfo *target_value;
6295
            struct sysinfo value;
6296
            ret = get_errno(sysinfo(&value));
6297
            if (!is_error(ret) && arg1)
6298
            {
6299
                if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
6300
                    goto efault;
6301
                __put_user(value.uptime, &target_value->uptime);
6302
                __put_user(value.loads[0], &target_value->loads[0]);
6303
                __put_user(value.loads[1], &target_value->loads[1]);
6304
                __put_user(value.loads[2], &target_value->loads[2]);
6305
                __put_user(value.totalram, &target_value->totalram);
6306
                __put_user(value.freeram, &target_value->freeram);
6307
                __put_user(value.sharedram, &target_value->sharedram);
6308
                __put_user(value.bufferram, &target_value->bufferram);
6309
                __put_user(value.totalswap, &target_value->totalswap);
6310
                __put_user(value.freeswap, &target_value->freeswap);
6311
                __put_user(value.procs, &target_value->procs);
6312
                __put_user(value.totalhigh, &target_value->totalhigh);
6313
                __put_user(value.freehigh, &target_value->freehigh);
6314
                __put_user(value.mem_unit, &target_value->mem_unit);
6315
                unlock_user_struct(target_value, arg1, 1);
6316
            }
6317
        }
6318
        break;
6319
#ifdef TARGET_NR_ipc
6320
    case TARGET_NR_ipc:
6321
        ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
6322
        break;
6323
#endif
6324
#ifdef TARGET_NR_semget
6325
    case TARGET_NR_semget:
6326
        ret = get_errno(semget(arg1, arg2, arg3));
6327
        break;
6328
#endif
6329
#ifdef TARGET_NR_semop
6330
    case TARGET_NR_semop:
6331
        ret = get_errno(do_semop(arg1, arg2, arg3));
6332
        break;
6333
#endif
6334
#ifdef TARGET_NR_semctl
6335
    case TARGET_NR_semctl:
6336
        ret = do_semctl(arg1, arg2, arg3, (union target_semun)(abi_ulong)arg4);
6337
        break;
6338
#endif
6339
#ifdef TARGET_NR_msgctl
6340
    case TARGET_NR_msgctl:
6341
        ret = do_msgctl(arg1, arg2, arg3);
6342
        break;
6343
#endif
6344
#ifdef TARGET_NR_msgget
6345
    case TARGET_NR_msgget:
6346
        ret = get_errno(msgget(arg1, arg2));
6347
        break;
6348
#endif
6349
#ifdef TARGET_NR_msgrcv
6350
    case TARGET_NR_msgrcv:
6351
        ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
6352
        break;
6353
#endif
6354
#ifdef TARGET_NR_msgsnd
6355
    case TARGET_NR_msgsnd:
6356
        ret = do_msgsnd(arg1, arg2, arg3, arg4);
6357
        break;
6358
#endif
6359
#ifdef TARGET_NR_shmget
6360
    case TARGET_NR_shmget:
6361
        ret = get_errno(shmget(arg1, arg2, arg3));
6362
        break;
6363
#endif
6364
#ifdef TARGET_NR_shmctl
6365
    case TARGET_NR_shmctl:
6366
        ret = do_shmctl(arg1, arg2, arg3);
6367
        break;
6368
#endif
6369
#ifdef TARGET_NR_shmat
6370
    case TARGET_NR_shmat:
6371
        ret = do_shmat(arg1, arg2, arg3);
6372
        break;
6373
#endif
6374
#ifdef TARGET_NR_shmdt
6375
    case TARGET_NR_shmdt:
6376
        ret = do_shmdt(arg1);
6377
        break;
6378
#endif
6379
    case TARGET_NR_fsync:
6380
        ret = get_errno(fsync(arg1));
6381
        break;
6382
    case TARGET_NR_clone:
6383
#if defined(TARGET_SH4) || defined(TARGET_ALPHA)
6384
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
6385
#elif defined(TARGET_CRIS)
6386
        ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg4, arg5));
6387
#elif defined(TARGET_S390X)
6388
        ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg5, arg4));
6389
#else
6390
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
6391
#endif
6392
        break;
6393
#ifdef __NR_exit_group
6394
        /* new thread calls */
6395
    case TARGET_NR_exit_group:
6396
#ifdef TARGET_GPROF
6397
        _mcleanup();
6398
#endif
6399
        gdb_exit(cpu_env, arg1);
6400
        ret = get_errno(exit_group(arg1));
6401
        break;
6402
#endif
6403
    case TARGET_NR_setdomainname:
6404
        if (!(p = lock_user_string(arg1)))
6405
            goto efault;
6406
        ret = get_errno(setdomainname(p, arg2));
6407
        unlock_user(p, arg1, 0);
6408
        break;
6409
    case TARGET_NR_uname:
6410
        /* no need to transcode because we use the linux syscall */
6411
        {
6412
            struct new_utsname * buf;
6413

    
6414
            if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
6415
                goto efault;
6416
            ret = get_errno(sys_uname(buf));
6417
            if (!is_error(ret)) {
6418
                /* Overrite the native machine name with whatever is being
6419
                   emulated. */
6420
                strcpy (buf->machine, cpu_to_uname_machine(cpu_env));
6421
                /* Allow the user to override the reported release.  */
6422
                if (qemu_uname_release && *qemu_uname_release)
6423
                  strcpy (buf->release, qemu_uname_release);
6424
            }
6425
            unlock_user_struct(buf, arg1, 1);
6426
        }
6427
        break;
6428
#ifdef TARGET_I386
6429
    case TARGET_NR_modify_ldt:
6430
        ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
6431
        break;
6432
#if !defined(TARGET_X86_64)
6433
    case TARGET_NR_vm86old:
6434
        goto unimplemented;
6435
    case TARGET_NR_vm86:
6436
        ret = do_vm86(cpu_env, arg1, arg2);
6437
        break;
6438
#endif
6439
#endif
6440
    case TARGET_NR_adjtimex:
6441
        goto unimplemented;
6442
#ifdef TARGET_NR_create_module
6443
    case TARGET_NR_create_module:
6444
#endif
6445
    case TARGET_NR_init_module:
6446
    case TARGET_NR_delete_module:
6447
#ifdef TARGET_NR_get_kernel_syms
6448
    case TARGET_NR_get_kernel_syms:
6449
#endif
6450
        goto unimplemented;
6451
    case TARGET_NR_quotactl:
6452
        goto unimplemented;
6453
    case TARGET_NR_getpgid:
6454
        ret = get_errno(getpgid(arg1));
6455
        break;
6456
    case TARGET_NR_fchdir:
6457
        ret = get_errno(fchdir(arg1));
6458
        break;
6459
#ifdef TARGET_NR_bdflush /* not on x86_64 */
6460
    case TARGET_NR_bdflush:
6461
        goto unimplemented;
6462
#endif
6463
#ifdef TARGET_NR_sysfs
6464
    case TARGET_NR_sysfs:
6465
        goto unimplemented;
6466
#endif
6467
    case TARGET_NR_personality:
6468
        ret = get_errno(personality(arg1));
6469
        break;
6470
#ifdef TARGET_NR_afs_syscall
6471
    case TARGET_NR_afs_syscall:
6472
        goto unimplemented;
6473
#endif
6474
#ifdef TARGET_NR__llseek /* Not on alpha */
6475
    case TARGET_NR__llseek:
6476
        {
6477
            int64_t res;
6478
#if !defined(__NR_llseek)
6479
            res = lseek(arg1, ((uint64_t)arg2 << 32) | arg3, arg5);
6480
            if (res == -1) {
6481
                ret = get_errno(res);
6482
            } else {
6483
                ret = 0;
6484
            }
6485
#else
6486
            ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
6487
#endif
6488
            if ((ret == 0) && put_user_s64(res, arg4)) {
6489
                goto efault;
6490
            }
6491
        }
6492
        break;
6493
#endif
6494
    case TARGET_NR_getdents:
6495
#if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
6496
        {
6497
            struct target_dirent *target_dirp;
6498
            struct linux_dirent *dirp;
6499
            abi_long count = arg3;
6500

    
6501
            dirp = malloc(count);
6502
            if (!dirp) {
6503
                ret = -TARGET_ENOMEM;
6504
                goto fail;
6505
            }
6506

    
6507
            ret = get_errno(sys_getdents(arg1, dirp, count));
6508
            if (!is_error(ret)) {
6509
                struct linux_dirent *de;
6510
                struct target_dirent *tde;
6511
                int len = ret;
6512
                int reclen, treclen;
6513
                int count1, tnamelen;
6514

    
6515
                count1 = 0;
6516
                de = dirp;
6517
                if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
6518
                    goto efault;
6519
                tde = target_dirp;
6520
                while (len > 0) {
6521
                    reclen = de->d_reclen;
6522
                    treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
6523
                    tde->d_reclen = tswap16(treclen);
6524
                    tde->d_ino = tswapal(de->d_ino);
6525
                    tde->d_off = tswapal(de->d_off);
6526
                    tnamelen = treclen - (2 * sizeof(abi_long) + 2);
6527
                    if (tnamelen > 256)
6528
                        tnamelen = 256;
6529
                    /* XXX: may not be correct */
6530
                    pstrcpy(tde->d_name, tnamelen, de->d_name);
6531
                    de = (struct linux_dirent *)((char *)de + reclen);
6532
                    len -= reclen;
6533
                    tde = (struct target_dirent *)((char *)tde + treclen);
6534
                    count1 += treclen;
6535
                }
6536
                ret = count1;
6537
                unlock_user(target_dirp, arg2, ret);
6538
            }
6539
            free(dirp);
6540
        }
6541
#else
6542
        {
6543
            struct linux_dirent *dirp;
6544
            abi_long count = arg3;
6545

    
6546
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
6547
                goto efault;
6548
            ret = get_errno(sys_getdents(arg1, dirp, count));
6549
            if (!is_error(ret)) {
6550
                struct linux_dirent *de;
6551
                int len = ret;
6552
                int reclen;
6553
                de = dirp;
6554
                while (len > 0) {
6555
                    reclen = de->d_reclen;
6556
                    if (reclen > len)
6557
                        break;
6558
                    de->d_reclen = tswap16(reclen);
6559
                    tswapls(&de->d_ino);
6560
                    tswapls(&de->d_off);
6561
                    de = (struct linux_dirent *)((char *)de + reclen);
6562
                    len -= reclen;
6563
                }
6564
            }
6565
            unlock_user(dirp, arg2, ret);
6566
        }
6567
#endif
6568
        break;
6569
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
6570
    case TARGET_NR_getdents64:
6571
        {
6572
            struct linux_dirent64 *dirp;
6573
            abi_long count = arg3;
6574
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
6575
                goto efault;
6576
            ret = get_errno(sys_getdents64(arg1, dirp, count));
6577
            if (!is_error(ret)) {
6578
                struct linux_dirent64 *de;
6579
                int len = ret;
6580
                int reclen;
6581
                de = dirp;
6582
                while (len > 0) {
6583
                    reclen = de->d_reclen;
6584
                    if (reclen > len)
6585
                        break;
6586
                    de->d_reclen = tswap16(reclen);
6587
                    tswap64s((uint64_t *)&de->d_ino);
6588
                    tswap64s((uint64_t *)&de->d_off);
6589
                    de = (struct linux_dirent64 *)((char *)de + reclen);
6590
                    len -= reclen;
6591
                }
6592
            }
6593
            unlock_user(dirp, arg2, ret);
6594
        }
6595
        break;
6596
#endif /* TARGET_NR_getdents64 */
6597
#if defined(TARGET_NR__newselect) || defined(TARGET_S390X)
6598
#ifdef TARGET_S390X
6599
    case TARGET_NR_select:
6600
#else
6601
    case TARGET_NR__newselect:
6602
#endif
6603
        ret = do_select(arg1, arg2, arg3, arg4, arg5);
6604
        break;
6605
#endif
6606
#if defined(TARGET_NR_poll) || defined(TARGET_NR_ppoll)
6607
# ifdef TARGET_NR_poll
6608
    case TARGET_NR_poll:
6609
# endif
6610
# ifdef TARGET_NR_ppoll
6611
    case TARGET_NR_ppoll:
6612
# endif
6613
        {
6614
            struct target_pollfd *target_pfd;
6615
            unsigned int nfds = arg2;
6616
            int timeout = arg3;
6617
            struct pollfd *pfd;
6618
            unsigned int i;
6619

    
6620
            target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
6621
            if (!target_pfd)
6622
                goto efault;
6623

    
6624
            pfd = alloca(sizeof(struct pollfd) * nfds);
6625
            for(i = 0; i < nfds; i++) {
6626
                pfd[i].fd = tswap32(target_pfd[i].fd);
6627
                pfd[i].events = tswap16(target_pfd[i].events);
6628
            }
6629

    
6630
# ifdef TARGET_NR_ppoll
6631
            if (num == TARGET_NR_ppoll) {
6632
                struct timespec _timeout_ts, *timeout_ts = &_timeout_ts;
6633
                target_sigset_t *target_set;
6634
                sigset_t _set, *set = &_set;
6635

    
6636
                if (arg3) {
6637
                    if (target_to_host_timespec(timeout_ts, arg3)) {
6638
                        unlock_user(target_pfd, arg1, 0);
6639
                        goto efault;
6640
                    }
6641
                } else {
6642
                    timeout_ts = NULL;
6643
                }
6644

    
6645
                if (arg4) {
6646
                    target_set = lock_user(VERIFY_READ, arg4, sizeof(target_sigset_t), 1);
6647
                    if (!target_set) {
6648
                        unlock_user(target_pfd, arg1, 0);
6649
                        goto efault;
6650
                    }
6651
                    target_to_host_sigset(set, target_set);
6652
                } else {
6653
                    set = NULL;
6654
                }
6655

    
6656
                ret = get_errno(sys_ppoll(pfd, nfds, timeout_ts, set, _NSIG/8));
6657

    
6658
                if (!is_error(ret) && arg3) {
6659
                    host_to_target_timespec(arg3, timeout_ts);
6660
                }
6661
                if (arg4) {
6662
                    unlock_user(target_set, arg4, 0);
6663
                }
6664
            } else
6665
# endif
6666
                ret = get_errno(poll(pfd, nfds, timeout));
6667

    
6668
            if (!is_error(ret)) {
6669
                for(i = 0; i < nfds; i++) {
6670
                    target_pfd[i].revents = tswap16(pfd[i].revents);
6671
                }
6672
            }
6673
            unlock_user(target_pfd, arg1, sizeof(struct target_pollfd) * nfds);
6674
        }
6675
        break;
6676
#endif
6677
    case TARGET_NR_flock:
6678
        /* NOTE: the flock constant seems to be the same for every
6679
           Linux platform */
6680
        ret = get_errno(flock(arg1, arg2));
6681
        break;
6682
    case TARGET_NR_readv:
6683
        {
6684
            int count = arg3;
6685
            struct iovec *vec;
6686

    
6687
            vec = alloca(count * sizeof(struct iovec));
6688
            if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
6689
                goto efault;
6690
            ret = get_errno(readv(arg1, vec, count));
6691
            unlock_iovec(vec, arg2, count, 1);
6692
        }
6693
        break;
6694
    case TARGET_NR_writev:
6695
        {
6696
            int count = arg3;
6697
            struct iovec *vec;
6698

    
6699
            vec = alloca(count * sizeof(struct iovec));
6700
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
6701
                goto efault;
6702
            ret = get_errno(writev(arg1, vec, count));
6703
            unlock_iovec(vec, arg2, count, 0);
6704
        }
6705
        break;
6706
    case TARGET_NR_getsid:
6707
        ret = get_errno(getsid(arg1));
6708
        break;
6709
#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
6710
    case TARGET_NR_fdatasync:
6711
        ret = get_errno(fdatasync(arg1));
6712
        break;
6713
#endif
6714
    case TARGET_NR__sysctl:
6715
        /* We don't implement this, but ENOTDIR is always a safe
6716
           return value. */
6717
        ret = -TARGET_ENOTDIR;
6718
        break;
6719
    case TARGET_NR_sched_getaffinity:
6720
        {
6721
            unsigned int mask_size;
6722
            unsigned long *mask;
6723

    
6724
            /*
6725
             * sched_getaffinity needs multiples of ulong, so need to take
6726
             * care of mismatches between target ulong and host ulong sizes.
6727
             */
6728
            if (arg2 & (sizeof(abi_ulong) - 1)) {
6729
                ret = -TARGET_EINVAL;
6730
                break;
6731
            }
6732
            mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
6733

    
6734
            mask = alloca(mask_size);
6735
            ret = get_errno(sys_sched_getaffinity(arg1, mask_size, mask));
6736

    
6737
            if (!is_error(ret)) {
6738
                if (copy_to_user(arg3, mask, ret)) {
6739
                    goto efault;
6740
                }
6741
            }
6742
        }
6743
        break;
6744
    case TARGET_NR_sched_setaffinity:
6745
        {
6746
            unsigned int mask_size;
6747
            unsigned long *mask;
6748

    
6749
            /*
6750
             * sched_setaffinity needs multiples of ulong, so need to take
6751
             * care of mismatches between target ulong and host ulong sizes.
6752
             */
6753
            if (arg2 & (sizeof(abi_ulong) - 1)) {
6754
                ret = -TARGET_EINVAL;
6755
                break;
6756
            }
6757
            mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
6758

    
6759
            mask = alloca(mask_size);
6760
            if (!lock_user_struct(VERIFY_READ, p, arg3, 1)) {
6761
                goto efault;
6762
            }
6763
            memcpy(mask, p, arg2);
6764
            unlock_user_struct(p, arg2, 0);
6765

    
6766
            ret = get_errno(sys_sched_setaffinity(arg1, mask_size, mask));
6767
        }
6768
        break;
6769
    case TARGET_NR_sched_setparam:
6770
        {
6771
            struct sched_param *target_schp;
6772
            struct sched_param schp;
6773

    
6774
            if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
6775
                goto efault;
6776
            schp.sched_priority = tswap32(target_schp->sched_priority);
6777
            unlock_user_struct(target_schp, arg2, 0);
6778
            ret = get_errno(sched_setparam(arg1, &schp));
6779
        }
6780
        break;
6781
    case TARGET_NR_sched_getparam:
6782
        {
6783
            struct sched_param *target_schp;
6784
            struct sched_param schp;
6785
            ret = get_errno(sched_getparam(arg1, &schp));
6786
            if (!is_error(ret)) {
6787
                if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
6788
                    goto efault;
6789
                target_schp->sched_priority = tswap32(schp.sched_priority);
6790
                unlock_user_struct(target_schp, arg2, 1);
6791
            }
6792
        }
6793
        break;
6794
    case TARGET_NR_sched_setscheduler:
6795
        {
6796
            struct sched_param *target_schp;
6797
            struct sched_param schp;
6798
            if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
6799
                goto efault;
6800
            schp.sched_priority = tswap32(target_schp->sched_priority);
6801
            unlock_user_struct(target_schp, arg3, 0);
6802
            ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
6803
        }
6804
        break;
6805
    case TARGET_NR_sched_getscheduler:
6806
        ret = get_errno(sched_getscheduler(arg1));
6807
        break;
6808
    case TARGET_NR_sched_yield:
6809
        ret = get_errno(sched_yield());
6810
        break;
6811
    case TARGET_NR_sched_get_priority_max:
6812
        ret = get_errno(sched_get_priority_max(arg1));
6813
        break;
6814
    case TARGET_NR_sched_get_priority_min:
6815
        ret = get_errno(sched_get_priority_min(arg1));
6816
        break;
6817
    case TARGET_NR_sched_rr_get_interval:
6818
        {
6819
            struct timespec ts;
6820
            ret = get_errno(sched_rr_get_interval(arg1, &ts));
6821
            if (!is_error(ret)) {
6822
                host_to_target_timespec(arg2, &ts);
6823
            }
6824
        }
6825
        break;
6826
    case TARGET_NR_nanosleep:
6827
        {
6828
            struct timespec req, rem;
6829
            target_to_host_timespec(&req, arg1);
6830
            ret = get_errno(nanosleep(&req, &rem));
6831
            if (is_error(ret) && arg2) {
6832
                host_to_target_timespec(arg2, &rem);
6833
            }
6834
        }
6835
        break;
6836
#ifdef TARGET_NR_query_module
6837
    case TARGET_NR_query_module:
6838
        goto unimplemented;
6839
#endif
6840
#ifdef TARGET_NR_nfsservctl
6841
    case TARGET_NR_nfsservctl:
6842
        goto unimplemented;
6843
#endif
6844
    case TARGET_NR_prctl:
6845
        switch (arg1)
6846
            {
6847
            case PR_GET_PDEATHSIG:
6848
                {
6849
                    int deathsig;
6850
                    ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
6851
                    if (!is_error(ret) && arg2
6852
                        && put_user_ual(deathsig, arg2))
6853
                        goto efault;
6854
                }
6855
                break;
6856
            default:
6857
                ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
6858
                break;
6859
            }
6860
        break;
6861
#ifdef TARGET_NR_arch_prctl
6862
    case TARGET_NR_arch_prctl:
6863
#if defined(TARGET_I386) && !defined(TARGET_ABI32)
6864
        ret = do_arch_prctl(cpu_env, arg1, arg2);
6865
        break;
6866
#else
6867
        goto unimplemented;
6868
#endif
6869
#endif
6870
#ifdef TARGET_NR_pread
6871
    case TARGET_NR_pread:
6872
        if (regpairs_aligned(cpu_env))
6873
            arg4 = arg5;
6874
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
6875
            goto efault;
6876
        ret = get_errno(pread(arg1, p, arg3, arg4));
6877
        unlock_user(p, arg2, ret);
6878
        break;
6879
    case TARGET_NR_pwrite:
6880
        if (regpairs_aligned(cpu_env))
6881
            arg4 = arg5;
6882
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
6883
            goto efault;
6884
        ret = get_errno(pwrite(arg1, p, arg3, arg4));
6885
        unlock_user(p, arg2, 0);
6886
        break;
6887
#endif
6888
#ifdef TARGET_NR_pread64
6889
    case TARGET_NR_pread64:
6890
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
6891
            goto efault;
6892
        ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
6893
        unlock_user(p, arg2, ret);
6894
        break;
6895
    case TARGET_NR_pwrite64:
6896
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
6897
            goto efault;
6898
        ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
6899
        unlock_user(p, arg2, 0);
6900
        break;
6901
#endif
6902
    case TARGET_NR_getcwd:
6903
        if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
6904
            goto efault;
6905
        ret = get_errno(sys_getcwd1(p, arg2));
6906
        unlock_user(p, arg1, ret);
6907
        break;
6908
    case TARGET_NR_capget:
6909
        goto unimplemented;
6910
    case TARGET_NR_capset:
6911
        goto unimplemented;
6912
    case TARGET_NR_sigaltstack:
6913
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
6914
    defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA) || \
6915
    defined(TARGET_M68K) || defined(TARGET_S390X)
6916
        ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env));
6917
        break;
6918
#else
6919
        goto unimplemented;
6920
#endif
6921
    case TARGET_NR_sendfile:
6922
        goto unimplemented;
6923
#ifdef TARGET_NR_getpmsg
6924
    case TARGET_NR_getpmsg:
6925
        goto unimplemented;
6926
#endif
6927
#ifdef TARGET_NR_putpmsg
6928
    case TARGET_NR_putpmsg:
6929
        goto unimplemented;
6930
#endif
6931
#ifdef TARGET_NR_vfork
6932
    case TARGET_NR_vfork:
6933
        ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
6934
                        0, 0, 0, 0));
6935
        break;
6936
#endif
6937
#ifdef TARGET_NR_ugetrlimit
6938
    case TARGET_NR_ugetrlimit:
6939
    {
6940
        struct rlimit rlim;
6941
        int resource = target_to_host_resource(arg1);
6942
        ret = get_errno(getrlimit(resource, &rlim));
6943
        if (!is_error(ret)) {
6944
            struct target_rlimit *target_rlim;
6945
            if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
6946
                goto efault;
6947
            target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
6948
            target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
6949
            unlock_user_struct(target_rlim, arg2, 1);
6950
        }
6951
        break;
6952
    }
6953
#endif
6954
#ifdef TARGET_NR_truncate64
6955
    case TARGET_NR_truncate64:
6956
        if (!(p = lock_user_string(arg1)))
6957
            goto efault;
6958
        ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
6959
        unlock_user(p, arg1, 0);
6960
        break;
6961
#endif
6962
#ifdef TARGET_NR_ftruncate64
6963
    case TARGET_NR_ftruncate64:
6964
        ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
6965
        break;
6966
#endif
6967
#ifdef TARGET_NR_stat64
6968
    case TARGET_NR_stat64:
6969
        if (!(p = lock_user_string(arg1)))
6970
            goto efault;
6971
        ret = get_errno(stat(path(p), &st));
6972
        unlock_user(p, arg1, 0);
6973
        if (!is_error(ret))
6974
            ret = host_to_target_stat64(cpu_env, arg2, &st);
6975
        break;
6976
#endif
6977
#ifdef TARGET_NR_lstat64
6978
    case TARGET_NR_lstat64:
6979
        if (!(p = lock_user_string(arg1)))
6980
            goto efault;
6981
        ret = get_errno(lstat(path(p), &st));
6982
        unlock_user(p, arg1, 0);
6983
        if (!is_error(ret))
6984
            ret = host_to_target_stat64(cpu_env, arg2, &st);
6985
        break;
6986
#endif
6987
#ifdef TARGET_NR_fstat64
6988
    case TARGET_NR_fstat64:
6989
        ret = get_errno(fstat(arg1, &st));
6990
        if (!is_error(ret))
6991
            ret = host_to_target_stat64(cpu_env, arg2, &st);
6992
        break;
6993
#endif
6994
#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
6995
        (defined(__NR_fstatat64) || defined(__NR_newfstatat))
6996
#ifdef TARGET_NR_fstatat64
6997
    case TARGET_NR_fstatat64:
6998
#endif
6999
#ifdef TARGET_NR_newfstatat
7000
    case TARGET_NR_newfstatat:
7001
#endif
7002
        if (!(p = lock_user_string(arg2)))
7003
            goto efault;
7004
#ifdef __NR_fstatat64
7005
        ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
7006
#else
7007
        ret = get_errno(sys_newfstatat(arg1, path(p), &st, arg4));
7008
#endif
7009
        if (!is_error(ret))
7010
            ret = host_to_target_stat64(cpu_env, arg3, &st);
7011
        break;
7012
#endif
7013
    case TARGET_NR_lchown:
7014
        if (!(p = lock_user_string(arg1)))
7015
            goto efault;
7016
        ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
7017
        unlock_user(p, arg1, 0);
7018
        break;
7019
#ifdef TARGET_NR_getuid
7020
    case TARGET_NR_getuid:
7021
        ret = get_errno(high2lowuid(getuid()));
7022
        break;
7023
#endif
7024
#ifdef TARGET_NR_getgid
7025
    case TARGET_NR_getgid:
7026
        ret = get_errno(high2lowgid(getgid()));
7027
        break;
7028
#endif
7029
#ifdef TARGET_NR_geteuid
7030
    case TARGET_NR_geteuid:
7031
        ret = get_errno(high2lowuid(geteuid()));
7032
        break;
7033
#endif
7034
#ifdef TARGET_NR_getegid
7035
    case TARGET_NR_getegid:
7036
        ret = get_errno(high2lowgid(getegid()));
7037
        break;
7038
#endif
7039
    case TARGET_NR_setreuid:
7040
        ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
7041
        break;
7042
    case TARGET_NR_setregid:
7043
        ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
7044
        break;
7045
    case TARGET_NR_getgroups:
7046
        {
7047
            int gidsetsize = arg1;
7048
            target_id *target_grouplist;
7049
            gid_t *grouplist;
7050
            int i;
7051

    
7052
            grouplist = alloca(gidsetsize * sizeof(gid_t));
7053
            ret = get_errno(getgroups(gidsetsize, grouplist));
7054
            if (gidsetsize == 0)
7055
                break;
7056
            if (!is_error(ret)) {
7057
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
7058
                if (!target_grouplist)
7059
                    goto efault;
7060
                for(i = 0;i < ret; i++)
7061
                    target_grouplist[i] = tswapid(high2lowgid(grouplist[i]));
7062
                unlock_user(target_grouplist, arg2, gidsetsize * 2);
7063
            }
7064
        }
7065
        break;
7066
    case TARGET_NR_setgroups:
7067
        {
7068
            int gidsetsize = arg1;
7069
            target_id *target_grouplist;
7070
            gid_t *grouplist;
7071
            int i;
7072

    
7073
            grouplist = alloca(gidsetsize * sizeof(gid_t));
7074
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
7075
            if (!target_grouplist) {
7076
                ret = -TARGET_EFAULT;
7077
                goto fail;
7078
            }
7079
            for(i = 0;i < gidsetsize; i++)
7080
                grouplist[i] = low2highgid(tswapid(target_grouplist[i]));
7081
            unlock_user(target_grouplist, arg2, 0);
7082
            ret = get_errno(setgroups(gidsetsize, grouplist));
7083
        }
7084
        break;
7085
    case TARGET_NR_fchown:
7086
        ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
7087
        break;
7088
#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
7089
    case TARGET_NR_fchownat:
7090
        if (!(p = lock_user_string(arg2))) 
7091
            goto efault;
7092
        ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
7093
        unlock_user(p, arg2, 0);
7094
        break;
7095
#endif
7096
#ifdef TARGET_NR_setresuid
7097
    case TARGET_NR_setresuid:
7098
        ret = get_errno(setresuid(low2highuid(arg1),
7099
                                  low2highuid(arg2),
7100
                                  low2highuid(arg3)));
7101
        break;
7102
#endif
7103
#ifdef TARGET_NR_getresuid
7104
    case TARGET_NR_getresuid:
7105
        {
7106
            uid_t ruid, euid, suid;
7107
            ret = get_errno(getresuid(&ruid, &euid, &suid));
7108
            if (!is_error(ret)) {
7109
                if (put_user_u16(high2lowuid(ruid), arg1)
7110
                    || put_user_u16(high2lowuid(euid), arg2)
7111
                    || put_user_u16(high2lowuid(suid), arg3))
7112
                    goto efault;
7113
            }
7114
        }
7115
        break;
7116
#endif
7117
#ifdef TARGET_NR_getresgid
7118
    case TARGET_NR_setresgid:
7119
        ret = get_errno(setresgid(low2highgid(arg1),
7120
                                  low2highgid(arg2),
7121
                                  low2highgid(arg3)));
7122
        break;
7123
#endif
7124
#ifdef TARGET_NR_getresgid
7125
    case TARGET_NR_getresgid:
7126
        {
7127
            gid_t rgid, egid, sgid;
7128
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
7129
            if (!is_error(ret)) {
7130
                if (put_user_u16(high2lowgid(rgid), arg1)
7131
                    || put_user_u16(high2lowgid(egid), arg2)
7132
                    || put_user_u16(high2lowgid(sgid), arg3))
7133
                    goto efault;
7134
            }
7135
        }
7136
        break;
7137
#endif
7138
    case TARGET_NR_chown:
7139
        if (!(p = lock_user_string(arg1)))
7140
            goto efault;
7141
        ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
7142
        unlock_user(p, arg1, 0);
7143
        break;
7144
    case TARGET_NR_setuid:
7145
        ret = get_errno(setuid(low2highuid(arg1)));
7146
        break;
7147
    case TARGET_NR_setgid:
7148
        ret = get_errno(setgid(low2highgid(arg1)));
7149
        break;
7150
    case TARGET_NR_setfsuid:
7151
        ret = get_errno(setfsuid(arg1));
7152
        break;
7153
    case TARGET_NR_setfsgid:
7154
        ret = get_errno(setfsgid(arg1));
7155
        break;
7156

    
7157
#ifdef TARGET_NR_lchown32
7158
    case TARGET_NR_lchown32:
7159
        if (!(p = lock_user_string(arg1)))
7160
            goto efault;
7161
        ret = get_errno(lchown(p, arg2, arg3));
7162
        unlock_user(p, arg1, 0);
7163
        break;
7164
#endif
7165
#ifdef TARGET_NR_getuid32
7166
    case TARGET_NR_getuid32:
7167
        ret = get_errno(getuid());
7168
        break;
7169
#endif
7170

    
7171
#if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
7172
   /* Alpha specific */
7173
    case TARGET_NR_getxuid:
7174
         {
7175
            uid_t euid;
7176
            euid=geteuid();
7177
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
7178
         }
7179
        ret = get_errno(getuid());
7180
        break;
7181
#endif
7182
#if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
7183
   /* Alpha specific */
7184
    case TARGET_NR_getxgid:
7185
         {
7186
            uid_t egid;
7187
            egid=getegid();
7188
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
7189
         }
7190
        ret = get_errno(getgid());
7191
        break;
7192
#endif
7193
#if defined(TARGET_NR_osf_getsysinfo) && defined(TARGET_ALPHA)
7194
    /* Alpha specific */
7195
    case TARGET_NR_osf_getsysinfo:
7196
        ret = -TARGET_EOPNOTSUPP;
7197
        switch (arg1) {
7198
          case TARGET_GSI_IEEE_FP_CONTROL:
7199
            {
7200
                uint64_t swcr, fpcr = cpu_alpha_load_fpcr (cpu_env);
7201

    
7202
                /* Copied from linux ieee_fpcr_to_swcr.  */
7203
                swcr = (fpcr >> 35) & SWCR_STATUS_MASK;
7204
                swcr |= (fpcr >> 36) & SWCR_MAP_DMZ;
7205
                swcr |= (~fpcr >> 48) & (SWCR_TRAP_ENABLE_INV
7206
                                        | SWCR_TRAP_ENABLE_DZE
7207
                                        | SWCR_TRAP_ENABLE_OVF);
7208
                swcr |= (~fpcr >> 57) & (SWCR_TRAP_ENABLE_UNF
7209
                                        | SWCR_TRAP_ENABLE_INE);
7210
                swcr |= (fpcr >> 47) & SWCR_MAP_UMZ;
7211
                swcr |= (~fpcr >> 41) & SWCR_TRAP_ENABLE_DNO;
7212

    
7213
                if (put_user_u64 (swcr, arg2))
7214
                        goto efault;
7215
                ret = 0;
7216
            }
7217
            break;
7218

    
7219
          /* case GSI_IEEE_STATE_AT_SIGNAL:
7220
             -- Not implemented in linux kernel.
7221
             case GSI_UACPROC:
7222
             -- Retrieves current unaligned access state; not much used.
7223
             case GSI_PROC_TYPE:
7224
             -- Retrieves implver information; surely not used.
7225
             case GSI_GET_HWRPB:
7226
             -- Grabs a copy of the HWRPB; surely not used.
7227
          */
7228
        }
7229
        break;
7230
#endif
7231
#if defined(TARGET_NR_osf_setsysinfo) && defined(TARGET_ALPHA)
7232
    /* Alpha specific */
7233
    case TARGET_NR_osf_setsysinfo:
7234
        ret = -TARGET_EOPNOTSUPP;
7235
        switch (arg1) {
7236
          case TARGET_SSI_IEEE_FP_CONTROL:
7237
          case TARGET_SSI_IEEE_RAISE_EXCEPTION:
7238
            {
7239
                uint64_t swcr, fpcr, orig_fpcr;
7240

    
7241
                if (get_user_u64 (swcr, arg2))
7242
                    goto efault;
7243
                orig_fpcr = cpu_alpha_load_fpcr (cpu_env);
7244
                fpcr = orig_fpcr & FPCR_DYN_MASK;
7245

    
7246
                /* Copied from linux ieee_swcr_to_fpcr.  */
7247
                fpcr |= (swcr & SWCR_STATUS_MASK) << 35;
7248
                fpcr |= (swcr & SWCR_MAP_DMZ) << 36;
7249
                fpcr |= (~swcr & (SWCR_TRAP_ENABLE_INV
7250
                                  | SWCR_TRAP_ENABLE_DZE
7251
                                  | SWCR_TRAP_ENABLE_OVF)) << 48;
7252
                fpcr |= (~swcr & (SWCR_TRAP_ENABLE_UNF
7253
                                  | SWCR_TRAP_ENABLE_INE)) << 57;
7254
                fpcr |= (swcr & SWCR_MAP_UMZ ? FPCR_UNDZ | FPCR_UNFD : 0);
7255
                fpcr |= (~swcr & SWCR_TRAP_ENABLE_DNO) << 41;
7256

    
7257
                cpu_alpha_store_fpcr (cpu_env, fpcr);
7258
                ret = 0;
7259

    
7260
                if (arg1 == TARGET_SSI_IEEE_RAISE_EXCEPTION) {
7261
                    /* Old exceptions are not signaled.  */
7262
                    fpcr &= ~(orig_fpcr & FPCR_STATUS_MASK);
7263

    
7264
                    /* If any exceptions set by this call, and are unmasked,
7265
                       send a signal.  */
7266
                    /* ??? FIXME */
7267
                }
7268
            }
7269
            break;
7270

    
7271
          /* case SSI_NVPAIRS:
7272
             -- Used with SSIN_UACPROC to enable unaligned accesses.
7273
             case SSI_IEEE_STATE_AT_SIGNAL:
7274
             case SSI_IEEE_IGNORE_STATE_AT_SIGNAL:
7275
             -- Not implemented in linux kernel
7276
          */
7277
        }
7278
        break;
7279
#endif
7280
#ifdef TARGET_NR_osf_sigprocmask
7281
    /* Alpha specific.  */
7282
    case TARGET_NR_osf_sigprocmask:
7283
        {
7284
            abi_ulong mask;
7285
            int how;
7286
            sigset_t set, oldset;
7287

    
7288
            switch(arg1) {
7289
            case TARGET_SIG_BLOCK:
7290
                how = SIG_BLOCK;
7291
                break;
7292
            case TARGET_SIG_UNBLOCK:
7293
                how = SIG_UNBLOCK;
7294
                break;
7295
            case TARGET_SIG_SETMASK:
7296
                how = SIG_SETMASK;
7297
                break;
7298
            default:
7299
                ret = -TARGET_EINVAL;
7300
                goto fail;
7301
            }
7302
            mask = arg2;
7303
            target_to_host_old_sigset(&set, &mask);
7304
            sigprocmask(how, &set, &oldset);
7305
            host_to_target_old_sigset(&mask, &oldset);
7306
            ret = mask;
7307
        }
7308
        break;
7309
#endif
7310

    
7311
#ifdef TARGET_NR_getgid32
7312
    case TARGET_NR_getgid32:
7313
        ret = get_errno(getgid());
7314
        break;
7315
#endif
7316
#ifdef TARGET_NR_geteuid32
7317
    case TARGET_NR_geteuid32:
7318
        ret = get_errno(geteuid());
7319
        break;
7320
#endif
7321
#ifdef TARGET_NR_getegid32
7322
    case TARGET_NR_getegid32:
7323
        ret = get_errno(getegid());
7324
        break;
7325
#endif
7326
#ifdef TARGET_NR_setreuid32
7327
    case TARGET_NR_setreuid32:
7328
        ret = get_errno(setreuid(arg1, arg2));
7329
        break;
7330
#endif
7331
#ifdef TARGET_NR_setregid32
7332
    case TARGET_NR_setregid32:
7333
        ret = get_errno(setregid(arg1, arg2));
7334
        break;
7335
#endif
7336
#ifdef TARGET_NR_getgroups32
7337
    case TARGET_NR_getgroups32:
7338
        {
7339
            int gidsetsize = arg1;
7340
            uint32_t *target_grouplist;
7341
            gid_t *grouplist;
7342
            int i;
7343

    
7344
            grouplist = alloca(gidsetsize * sizeof(gid_t));
7345
            ret = get_errno(getgroups(gidsetsize, grouplist));
7346
            if (gidsetsize == 0)
7347
                break;
7348
            if (!is_error(ret)) {
7349
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
7350
                if (!target_grouplist) {
7351
                    ret = -TARGET_EFAULT;
7352
                    goto fail;
7353
                }
7354
                for(i = 0;i < ret; i++)
7355
                    target_grouplist[i] = tswap32(grouplist[i]);
7356
                unlock_user(target_grouplist, arg2, gidsetsize * 4);
7357
            }
7358
        }
7359
        break;
7360
#endif
7361
#ifdef TARGET_NR_setgroups32
7362
    case TARGET_NR_setgroups32:
7363
        {
7364
            int gidsetsize = arg1;
7365
            uint32_t *target_grouplist;
7366
            gid_t *grouplist;
7367
            int i;
7368

    
7369
            grouplist = alloca(gidsetsize * sizeof(gid_t));
7370
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
7371
            if (!target_grouplist) {
7372
                ret = -TARGET_EFAULT;
7373
                goto fail;
7374
            }
7375
            for(i = 0;i < gidsetsize; i++)
7376
                grouplist[i] = tswap32(target_grouplist[i]);
7377
            unlock_user(target_grouplist, arg2, 0);
7378
            ret = get_errno(setgroups(gidsetsize, grouplist));
7379
        }
7380
        break;
7381
#endif
7382
#ifdef TARGET_NR_fchown32
7383
    case TARGET_NR_fchown32:
7384
        ret = get_errno(fchown(arg1, arg2, arg3));
7385
        break;
7386
#endif
7387
#ifdef TARGET_NR_setresuid32
7388
    case TARGET_NR_setresuid32:
7389
        ret = get_errno(setresuid(arg1, arg2, arg3));
7390
        break;
7391
#endif
7392
#ifdef TARGET_NR_getresuid32
7393
    case TARGET_NR_getresuid32:
7394
        {
7395
            uid_t ruid, euid, suid;
7396
            ret = get_errno(getresuid(&ruid, &euid, &suid));
7397
            if (!is_error(ret)) {
7398
                if (put_user_u32(ruid, arg1)
7399
                    || put_user_u32(euid, arg2)
7400
                    || put_user_u32(suid, arg3))
7401
                    goto efault;
7402
            }
7403
        }
7404
        break;
7405
#endif
7406
#ifdef TARGET_NR_setresgid32
7407
    case TARGET_NR_setresgid32:
7408
        ret = get_errno(setresgid(arg1, arg2, arg3));
7409
        break;
7410
#endif
7411
#ifdef TARGET_NR_getresgid32
7412
    case TARGET_NR_getresgid32:
7413
        {
7414
            gid_t rgid, egid, sgid;
7415
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
7416
            if (!is_error(ret)) {
7417
                if (put_user_u32(rgid, arg1)
7418
                    || put_user_u32(egid, arg2)
7419
                    || put_user_u32(sgid, arg3))
7420
                    goto efault;
7421
            }
7422
        }
7423
        break;
7424
#endif
7425
#ifdef TARGET_NR_chown32
7426
    case TARGET_NR_chown32:
7427
        if (!(p = lock_user_string(arg1)))
7428
            goto efault;
7429
        ret = get_errno(chown(p, arg2, arg3));
7430
        unlock_user(p, arg1, 0);
7431
        break;
7432
#endif
7433
#ifdef TARGET_NR_setuid32
7434
    case TARGET_NR_setuid32:
7435
        ret = get_errno(setuid(arg1));
7436
        break;
7437
#endif
7438
#ifdef TARGET_NR_setgid32
7439
    case TARGET_NR_setgid32:
7440
        ret = get_errno(setgid(arg1));
7441
        break;
7442
#endif
7443
#ifdef TARGET_NR_setfsuid32
7444
    case TARGET_NR_setfsuid32:
7445
        ret = get_errno(setfsuid(arg1));
7446
        break;
7447
#endif
7448
#ifdef TARGET_NR_setfsgid32
7449
    case TARGET_NR_setfsgid32:
7450
        ret = get_errno(setfsgid(arg1));
7451
        break;
7452
#endif
7453

    
7454
    case TARGET_NR_pivot_root:
7455
        goto unimplemented;
7456
#ifdef TARGET_NR_mincore
7457
    case TARGET_NR_mincore:
7458
        {
7459
            void *a;
7460
            ret = -TARGET_EFAULT;
7461
            if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
7462
                goto efault;
7463
            if (!(p = lock_user_string(arg3)))
7464
                goto mincore_fail;
7465
            ret = get_errno(mincore(a, arg2, p));
7466
            unlock_user(p, arg3, ret);
7467
            mincore_fail:
7468
            unlock_user(a, arg1, 0);
7469
        }
7470
        break;
7471
#endif
7472
#ifdef TARGET_NR_arm_fadvise64_64
7473
    case TARGET_NR_arm_fadvise64_64:
7474
        {
7475
                /*
7476
                 * arm_fadvise64_64 looks like fadvise64_64 but
7477
                 * with different argument order
7478
                 */
7479
                abi_long temp;
7480
                temp = arg3;
7481
                arg3 = arg4;
7482
                arg4 = temp;
7483
        }
7484
#endif
7485
#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64) || defined(TARGET_NR_fadvise64)
7486
#ifdef TARGET_NR_fadvise64_64
7487
    case TARGET_NR_fadvise64_64:
7488
#endif
7489
#ifdef TARGET_NR_fadvise64
7490
    case TARGET_NR_fadvise64:
7491
#endif
7492
#ifdef TARGET_S390X
7493
        switch (arg4) {
7494
        case 4: arg4 = POSIX_FADV_NOREUSE + 1; break; /* make sure it's an invalid value */
7495
        case 5: arg4 = POSIX_FADV_NOREUSE + 2; break; /* ditto */
7496
        case 6: arg4 = POSIX_FADV_DONTNEED; break;
7497
        case 7: arg4 = POSIX_FADV_NOREUSE; break;
7498
        default: break;
7499
        }
7500
#endif
7501
        ret = -posix_fadvise(arg1, arg2, arg3, arg4);
7502
        break;
7503
#endif
7504
#ifdef TARGET_NR_madvise
7505
    case TARGET_NR_madvise:
7506
        /* A straight passthrough may not be safe because qemu sometimes
7507
           turns private flie-backed mappings into anonymous mappings.
7508
           This will break MADV_DONTNEED.
7509
           This is a hint, so ignoring and returning success is ok.  */
7510
        ret = get_errno(0);
7511
        break;
7512
#endif
7513
#if TARGET_ABI_BITS == 32
7514
    case TARGET_NR_fcntl64:
7515
    {
7516
        int cmd;
7517
        struct flock64 fl;
7518
        struct target_flock64 *target_fl;
7519
#ifdef TARGET_ARM
7520
        struct target_eabi_flock64 *target_efl;
7521
#endif
7522

    
7523
        cmd = target_to_host_fcntl_cmd(arg2);
7524
        if (cmd == -TARGET_EINVAL)
7525
                return cmd;
7526

    
7527
        switch(arg2) {
7528
        case TARGET_F_GETLK64:
7529
#ifdef TARGET_ARM
7530
            if (((CPUARMState *)cpu_env)->eabi) {
7531
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
7532
                    goto efault;
7533
                fl.l_type = tswap16(target_efl->l_type);
7534
                fl.l_whence = tswap16(target_efl->l_whence);
7535
                fl.l_start = tswap64(target_efl->l_start);
7536
                fl.l_len = tswap64(target_efl->l_len);
7537
                fl.l_pid = tswap32(target_efl->l_pid);
7538
                unlock_user_struct(target_efl, arg3, 0);
7539
            } else
7540
#endif
7541
            {
7542
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
7543
                    goto efault;
7544
                fl.l_type = tswap16(target_fl->l_type);
7545
                fl.l_whence = tswap16(target_fl->l_whence);
7546
                fl.l_start = tswap64(target_fl->l_start);
7547
                fl.l_len = tswap64(target_fl->l_len);
7548
                fl.l_pid = tswap32(target_fl->l_pid);
7549
                unlock_user_struct(target_fl, arg3, 0);
7550
            }
7551
            ret = get_errno(fcntl(arg1, cmd, &fl));
7552
            if (ret == 0) {
7553
#ifdef TARGET_ARM
7554
                if (((CPUARMState *)cpu_env)->eabi) {
7555
                    if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) 
7556
                        goto efault;
7557
                    target_efl->l_type = tswap16(fl.l_type);
7558
                    target_efl->l_whence = tswap16(fl.l_whence);
7559
                    target_efl->l_start = tswap64(fl.l_start);
7560
                    target_efl->l_len = tswap64(fl.l_len);
7561
                    target_efl->l_pid = tswap32(fl.l_pid);
7562
                    unlock_user_struct(target_efl, arg3, 1);
7563
                } else
7564
#endif
7565
                {
7566
                    if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) 
7567
                        goto efault;
7568
                    target_fl->l_type = tswap16(fl.l_type);
7569
                    target_fl->l_whence = tswap16(fl.l_whence);
7570
                    target_fl->l_start = tswap64(fl.l_start);
7571
                    target_fl->l_len = tswap64(fl.l_len);
7572
                    target_fl->l_pid = tswap32(fl.l_pid);
7573
                    unlock_user_struct(target_fl, arg3, 1);
7574
                }
7575
            }
7576
            break;
7577

    
7578
        case TARGET_F_SETLK64:
7579
        case TARGET_F_SETLKW64:
7580
#ifdef TARGET_ARM
7581
            if (((CPUARMState *)cpu_env)->eabi) {
7582
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
7583
                    goto efault;
7584
                fl.l_type = tswap16(target_efl->l_type);
7585
                fl.l_whence = tswap16(target_efl->l_whence);
7586
                fl.l_start = tswap64(target_efl->l_start);
7587
                fl.l_len = tswap64(target_efl->l_len);
7588
                fl.l_pid = tswap32(target_efl->l_pid);
7589
                unlock_user_struct(target_efl, arg3, 0);
7590
            } else
7591
#endif
7592
            {
7593
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
7594
                    goto efault;
7595
                fl.l_type = tswap16(target_fl->l_type);
7596
                fl.l_whence = tswap16(target_fl->l_whence);
7597
                fl.l_start = tswap64(target_fl->l_start);
7598
                fl.l_len = tswap64(target_fl->l_len);
7599
                fl.l_pid = tswap32(target_fl->l_pid);
7600
                unlock_user_struct(target_fl, arg3, 0);
7601
            }
7602
            ret = get_errno(fcntl(arg1, cmd, &fl));
7603
            break;
7604
        default:
7605
            ret = do_fcntl(arg1, arg2, arg3);
7606
            break;
7607
        }
7608
        break;
7609
    }
7610
#endif
7611
#ifdef TARGET_NR_cacheflush
7612
    case TARGET_NR_cacheflush:
7613
        /* self-modifying code is handled automatically, so nothing needed */
7614
        ret = 0;
7615
        break;
7616
#endif
7617
#ifdef TARGET_NR_security
7618
    case TARGET_NR_security:
7619
        goto unimplemented;
7620
#endif
7621
#ifdef TARGET_NR_getpagesize
7622
    case TARGET_NR_getpagesize:
7623
        ret = TARGET_PAGE_SIZE;
7624
        break;
7625
#endif
7626
    case TARGET_NR_gettid:
7627
        ret = get_errno(gettid());
7628
        break;
7629
#ifdef TARGET_NR_readahead
7630
    case TARGET_NR_readahead:
7631
#if TARGET_ABI_BITS == 32
7632
        if (regpairs_aligned(cpu_env)) {
7633
            arg2 = arg3;
7634
            arg3 = arg4;
7635
            arg4 = arg5;
7636
        }
7637
        ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
7638
#else
7639
        ret = get_errno(readahead(arg1, arg2, arg3));
7640
#endif
7641
        break;
7642
#endif
7643
#ifdef CONFIG_ATTR
7644
#ifdef TARGET_NR_setxattr
7645
    case TARGET_NR_lsetxattr:
7646
    case TARGET_NR_fsetxattr:
7647
    case TARGET_NR_lgetxattr:
7648
    case TARGET_NR_fgetxattr:
7649
    case TARGET_NR_listxattr:
7650
    case TARGET_NR_llistxattr:
7651
    case TARGET_NR_flistxattr:
7652
    case TARGET_NR_lremovexattr:
7653
    case TARGET_NR_fremovexattr:
7654
        ret = -TARGET_EOPNOTSUPP;
7655
        break;
7656
    case TARGET_NR_setxattr:
7657
        {
7658
            void *p, *n, *v;
7659
            p = lock_user_string(arg1);
7660
            n = lock_user_string(arg2);
7661
            v = lock_user(VERIFY_READ, arg3, arg4, 1);
7662
            if (p && n && v) {
7663
                ret = get_errno(setxattr(p, n, v, arg4, arg5));
7664
            } else {
7665
                ret = -TARGET_EFAULT;
7666
            }
7667
            unlock_user(p, arg1, 0);
7668
            unlock_user(n, arg2, 0);
7669
            unlock_user(v, arg3, 0);
7670
        }
7671
        break;
7672
    case TARGET_NR_getxattr:
7673
        {
7674
            void *p, *n, *v;
7675
            p = lock_user_string(arg1);
7676
            n = lock_user_string(arg2);
7677
            v = lock_user(VERIFY_WRITE, arg3, arg4, 0);
7678
            if (p && n && v) {
7679
                ret = get_errno(getxattr(p, n, v, arg4));
7680
            } else {
7681
                ret = -TARGET_EFAULT;
7682
            }
7683
            unlock_user(p, arg1, 0);
7684
            unlock_user(n, arg2, 0);
7685
            unlock_user(v, arg3, arg4);
7686
        }
7687
        break;
7688
    case TARGET_NR_removexattr:
7689
        {
7690
            void *p, *n;
7691
            p = lock_user_string(arg1);
7692
            n = lock_user_string(arg2);
7693
            if (p && n) {
7694
                ret = get_errno(removexattr(p, n));
7695
            } else {
7696
                ret = -TARGET_EFAULT;
7697
            }
7698
            unlock_user(p, arg1, 0);
7699
            unlock_user(n, arg2, 0);
7700
        }
7701
        break;
7702
#endif
7703
#endif /* CONFIG_ATTR */
7704
#ifdef TARGET_NR_set_thread_area
7705
    case TARGET_NR_set_thread_area:
7706
#if defined(TARGET_MIPS)
7707
      ((CPUMIPSState *) cpu_env)->tls_value = arg1;
7708
      ret = 0;
7709
      break;
7710
#elif defined(TARGET_CRIS)
7711
      if (arg1 & 0xff)
7712
          ret = -TARGET_EINVAL;
7713
      else {
7714
          ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
7715
          ret = 0;
7716
      }
7717
      break;
7718
#elif defined(TARGET_I386) && defined(TARGET_ABI32)
7719
      ret = do_set_thread_area(cpu_env, arg1);
7720
      break;
7721
#else
7722
      goto unimplemented_nowarn;
7723
#endif
7724
#endif
7725
#ifdef TARGET_NR_get_thread_area
7726
    case TARGET_NR_get_thread_area:
7727
#if defined(TARGET_I386) && defined(TARGET_ABI32)
7728
        ret = do_get_thread_area(cpu_env, arg1);
7729
#else
7730
        goto unimplemented_nowarn;
7731
#endif
7732
#endif
7733
#ifdef TARGET_NR_getdomainname
7734
    case TARGET_NR_getdomainname:
7735
        goto unimplemented_nowarn;
7736
#endif
7737

    
7738
#ifdef TARGET_NR_clock_gettime
7739
    case TARGET_NR_clock_gettime:
7740
    {
7741
        struct timespec ts;
7742
        ret = get_errno(clock_gettime(arg1, &ts));
7743
        if (!is_error(ret)) {
7744
            host_to_target_timespec(arg2, &ts);
7745
        }
7746
        break;
7747
    }
7748
#endif
7749
#ifdef TARGET_NR_clock_getres
7750
    case TARGET_NR_clock_getres:
7751
    {
7752
        struct timespec ts;
7753
        ret = get_errno(clock_getres(arg1, &ts));
7754
        if (!is_error(ret)) {
7755
            host_to_target_timespec(arg2, &ts);
7756
        }
7757
        break;
7758
    }
7759
#endif
7760
#ifdef TARGET_NR_clock_nanosleep
7761
    case TARGET_NR_clock_nanosleep:
7762
    {
7763
        struct timespec ts;
7764
        target_to_host_timespec(&ts, arg3);
7765
        ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
7766
        if (arg4)
7767
            host_to_target_timespec(arg4, &ts);
7768
        break;
7769
    }
7770
#endif
7771

    
7772
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
7773
    case TARGET_NR_set_tid_address:
7774
        ret = get_errno(set_tid_address((int *)g2h(arg1)));
7775
        break;
7776
#endif
7777

    
7778
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
7779
    case TARGET_NR_tkill:
7780
        ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
7781
        break;
7782
#endif
7783

    
7784
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
7785
    case TARGET_NR_tgkill:
7786
        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
7787
                        target_to_host_signal(arg3)));
7788
        break;
7789
#endif
7790

    
7791
#ifdef TARGET_NR_set_robust_list
7792
    case TARGET_NR_set_robust_list:
7793
        goto unimplemented_nowarn;
7794
#endif
7795

    
7796
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
7797
    case TARGET_NR_utimensat:
7798
        {
7799
            struct timespec *tsp, ts[2];
7800
            if (!arg3) {
7801
                tsp = NULL;
7802
            } else {
7803
                target_to_host_timespec(ts, arg3);
7804
                target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
7805
                tsp = ts;
7806
            }
7807
            if (!arg2)
7808
                ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4));
7809
            else {
7810
                if (!(p = lock_user_string(arg2))) {
7811
                    ret = -TARGET_EFAULT;
7812
                    goto fail;
7813
                }
7814
                ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4));
7815
                unlock_user(p, arg2, 0);
7816
            }
7817
        }
7818
        break;
7819
#endif
7820
#if defined(CONFIG_USE_NPTL)
7821
    case TARGET_NR_futex:
7822
        ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
7823
        break;
7824
#endif
7825
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
7826
    case TARGET_NR_inotify_init:
7827
        ret = get_errno(sys_inotify_init());
7828
        break;
7829
#endif
7830
#ifdef CONFIG_INOTIFY1
7831
#if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
7832
    case TARGET_NR_inotify_init1:
7833
        ret = get_errno(sys_inotify_init1(arg1));
7834
        break;
7835
#endif
7836
#endif
7837
#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
7838
    case TARGET_NR_inotify_add_watch:
7839
        p = lock_user_string(arg2);
7840
        ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
7841
        unlock_user(p, arg2, 0);
7842
        break;
7843
#endif
7844
#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
7845
    case TARGET_NR_inotify_rm_watch:
7846
        ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
7847
        break;
7848
#endif
7849

    
7850
#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
7851
    case TARGET_NR_mq_open:
7852
        {
7853
            struct mq_attr posix_mq_attr;
7854

    
7855
            p = lock_user_string(arg1 - 1);
7856
            if (arg4 != 0)
7857
                copy_from_user_mq_attr (&posix_mq_attr, arg4);
7858
            ret = get_errno(mq_open(p, arg2, arg3, &posix_mq_attr));
7859
            unlock_user (p, arg1, 0);
7860
        }
7861
        break;
7862

    
7863
    case TARGET_NR_mq_unlink:
7864
        p = lock_user_string(arg1 - 1);
7865
        ret = get_errno(mq_unlink(p));
7866
        unlock_user (p, arg1, 0);
7867
        break;
7868

    
7869
    case TARGET_NR_mq_timedsend:
7870
        {
7871
            struct timespec ts;
7872

    
7873
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
7874
            if (arg5 != 0) {
7875
                target_to_host_timespec(&ts, arg5);
7876
                ret = get_errno(mq_timedsend(arg1, p, arg3, arg4, &ts));
7877
                host_to_target_timespec(arg5, &ts);
7878
            }
7879
            else
7880
                ret = get_errno(mq_send(arg1, p, arg3, arg4));
7881
            unlock_user (p, arg2, arg3);
7882
        }
7883
        break;
7884

    
7885
    case TARGET_NR_mq_timedreceive:
7886
        {
7887
            struct timespec ts;
7888
            unsigned int prio;
7889

    
7890
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
7891
            if (arg5 != 0) {
7892
                target_to_host_timespec(&ts, arg5);
7893
                ret = get_errno(mq_timedreceive(arg1, p, arg3, &prio, &ts));
7894
                host_to_target_timespec(arg5, &ts);
7895
            }
7896
            else
7897
                ret = get_errno(mq_receive(arg1, p, arg3, &prio));
7898
            unlock_user (p, arg2, arg3);
7899
            if (arg4 != 0)
7900
                put_user_u32(prio, arg4);
7901
        }
7902
        break;
7903

    
7904
    /* Not implemented for now... */
7905
/*     case TARGET_NR_mq_notify: */
7906
/*         break; */
7907

    
7908
    case TARGET_NR_mq_getsetattr:
7909
        {
7910
            struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
7911
            ret = 0;
7912
            if (arg3 != 0) {
7913
                ret = mq_getattr(arg1, &posix_mq_attr_out);
7914
                copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
7915
            }
7916
            if (arg2 != 0) {
7917
                copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
7918
                ret |= mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_attr_out);
7919
            }
7920

    
7921
        }
7922
        break;
7923
#endif
7924

    
7925
#ifdef CONFIG_SPLICE
7926
#ifdef TARGET_NR_tee
7927
    case TARGET_NR_tee:
7928
        {
7929
            ret = get_errno(tee(arg1,arg2,arg3,arg4));
7930
        }
7931
        break;
7932
#endif
7933
#ifdef TARGET_NR_splice
7934
    case TARGET_NR_splice:
7935
        {
7936
            loff_t loff_in, loff_out;
7937
            loff_t *ploff_in = NULL, *ploff_out = NULL;
7938
            if(arg2) {
7939
                get_user_u64(loff_in, arg2);
7940
                ploff_in = &loff_in;
7941
            }
7942
            if(arg4) {
7943
                get_user_u64(loff_out, arg2);
7944
                ploff_out = &loff_out;
7945
            }
7946
            ret = get_errno(splice(arg1, ploff_in, arg3, ploff_out, arg5, arg6));
7947
        }
7948
        break;
7949
#endif
7950
#ifdef TARGET_NR_vmsplice
7951
        case TARGET_NR_vmsplice:
7952
        {
7953
            int count = arg3;
7954
            struct iovec *vec;
7955

    
7956
            vec = alloca(count * sizeof(struct iovec));
7957
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
7958
                goto efault;
7959
            ret = get_errno(vmsplice(arg1, vec, count, arg4));
7960
            unlock_iovec(vec, arg2, count, 0);
7961
        }
7962
        break;
7963
#endif
7964
#endif /* CONFIG_SPLICE */
7965
#ifdef CONFIG_EVENTFD
7966
#if defined(TARGET_NR_eventfd)
7967
    case TARGET_NR_eventfd:
7968
        ret = get_errno(eventfd(arg1, 0));
7969
        break;
7970
#endif
7971
#if defined(TARGET_NR_eventfd2)
7972
    case TARGET_NR_eventfd2:
7973
        ret = get_errno(eventfd(arg1, arg2));
7974
        break;
7975
#endif
7976
#endif /* CONFIG_EVENTFD  */
7977
#if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate)
7978
    case TARGET_NR_fallocate:
7979
        ret = get_errno(fallocate(arg1, arg2, arg3, arg4));
7980
        break;
7981
#endif
7982
#if defined(CONFIG_SYNC_FILE_RANGE)
7983
#if defined(TARGET_NR_sync_file_range)
7984
    case TARGET_NR_sync_file_range:
7985
#if TARGET_ABI_BITS == 32
7986
#if defined(TARGET_MIPS)
7987
        ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
7988
                                        target_offset64(arg5, arg6), arg7));
7989
#else
7990
        ret = get_errno(sync_file_range(arg1, target_offset64(arg2, arg3),
7991
                                        target_offset64(arg4, arg5), arg6));
7992
#endif /* !TARGET_MIPS */
7993
#else
7994
        ret = get_errno(sync_file_range(arg1, arg2, arg3, arg4));
7995
#endif
7996
        break;
7997
#endif
7998
#if defined(TARGET_NR_sync_file_range2)
7999
    case TARGET_NR_sync_file_range2:
8000
        /* This is like sync_file_range but the arguments are reordered */
8001
#if TARGET_ABI_BITS == 32
8002
        ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
8003
                                        target_offset64(arg5, arg6), arg2));
8004
#else
8005
        ret = get_errno(sync_file_range(arg1, arg3, arg4, arg2));
8006
#endif
8007
        break;
8008
#endif
8009
#endif
8010
#if defined(CONFIG_EPOLL)
8011
#if defined(TARGET_NR_epoll_create)
8012
    case TARGET_NR_epoll_create:
8013
        ret = get_errno(epoll_create(arg1));
8014
        break;
8015
#endif
8016
#if defined(TARGET_NR_epoll_create1) && defined(CONFIG_EPOLL_CREATE1)
8017
    case TARGET_NR_epoll_create1:
8018
        ret = get_errno(epoll_create1(arg1));
8019
        break;
8020
#endif
8021
#if defined(TARGET_NR_epoll_ctl)
8022
    case TARGET_NR_epoll_ctl:
8023
    {
8024
        struct epoll_event ep;
8025
        struct epoll_event *epp = 0;
8026
        if (arg4) {
8027
            struct target_epoll_event *target_ep;
8028
            if (!lock_user_struct(VERIFY_READ, target_ep, arg4, 1)) {
8029
                goto efault;
8030
            }
8031
            ep.events = tswap32(target_ep->events);
8032
            /* The epoll_data_t union is just opaque data to the kernel,
8033
             * so we transfer all 64 bits across and need not worry what
8034
             * actual data type it is.
8035
             */
8036
            ep.data.u64 = tswap64(target_ep->data.u64);
8037
            unlock_user_struct(target_ep, arg4, 0);
8038
            epp = &ep;
8039
        }
8040
        ret = get_errno(epoll_ctl(arg1, arg2, arg3, epp));
8041
        break;
8042
    }
8043
#endif
8044

    
8045
#if defined(TARGET_NR_epoll_pwait) && defined(CONFIG_EPOLL_PWAIT)
8046
#define IMPLEMENT_EPOLL_PWAIT
8047
#endif
8048
#if defined(TARGET_NR_epoll_wait) || defined(IMPLEMENT_EPOLL_PWAIT)
8049
#if defined(TARGET_NR_epoll_wait)
8050
    case TARGET_NR_epoll_wait:
8051
#endif
8052
#if defined(IMPLEMENT_EPOLL_PWAIT)
8053
    case TARGET_NR_epoll_pwait:
8054
#endif
8055
    {
8056
        struct target_epoll_event *target_ep;
8057
        struct epoll_event *ep;
8058
        int epfd = arg1;
8059
        int maxevents = arg3;
8060
        int timeout = arg4;
8061

    
8062
        target_ep = lock_user(VERIFY_WRITE, arg2,
8063
                              maxevents * sizeof(struct target_epoll_event), 1);
8064
        if (!target_ep) {
8065
            goto efault;
8066
        }
8067

    
8068
        ep = alloca(maxevents * sizeof(struct epoll_event));
8069

    
8070
        switch (num) {
8071
#if defined(IMPLEMENT_EPOLL_PWAIT)
8072
        case TARGET_NR_epoll_pwait:
8073
        {
8074
            target_sigset_t *target_set;
8075
            sigset_t _set, *set = &_set;
8076

    
8077
            if (arg5) {
8078
                target_set = lock_user(VERIFY_READ, arg5,
8079
                                       sizeof(target_sigset_t), 1);
8080
                if (!target_set) {
8081
                    unlock_user(target_ep, arg2, 0);
8082
                    goto efault;
8083
                }
8084
                target_to_host_sigset(set, target_set);
8085
                unlock_user(target_set, arg5, 0);
8086
            } else {
8087
                set = NULL;
8088
            }
8089

    
8090
            ret = get_errno(epoll_pwait(epfd, ep, maxevents, timeout, set));
8091
            break;
8092
        }
8093
#endif
8094
#if defined(TARGET_NR_epoll_wait)
8095
        case TARGET_NR_epoll_wait:
8096
            ret = get_errno(epoll_wait(epfd, ep, maxevents, timeout));
8097
            break;
8098
#endif
8099
        default:
8100
            ret = -TARGET_ENOSYS;
8101
        }
8102
        if (!is_error(ret)) {
8103
            int i;
8104
            for (i = 0; i < ret; i++) {
8105
                target_ep[i].events = tswap32(ep[i].events);
8106
                target_ep[i].data.u64 = tswap64(ep[i].data.u64);
8107
            }
8108
        }
8109
        unlock_user(target_ep, arg2, ret * sizeof(struct target_epoll_event));
8110
        break;
8111
    }
8112
#endif
8113
#endif
8114
#ifdef TARGET_NR_prlimit64
8115
    case TARGET_NR_prlimit64:
8116
    {
8117
        /* args: pid, resource number, ptr to new rlimit, ptr to old rlimit */
8118
        struct target_rlimit64 *target_rnew, *target_rold;
8119
        struct host_rlimit64 rnew, rold, *rnewp = 0;
8120
        if (arg3) {
8121
            if (!lock_user_struct(VERIFY_READ, target_rnew, arg3, 1)) {
8122
                goto efault;
8123
            }
8124
            rnew.rlim_cur = tswap64(target_rnew->rlim_cur);
8125
            rnew.rlim_max = tswap64(target_rnew->rlim_max);
8126
            unlock_user_struct(target_rnew, arg3, 0);
8127
            rnewp = &rnew;
8128
        }
8129

    
8130
        ret = get_errno(sys_prlimit64(arg1, arg2, rnewp, arg4 ? &rold : 0));
8131
        if (!is_error(ret) && arg4) {
8132
            if (!lock_user_struct(VERIFY_WRITE, target_rold, arg4, 1)) {
8133
                goto efault;
8134
            }
8135
            target_rold->rlim_cur = tswap64(rold.rlim_cur);
8136
            target_rold->rlim_max = tswap64(rold.rlim_max);
8137
            unlock_user_struct(target_rold, arg4, 1);
8138
        }
8139
        break;
8140
    }
8141
#endif
8142
    default:
8143
    unimplemented:
8144
        gemu_log("qemu: Unsupported syscall: %d\n", num);
8145
#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
8146
    unimplemented_nowarn:
8147
#endif
8148
        ret = -TARGET_ENOSYS;
8149
        break;
8150
    }
8151
fail:
8152
#ifdef DEBUG
8153
    gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
8154
#endif
8155
    if(do_strace)
8156
        print_syscall_ret(num, ret);
8157
    return ret;
8158
efault:
8159
    ret = -TARGET_EFAULT;
8160
    goto fail;
8161
}