Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ 6ad0a1ed

History | View | Annotate | Download (231.1 kB)

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

    
70
#define termios host_termios
71
#define winsize host_winsize
72
#define termio host_termio
73
#define sgttyb host_sgttyb /* same as target */
74
#define tchars host_tchars /* same as target */
75
#define ltchars host_ltchars /* same as target */
76

    
77
#include <linux/termios.h>
78
#include <linux/unistd.h>
79
#include <linux/utsname.h>
80
#include <linux/cdrom.h>
81
#include <linux/hdreg.h>
82
#include <linux/soundcard.h>
83
#include <linux/kd.h>
84
#include <linux/mtio.h>
85
#include <linux/fs.h>
86
#if defined(CONFIG_FIEMAP)
87
#include <linux/fiemap.h>
88
#endif
89
#include <linux/fb.h>
90
#include <linux/vt.h>
91
#include "linux_loop.h"
92
#include "cpu-uname.h"
93

    
94
#include "qemu.h"
95
#include "qemu-common.h"
96

    
97
#if defined(CONFIG_USE_NPTL)
98
#define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
99
    CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
100
#else
101
/* XXX: Hardcode the above values.  */
102
#define CLONE_NPTL_FLAGS2 0
103
#endif
104

    
105
//#define DEBUG
106

    
107
//#include <linux/msdos_fs.h>
108
#define        VFAT_IOCTL_READDIR_BOTH                _IOR('r', 1, struct linux_dirent [2])
109
#define        VFAT_IOCTL_READDIR_SHORT        _IOR('r', 2, struct linux_dirent [2])
110

    
111

    
112
#undef _syscall0
113
#undef _syscall1
114
#undef _syscall2
115
#undef _syscall3
116
#undef _syscall4
117
#undef _syscall5
118
#undef _syscall6
119

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

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

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

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

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

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

    
157

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

    
166

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

    
196
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
197
#define __NR__llseek __NR_lseek
198
#endif
199

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

    
239
static bitmask_transtbl fcntl_flags_tbl[] = {
240
  { TARGET_O_ACCMODE,   TARGET_O_WRONLY,    O_ACCMODE,   O_WRONLY,    },
241
  { TARGET_O_ACCMODE,   TARGET_O_RDWR,      O_ACCMODE,   O_RDWR,      },
242
  { TARGET_O_CREAT,     TARGET_O_CREAT,     O_CREAT,     O_CREAT,     },
243
  { TARGET_O_EXCL,      TARGET_O_EXCL,      O_EXCL,      O_EXCL,      },
244
  { TARGET_O_NOCTTY,    TARGET_O_NOCTTY,    O_NOCTTY,    O_NOCTTY,    },
245
  { TARGET_O_TRUNC,     TARGET_O_TRUNC,     O_TRUNC,     O_TRUNC,     },
246
  { TARGET_O_APPEND,    TARGET_O_APPEND,    O_APPEND,    O_APPEND,    },
247
  { TARGET_O_NONBLOCK,  TARGET_O_NONBLOCK,  O_NONBLOCK,  O_NONBLOCK,  },
248
  { TARGET_O_SYNC,      TARGET_O_SYNC,      O_SYNC,      O_SYNC,      },
249
  { TARGET_FASYNC,      TARGET_FASYNC,      FASYNC,      FASYNC,      },
250
  { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
251
  { TARGET_O_NOFOLLOW,  TARGET_O_NOFOLLOW,  O_NOFOLLOW,  O_NOFOLLOW,  },
252
  { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
253
#if defined(O_DIRECT)
254
  { TARGET_O_DIRECT,    TARGET_O_DIRECT,    O_DIRECT,    O_DIRECT,    },
255
#endif
256
  { 0, 0, 0, 0 }
257
};
258

    
259
#define COPY_UTSNAME_FIELD(dest, src) \
260
  do { \
261
      /* __NEW_UTS_LEN doesn't include terminating null */ \
262
      (void) strncpy((dest), (src), __NEW_UTS_LEN); \
263
      (dest)[__NEW_UTS_LEN] = '\0'; \
264
  } while (0)
265

    
266
static int sys_uname(struct new_utsname *buf)
267
{
268
  struct utsname uts_buf;
269

    
270
  if (uname(&uts_buf) < 0)
271
      return (-1);
272

    
273
  /*
274
   * Just in case these have some differences, we
275
   * translate utsname to new_utsname (which is the
276
   * struct linux kernel uses).
277
   */
278

    
279
  bzero(buf, sizeof (*buf));
280
  COPY_UTSNAME_FIELD(buf->sysname, uts_buf.sysname);
281
  COPY_UTSNAME_FIELD(buf->nodename, uts_buf.nodename);
282
  COPY_UTSNAME_FIELD(buf->release, uts_buf.release);
283
  COPY_UTSNAME_FIELD(buf->version, uts_buf.version);
284
  COPY_UTSNAME_FIELD(buf->machine, uts_buf.machine);
285
#ifdef _GNU_SOURCE
286
  COPY_UTSNAME_FIELD(buf->domainname, uts_buf.domainname);
287
#endif
288
  return (0);
289

    
290
#undef COPY_UTSNAME_FIELD
291
}
292

    
293
static int sys_getcwd1(char *buf, size_t size)
294
{
295
  if (getcwd(buf, size) == NULL) {
296
      /* getcwd() sets errno */
297
      return (-1);
298
  }
299
  return strlen(buf)+1;
300
}
301

    
302
#ifdef CONFIG_ATFILE
303
/*
304
 * Host system seems to have atfile syscall stubs available.  We
305
 * now enable them one by one as specified by target syscall_nr.h.
306
 */
307

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

    
379
      /*
380
       * Get the 'mode' parameter and translate it to
381
       * host bits.
382
       */
383
      va_start(ap, flags);
384
      mode = va_arg(ap, mode_t);
385
      mode = target_to_host_bitmask(mode, fcntl_flags_tbl);
386
      va_end(ap);
387

    
388
      return (openat(dirfd, pathname, flags, mode));
389
  }
390
  return (openat(dirfd, pathname, flags));
391
}
392
#endif
393
#ifdef TARGET_NR_readlinkat
394
static int sys_readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz)
395
{
396
  return (readlinkat(dirfd, pathname, buf, bufsiz));
397
}
398
#endif
399
#ifdef TARGET_NR_renameat
400
static int sys_renameat(int olddirfd, const char *oldpath,
401
    int newdirfd, const char *newpath)
402
{
403
  return (renameat(olddirfd, oldpath, newdirfd, newpath));
404
}
405
#endif
406
#ifdef TARGET_NR_symlinkat
407
static int sys_symlinkat(const char *oldpath, int newdirfd, const char *newpath)
408
{
409
  return (symlinkat(oldpath, newdirfd, newpath));
410
}
411
#endif
412
#ifdef TARGET_NR_unlinkat
413
static int sys_unlinkat(int dirfd, const char *pathname, int flags)
414
{
415
  return (unlinkat(dirfd, pathname, flags));
416
}
417
#endif
418
#else /* !CONFIG_ATFILE */
419

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

    
477
#endif /* CONFIG_ATFILE */
478

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

    
495
#ifdef CONFIG_INOTIFY
496
#include <sys/inotify.h>
497

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

    
532

    
533
extern int personality(int);
534
extern int flock(int, int);
535
extern int setfsuid(int);
536
extern int setfsgid(int);
537
extern int setgroups(int, gid_t *);
538

    
539
#define ERRNO_TABLE_SIZE 1200
540

    
541
/* target_to_host_errno_table[] is initialized from
542
 * host_to_target_errno_table[] in syscall_init(). */
543
static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
544
};
545

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

    
658
static inline int host_to_target_errno(int err)
659
{
660
    if(host_to_target_errno_table[err])
661
        return host_to_target_errno_table[err];
662
    return err;
663
}
664

    
665
static inline int target_to_host_errno(int err)
666
{
667
    if (target_to_host_errno_table[err])
668
        return target_to_host_errno_table[err];
669
    return err;
670
}
671

    
672
static inline abi_long get_errno(abi_long ret)
673
{
674
    if (ret == -1)
675
        return -host_to_target_errno(errno);
676
    else
677
        return ret;
678
}
679

    
680
static inline int is_error(abi_long ret)
681
{
682
    return (abi_ulong)ret >= (abi_ulong)(-4096);
683
}
684

    
685
char *target_strerror(int err)
686
{
687
    return strerror(target_to_host_errno(err));
688
}
689

    
690
static abi_ulong target_brk;
691
static abi_ulong target_original_brk;
692

    
693
void target_set_brk(abi_ulong new_brk)
694
{
695
    target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
696
}
697

    
698
/* do_brk() must return target values and target errnos. */
699
abi_long do_brk(abi_ulong new_brk)
700
{
701
    abi_ulong brk_page;
702
    abi_long mapped_addr;
703
    int        new_alloc_size;
704

    
705
    if (!new_brk)
706
        return target_brk;
707
    if (new_brk < target_original_brk)
708
        return target_brk;
709

    
710
    brk_page = HOST_PAGE_ALIGN(target_brk);
711

    
712
    /* If the new brk is less than this, set it and we're done... */
713
    if (new_brk < brk_page) {
714
        target_brk = new_brk;
715
            return target_brk;
716
    }
717

    
718
    /* We need to allocate more memory after the brk... */
719
    new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
720
    mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
721
                                        PROT_READ|PROT_WRITE,
722
                                        MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
723

    
724
#if defined(TARGET_ALPHA)
725
    /* We (partially) emulate OSF/1 on Alpha, which requires we
726
       return a proper errno, not an unchanged brk value.  */
727
    if (is_error(mapped_addr)) {
728
        return -TARGET_ENOMEM;
729
    }
730
#endif
731

    
732
    if (!is_error(mapped_addr)) {
733
        target_brk = new_brk;
734
    }
735
    return target_brk;
736
}
737

    
738
static inline abi_long copy_from_user_fdset(fd_set *fds,
739
                                            abi_ulong target_fds_addr,
740
                                            int n)
741
{
742
    int i, nw, j, k;
743
    abi_ulong b, *target_fds;
744

    
745
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
746
    if (!(target_fds = lock_user(VERIFY_READ,
747
                                 target_fds_addr,
748
                                 sizeof(abi_ulong) * nw,
749
                                 1)))
750
        return -TARGET_EFAULT;
751

    
752
    FD_ZERO(fds);
753
    k = 0;
754
    for (i = 0; i < nw; i++) {
755
        /* grab the abi_ulong */
756
        __get_user(b, &target_fds[i]);
757
        for (j = 0; j < TARGET_ABI_BITS; j++) {
758
            /* check the bit inside the abi_ulong */
759
            if ((b >> j) & 1)
760
                FD_SET(k, fds);
761
            k++;
762
        }
763
    }
764

    
765
    unlock_user(target_fds, target_fds_addr, 0);
766

    
767
    return 0;
768
}
769

    
770
static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
771
                                          const fd_set *fds,
772
                                          int n)
773
{
774
    int i, nw, j, k;
775
    abi_long v;
776
    abi_ulong *target_fds;
777

    
778
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
779
    if (!(target_fds = lock_user(VERIFY_WRITE,
780
                                 target_fds_addr,
781
                                 sizeof(abi_ulong) * nw,
782
                                 0)))
783
        return -TARGET_EFAULT;
784

    
785
    k = 0;
786
    for (i = 0; i < nw; i++) {
787
        v = 0;
788
        for (j = 0; j < TARGET_ABI_BITS; j++) {
789
            v |= ((FD_ISSET(k, fds) != 0) << j);
790
            k++;
791
        }
792
        __put_user(v, &target_fds[i]);
793
    }
794

    
795
    unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
796

    
797
    return 0;
798
}
799

    
800
#if defined(__alpha__)
801
#define HOST_HZ 1024
802
#else
803
#define HOST_HZ 100
804
#endif
805

    
806
static inline abi_long host_to_target_clock_t(long ticks)
807
{
808
#if HOST_HZ == TARGET_HZ
809
    return ticks;
810
#else
811
    return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
812
#endif
813
}
814

    
815
static inline abi_long host_to_target_rusage(abi_ulong target_addr,
816
                                             const struct rusage *rusage)
817
{
818
    struct target_rusage *target_rusage;
819

    
820
    if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
821
        return -TARGET_EFAULT;
822
    target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
823
    target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
824
    target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
825
    target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec);
826
    target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss);
827
    target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss);
828
    target_rusage->ru_idrss = tswapl(rusage->ru_idrss);
829
    target_rusage->ru_isrss = tswapl(rusage->ru_isrss);
830
    target_rusage->ru_minflt = tswapl(rusage->ru_minflt);
831
    target_rusage->ru_majflt = tswapl(rusage->ru_majflt);
832
    target_rusage->ru_nswap = tswapl(rusage->ru_nswap);
833
    target_rusage->ru_inblock = tswapl(rusage->ru_inblock);
834
    target_rusage->ru_oublock = tswapl(rusage->ru_oublock);
835
    target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd);
836
    target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv);
837
    target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);
838
    target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
839
    target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
840
    unlock_user_struct(target_rusage, target_addr, 1);
841

    
842
    return 0;
843
}
844

    
845
static inline rlim_t target_to_host_rlim(target_ulong target_rlim)
846
{
847
    if (target_rlim == TARGET_RLIM_INFINITY)
848
        return RLIM_INFINITY;
849
    else
850
        return tswapl(target_rlim);
851
}
852

    
853
static inline target_ulong host_to_target_rlim(rlim_t rlim)
854
{
855
    if (rlim == RLIM_INFINITY || rlim != (target_long)rlim)
856
        return TARGET_RLIM_INFINITY;
857
    else
858
        return tswapl(rlim);
859
}
860

    
861
static inline abi_long copy_from_user_timeval(struct timeval *tv,
862
                                              abi_ulong target_tv_addr)
863
{
864
    struct target_timeval *target_tv;
865

    
866
    if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
867
        return -TARGET_EFAULT;
868

    
869
    __get_user(tv->tv_sec, &target_tv->tv_sec);
870
    __get_user(tv->tv_usec, &target_tv->tv_usec);
871

    
872
    unlock_user_struct(target_tv, target_tv_addr, 0);
873

    
874
    return 0;
875
}
876

    
877
static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
878
                                            const struct timeval *tv)
879
{
880
    struct target_timeval *target_tv;
881

    
882
    if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
883
        return -TARGET_EFAULT;
884

    
885
    __put_user(tv->tv_sec, &target_tv->tv_sec);
886
    __put_user(tv->tv_usec, &target_tv->tv_usec);
887

    
888
    unlock_user_struct(target_tv, target_tv_addr, 1);
889

    
890
    return 0;
891
}
892

    
893
#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
894
#include <mqueue.h>
895

    
896
static inline abi_long copy_from_user_mq_attr(struct mq_attr *attr,
897
                                              abi_ulong target_mq_attr_addr)
898
{
899
    struct target_mq_attr *target_mq_attr;
900

    
901
    if (!lock_user_struct(VERIFY_READ, target_mq_attr,
902
                          target_mq_attr_addr, 1))
903
        return -TARGET_EFAULT;
904

    
905
    __get_user(attr->mq_flags, &target_mq_attr->mq_flags);
906
    __get_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
907
    __get_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
908
    __get_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
909

    
910
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0);
911

    
912
    return 0;
913
}
914

    
915
static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr,
916
                                            const struct mq_attr *attr)
917
{
918
    struct target_mq_attr *target_mq_attr;
919

    
920
    if (!lock_user_struct(VERIFY_WRITE, target_mq_attr,
921
                          target_mq_attr_addr, 0))
922
        return -TARGET_EFAULT;
923

    
924
    __put_user(attr->mq_flags, &target_mq_attr->mq_flags);
925
    __put_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
926
    __put_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
927
    __put_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
928

    
929
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1);
930

    
931
    return 0;
932
}
933
#endif
934

    
935
/* do_select() must return target values and target errnos. */
936
static abi_long do_select(int n,
937
                          abi_ulong rfd_addr, abi_ulong wfd_addr,
938
                          abi_ulong efd_addr, abi_ulong target_tv_addr)
939
{
940
    fd_set rfds, wfds, efds;
941
    fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
942
    struct timeval tv, *tv_ptr;
943
    abi_long ret;
944

    
945
    if (rfd_addr) {
946
        if (copy_from_user_fdset(&rfds, rfd_addr, n))
947
            return -TARGET_EFAULT;
948
        rfds_ptr = &rfds;
949
    } else {
950
        rfds_ptr = NULL;
951
    }
952
    if (wfd_addr) {
953
        if (copy_from_user_fdset(&wfds, wfd_addr, n))
954
            return -TARGET_EFAULT;
955
        wfds_ptr = &wfds;
956
    } else {
957
        wfds_ptr = NULL;
958
    }
959
    if (efd_addr) {
960
        if (copy_from_user_fdset(&efds, efd_addr, n))
961
            return -TARGET_EFAULT;
962
        efds_ptr = &efds;
963
    } else {
964
        efds_ptr = NULL;
965
    }
966

    
967
    if (target_tv_addr) {
968
        if (copy_from_user_timeval(&tv, target_tv_addr))
969
            return -TARGET_EFAULT;
970
        tv_ptr = &tv;
971
    } else {
972
        tv_ptr = NULL;
973
    }
974

    
975
    ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
976

    
977
    if (!is_error(ret)) {
978
        if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
979
            return -TARGET_EFAULT;
980
        if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
981
            return -TARGET_EFAULT;
982
        if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
983
            return -TARGET_EFAULT;
984

    
985
        if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
986
            return -TARGET_EFAULT;
987
    }
988

    
989
    return ret;
990
}
991

    
992
static abi_long do_pipe2(int host_pipe[], int flags)
993
{
994
#ifdef CONFIG_PIPE2
995
    return pipe2(host_pipe, flags);
996
#else
997
    return -ENOSYS;
998
#endif
999
}
1000

    
1001
static abi_long do_pipe(void *cpu_env, abi_ulong pipedes,
1002
                        int flags, int is_pipe2)
1003
{
1004
    int host_pipe[2];
1005
    abi_long ret;
1006
    ret = flags ? do_pipe2(host_pipe, flags) : pipe(host_pipe);
1007

    
1008
    if (is_error(ret))
1009
        return get_errno(ret);
1010

    
1011
    /* Several targets have special calling conventions for the original
1012
       pipe syscall, but didn't replicate this into the pipe2 syscall.  */
1013
    if (!is_pipe2) {
1014
#if defined(TARGET_ALPHA)
1015
        ((CPUAlphaState *)cpu_env)->ir[IR_A4] = host_pipe[1];
1016
        return host_pipe[0];
1017
#elif defined(TARGET_MIPS)
1018
        ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1];
1019
        return host_pipe[0];
1020
#elif defined(TARGET_SH4)
1021
        ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
1022
        return host_pipe[0];
1023
#endif
1024
    }
1025

    
1026
    if (put_user_s32(host_pipe[0], pipedes)
1027
        || put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0])))
1028
        return -TARGET_EFAULT;
1029
    return get_errno(ret);
1030
}
1031

    
1032
static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn,
1033
                                              abi_ulong target_addr,
1034
                                              socklen_t len)
1035
{
1036
    struct target_ip_mreqn *target_smreqn;
1037

    
1038
    target_smreqn = lock_user(VERIFY_READ, target_addr, len, 1);
1039
    if (!target_smreqn)
1040
        return -TARGET_EFAULT;
1041
    mreqn->imr_multiaddr.s_addr = target_smreqn->imr_multiaddr.s_addr;
1042
    mreqn->imr_address.s_addr = target_smreqn->imr_address.s_addr;
1043
    if (len == sizeof(struct target_ip_mreqn))
1044
        mreqn->imr_ifindex = tswapl(target_smreqn->imr_ifindex);
1045
    unlock_user(target_smreqn, target_addr, 0);
1046

    
1047
    return 0;
1048
}
1049

    
1050
static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
1051
                                               abi_ulong target_addr,
1052
                                               socklen_t len)
1053
{
1054
    const socklen_t unix_maxlen = sizeof (struct sockaddr_un);
1055
    sa_family_t sa_family;
1056
    struct target_sockaddr *target_saddr;
1057

    
1058
    target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
1059
    if (!target_saddr)
1060
        return -TARGET_EFAULT;
1061

    
1062
    sa_family = tswap16(target_saddr->sa_family);
1063

    
1064
    /* Oops. The caller might send a incomplete sun_path; sun_path
1065
     * must be terminated by \0 (see the manual page), but
1066
     * unfortunately it is quite common to specify sockaddr_un
1067
     * length as "strlen(x->sun_path)" while it should be
1068
     * "strlen(...) + 1". We'll fix that here if needed.
1069
     * Linux kernel has a similar feature.
1070
     */
1071

    
1072
    if (sa_family == AF_UNIX) {
1073
        if (len < unix_maxlen && len > 0) {
1074
            char *cp = (char*)target_saddr;
1075

    
1076
            if ( cp[len-1] && !cp[len] )
1077
                len++;
1078
        }
1079
        if (len > unix_maxlen)
1080
            len = unix_maxlen;
1081
    }
1082

    
1083
    memcpy(addr, target_saddr, len);
1084
    addr->sa_family = sa_family;
1085
    unlock_user(target_saddr, target_addr, 0);
1086

    
1087
    return 0;
1088
}
1089

    
1090
static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
1091
                                               struct sockaddr *addr,
1092
                                               socklen_t len)
1093
{
1094
    struct target_sockaddr *target_saddr;
1095

    
1096
    target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
1097
    if (!target_saddr)
1098
        return -TARGET_EFAULT;
1099
    memcpy(target_saddr, addr, len);
1100
    target_saddr->sa_family = tswap16(addr->sa_family);
1101
    unlock_user(target_saddr, target_addr, len);
1102

    
1103
    return 0;
1104
}
1105

    
1106
/* ??? Should this also swap msgh->name?  */
1107
static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
1108
                                           struct target_msghdr *target_msgh)
1109
{
1110
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1111
    abi_long msg_controllen;
1112
    abi_ulong target_cmsg_addr;
1113
    struct target_cmsghdr *target_cmsg;
1114
    socklen_t space = 0;
1115
    
1116
    msg_controllen = tswapl(target_msgh->msg_controllen);
1117
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1118
        goto the_end;
1119
    target_cmsg_addr = tswapl(target_msgh->msg_control);
1120
    target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
1121
    if (!target_cmsg)
1122
        return -TARGET_EFAULT;
1123

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

    
1128
        int len = tswapl(target_cmsg->cmsg_len)
1129
                  - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
1130

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

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

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

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

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

    
1163
/* ??? Should this also swap msgh->name?  */
1164
static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
1165
                                           struct msghdr *msgh)
1166
{
1167
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1168
    abi_long msg_controllen;
1169
    abi_ulong target_cmsg_addr;
1170
    struct target_cmsghdr *target_cmsg;
1171
    socklen_t space = 0;
1172

    
1173
    msg_controllen = tswapl(target_msgh->msg_controllen);
1174
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1175
        goto the_end;
1176
    target_cmsg_addr = tswapl(target_msgh->msg_control);
1177
    target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
1178
    if (!target_cmsg)
1179
        return -TARGET_EFAULT;
1180

    
1181
    while (cmsg && target_cmsg) {
1182
        void *data = CMSG_DATA(cmsg);
1183
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
1184

    
1185
        int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
1186

    
1187
        space += TARGET_CMSG_SPACE(len);
1188
        if (space > msg_controllen) {
1189
            space -= TARGET_CMSG_SPACE(len);
1190
            gemu_log("Target cmsg overflow\n");
1191
            break;
1192
        }
1193

    
1194
        target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
1195
        target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
1196
        target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
1197

    
1198
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1199
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1200
            memcpy(target_data, data, len);
1201
        } else {
1202
            int *fd = (int *)data;
1203
            int *target_fd = (int *)target_data;
1204
            int i, numfds = len / sizeof(int);
1205

    
1206
            for (i = 0; i < numfds; i++)
1207
                target_fd[i] = tswap32(fd[i]);
1208
        }
1209

    
1210
        cmsg = CMSG_NXTHDR(msgh, cmsg);
1211
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1212
    }
1213
    unlock_user(target_cmsg, target_cmsg_addr, space);
1214
 the_end:
1215
    target_msgh->msg_controllen = tswapl(space);
1216
    return 0;
1217
}
1218

    
1219
/* do_setsockopt() Must return target values and target errnos. */
1220
static abi_long do_setsockopt(int sockfd, int level, int optname,
1221
                              abi_ulong optval_addr, socklen_t optlen)
1222
{
1223
    abi_long ret;
1224
    int val;
1225
    struct ip_mreqn *ip_mreq;
1226
    struct ip_mreq_source *ip_mreq_source;
1227

    
1228
    switch(level) {
1229
    case SOL_TCP:
1230
        /* TCP options all take an 'int' value.  */
1231
        if (optlen < sizeof(uint32_t))
1232
            return -TARGET_EINVAL;
1233

    
1234
        if (get_user_u32(val, optval_addr))
1235
            return -TARGET_EFAULT;
1236
        ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1237
        break;
1238
    case SOL_IP:
1239
        switch(optname) {
1240
        case IP_TOS:
1241
        case IP_TTL:
1242
        case IP_HDRINCL:
1243
        case IP_ROUTER_ALERT:
1244
        case IP_RECVOPTS:
1245
        case IP_RETOPTS:
1246
        case IP_PKTINFO:
1247
        case IP_MTU_DISCOVER:
1248
        case IP_RECVERR:
1249
        case IP_RECVTOS:
1250
#ifdef IP_FREEBIND
1251
        case IP_FREEBIND:
1252
#endif
1253
        case IP_MULTICAST_TTL:
1254
        case IP_MULTICAST_LOOP:
1255
            val = 0;
1256
            if (optlen >= sizeof(uint32_t)) {
1257
                if (get_user_u32(val, optval_addr))
1258
                    return -TARGET_EFAULT;
1259
            } else if (optlen >= 1) {
1260
                if (get_user_u8(val, optval_addr))
1261
                    return -TARGET_EFAULT;
1262
            }
1263
            ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1264
            break;
1265
        case IP_ADD_MEMBERSHIP:
1266
        case IP_DROP_MEMBERSHIP:
1267
            if (optlen < sizeof (struct target_ip_mreq) ||
1268
                optlen > sizeof (struct target_ip_mreqn))
1269
                return -TARGET_EINVAL;
1270

    
1271
            ip_mreq = (struct ip_mreqn *) alloca(optlen);
1272
            target_to_host_ip_mreq(ip_mreq, optval_addr, optlen);
1273
            ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq, optlen));
1274
            break;
1275

    
1276
        case IP_BLOCK_SOURCE:
1277
        case IP_UNBLOCK_SOURCE:
1278
        case IP_ADD_SOURCE_MEMBERSHIP:
1279
        case IP_DROP_SOURCE_MEMBERSHIP:
1280
            if (optlen != sizeof (struct target_ip_mreq_source))
1281
                return -TARGET_EINVAL;
1282

    
1283
            ip_mreq_source = lock_user(VERIFY_READ, optval_addr, optlen, 1);
1284
            ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq_source, optlen));
1285
            unlock_user (ip_mreq_source, optval_addr, 0);
1286
            break;
1287

    
1288
        default:
1289
            goto unimplemented;
1290
        }
1291
        break;
1292
    case TARGET_SOL_SOCKET:
1293
        switch (optname) {
1294
            /* Options with 'int' argument.  */
1295
        case TARGET_SO_DEBUG:
1296
                optname = SO_DEBUG;
1297
                break;
1298
        case TARGET_SO_REUSEADDR:
1299
                optname = SO_REUSEADDR;
1300
                break;
1301
        case TARGET_SO_TYPE:
1302
                optname = SO_TYPE;
1303
                break;
1304
        case TARGET_SO_ERROR:
1305
                optname = SO_ERROR;
1306
                break;
1307
        case TARGET_SO_DONTROUTE:
1308
                optname = SO_DONTROUTE;
1309
                break;
1310
        case TARGET_SO_BROADCAST:
1311
                optname = SO_BROADCAST;
1312
                break;
1313
        case TARGET_SO_SNDBUF:
1314
                optname = SO_SNDBUF;
1315
                break;
1316
        case TARGET_SO_RCVBUF:
1317
                optname = SO_RCVBUF;
1318
                break;
1319
        case TARGET_SO_KEEPALIVE:
1320
                optname = SO_KEEPALIVE;
1321
                break;
1322
        case TARGET_SO_OOBINLINE:
1323
                optname = SO_OOBINLINE;
1324
                break;
1325
        case TARGET_SO_NO_CHECK:
1326
                optname = SO_NO_CHECK;
1327
                break;
1328
        case TARGET_SO_PRIORITY:
1329
                optname = SO_PRIORITY;
1330
                break;
1331
#ifdef SO_BSDCOMPAT
1332
        case TARGET_SO_BSDCOMPAT:
1333
                optname = SO_BSDCOMPAT;
1334
                break;
1335
#endif
1336
        case TARGET_SO_PASSCRED:
1337
                optname = SO_PASSCRED;
1338
                break;
1339
        case TARGET_SO_TIMESTAMP:
1340
                optname = SO_TIMESTAMP;
1341
                break;
1342
        case TARGET_SO_RCVLOWAT:
1343
                optname = SO_RCVLOWAT;
1344
                break;
1345
        case TARGET_SO_RCVTIMEO:
1346
                optname = SO_RCVTIMEO;
1347
                break;
1348
        case TARGET_SO_SNDTIMEO:
1349
                optname = SO_SNDTIMEO;
1350
                break;
1351
            break;
1352
        default:
1353
            goto unimplemented;
1354
        }
1355
        if (optlen < sizeof(uint32_t))
1356
            return -TARGET_EINVAL;
1357

    
1358
        if (get_user_u32(val, optval_addr))
1359
            return -TARGET_EFAULT;
1360
        ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
1361
        break;
1362
    default:
1363
    unimplemented:
1364
        gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
1365
        ret = -TARGET_ENOPROTOOPT;
1366
    }
1367
    return ret;
1368
}
1369

    
1370
/* do_getsockopt() Must return target values and target errnos. */
1371
static abi_long do_getsockopt(int sockfd, int level, int optname,
1372
                              abi_ulong optval_addr, abi_ulong optlen)
1373
{
1374
    abi_long ret;
1375
    int len, val;
1376
    socklen_t lv;
1377

    
1378
    switch(level) {
1379
    case TARGET_SOL_SOCKET:
1380
        level = SOL_SOCKET;
1381
        switch (optname) {
1382
        /* These don't just return a single integer */
1383
        case TARGET_SO_LINGER:
1384
        case TARGET_SO_RCVTIMEO:
1385
        case TARGET_SO_SNDTIMEO:
1386
        case TARGET_SO_PEERCRED:
1387
        case TARGET_SO_PEERNAME:
1388
            goto unimplemented;
1389
        /* Options with 'int' argument.  */
1390
        case TARGET_SO_DEBUG:
1391
            optname = SO_DEBUG;
1392
            goto int_case;
1393
        case TARGET_SO_REUSEADDR:
1394
            optname = SO_REUSEADDR;
1395
            goto int_case;
1396
        case TARGET_SO_TYPE:
1397
            optname = SO_TYPE;
1398
            goto int_case;
1399
        case TARGET_SO_ERROR:
1400
            optname = SO_ERROR;
1401
            goto int_case;
1402
        case TARGET_SO_DONTROUTE:
1403
            optname = SO_DONTROUTE;
1404
            goto int_case;
1405
        case TARGET_SO_BROADCAST:
1406
            optname = SO_BROADCAST;
1407
            goto int_case;
1408
        case TARGET_SO_SNDBUF:
1409
            optname = SO_SNDBUF;
1410
            goto int_case;
1411
        case TARGET_SO_RCVBUF:
1412
            optname = SO_RCVBUF;
1413
            goto int_case;
1414
        case TARGET_SO_KEEPALIVE:
1415
            optname = SO_KEEPALIVE;
1416
            goto int_case;
1417
        case TARGET_SO_OOBINLINE:
1418
            optname = SO_OOBINLINE;
1419
            goto int_case;
1420
        case TARGET_SO_NO_CHECK:
1421
            optname = SO_NO_CHECK;
1422
            goto int_case;
1423
        case TARGET_SO_PRIORITY:
1424
            optname = SO_PRIORITY;
1425
            goto int_case;
1426
#ifdef SO_BSDCOMPAT
1427
        case TARGET_SO_BSDCOMPAT:
1428
            optname = SO_BSDCOMPAT;
1429
            goto int_case;
1430
#endif
1431
        case TARGET_SO_PASSCRED:
1432
            optname = SO_PASSCRED;
1433
            goto int_case;
1434
        case TARGET_SO_TIMESTAMP:
1435
            optname = SO_TIMESTAMP;
1436
            goto int_case;
1437
        case TARGET_SO_RCVLOWAT:
1438
            optname = SO_RCVLOWAT;
1439
            goto int_case;
1440
        default:
1441
            goto int_case;
1442
        }
1443
        break;
1444
    case SOL_TCP:
1445
        /* TCP options all take an 'int' value.  */
1446
    int_case:
1447
        if (get_user_u32(len, optlen))
1448
            return -TARGET_EFAULT;
1449
        if (len < 0)
1450
            return -TARGET_EINVAL;
1451
        lv = sizeof(int);
1452
        ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1453
        if (ret < 0)
1454
            return ret;
1455
        if (len > lv)
1456
            len = lv;
1457
        if (len == 4) {
1458
            if (put_user_u32(val, optval_addr))
1459
                return -TARGET_EFAULT;
1460
        } else {
1461
            if (put_user_u8(val, optval_addr))
1462
                return -TARGET_EFAULT;
1463
        }
1464
        if (put_user_u32(len, optlen))
1465
            return -TARGET_EFAULT;
1466
        break;
1467
    case SOL_IP:
1468
        switch(optname) {
1469
        case IP_TOS:
1470
        case IP_TTL:
1471
        case IP_HDRINCL:
1472
        case IP_ROUTER_ALERT:
1473
        case IP_RECVOPTS:
1474
        case IP_RETOPTS:
1475
        case IP_PKTINFO:
1476
        case IP_MTU_DISCOVER:
1477
        case IP_RECVERR:
1478
        case IP_RECVTOS:
1479
#ifdef IP_FREEBIND
1480
        case IP_FREEBIND:
1481
#endif
1482
        case IP_MULTICAST_TTL:
1483
        case IP_MULTICAST_LOOP:
1484
            if (get_user_u32(len, optlen))
1485
                return -TARGET_EFAULT;
1486
            if (len < 0)
1487
                return -TARGET_EINVAL;
1488
            lv = sizeof(int);
1489
            ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1490
            if (ret < 0)
1491
                return ret;
1492
            if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
1493
                len = 1;
1494
                if (put_user_u32(len, optlen)
1495
                    || put_user_u8(val, optval_addr))
1496
                    return -TARGET_EFAULT;
1497
            } else {
1498
                if (len > sizeof(int))
1499
                    len = sizeof(int);
1500
                if (put_user_u32(len, optlen)
1501
                    || put_user_u32(val, optval_addr))
1502
                    return -TARGET_EFAULT;
1503
            }
1504
            break;
1505
        default:
1506
            ret = -TARGET_ENOPROTOOPT;
1507
            break;
1508
        }
1509
        break;
1510
    default:
1511
    unimplemented:
1512
        gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1513
                 level, optname);
1514
        ret = -TARGET_EOPNOTSUPP;
1515
        break;
1516
    }
1517
    return ret;
1518
}
1519

    
1520
/* FIXME
1521
 * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1522
 * other lock functions have a return code of 0 for failure.
1523
 */
1524
static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1525
                           int count, int copy)
1526
{
1527
    struct target_iovec *target_vec;
1528
    abi_ulong base;
1529
    int i;
1530

    
1531
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1532
    if (!target_vec)
1533
        return -TARGET_EFAULT;
1534
    for(i = 0;i < count; i++) {
1535
        base = tswapl(target_vec[i].iov_base);
1536
        vec[i].iov_len = tswapl(target_vec[i].iov_len);
1537
        if (vec[i].iov_len != 0) {
1538
            vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
1539
            /* Don't check lock_user return value. We must call writev even
1540
               if a element has invalid base address. */
1541
        } else {
1542
            /* zero length pointer is ignored */
1543
            vec[i].iov_base = NULL;
1544
        }
1545
    }
1546
    unlock_user (target_vec, target_addr, 0);
1547
    return 0;
1548
}
1549

    
1550
static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1551
                             int count, int copy)
1552
{
1553
    struct target_iovec *target_vec;
1554
    abi_ulong base;
1555
    int i;
1556

    
1557
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1558
    if (!target_vec)
1559
        return -TARGET_EFAULT;
1560
    for(i = 0;i < count; i++) {
1561
        if (target_vec[i].iov_base) {
1562
            base = tswapl(target_vec[i].iov_base);
1563
            unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1564
        }
1565
    }
1566
    unlock_user (target_vec, target_addr, 0);
1567

    
1568
    return 0;
1569
}
1570

    
1571
/* do_socket() Must return target values and target errnos. */
1572
static abi_long do_socket(int domain, int type, int protocol)
1573
{
1574
#if defined(TARGET_MIPS)
1575
    switch(type) {
1576
    case TARGET_SOCK_DGRAM:
1577
        type = SOCK_DGRAM;
1578
        break;
1579
    case TARGET_SOCK_STREAM:
1580
        type = SOCK_STREAM;
1581
        break;
1582
    case TARGET_SOCK_RAW:
1583
        type = SOCK_RAW;
1584
        break;
1585
    case TARGET_SOCK_RDM:
1586
        type = SOCK_RDM;
1587
        break;
1588
    case TARGET_SOCK_SEQPACKET:
1589
        type = SOCK_SEQPACKET;
1590
        break;
1591
    case TARGET_SOCK_PACKET:
1592
        type = SOCK_PACKET;
1593
        break;
1594
    }
1595
#endif
1596
    if (domain == PF_NETLINK)
1597
        return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1598
    return get_errno(socket(domain, type, protocol));
1599
}
1600

    
1601
/* do_bind() Must return target values and target errnos. */
1602
static abi_long do_bind(int sockfd, abi_ulong target_addr,
1603
                        socklen_t addrlen)
1604
{
1605
    void *addr;
1606
    abi_long ret;
1607

    
1608
    if ((int)addrlen < 0) {
1609
        return -TARGET_EINVAL;
1610
    }
1611

    
1612
    addr = alloca(addrlen+1);
1613

    
1614
    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1615
    if (ret)
1616
        return ret;
1617

    
1618
    return get_errno(bind(sockfd, addr, addrlen));
1619
}
1620

    
1621
/* do_connect() Must return target values and target errnos. */
1622
static abi_long do_connect(int sockfd, abi_ulong target_addr,
1623
                           socklen_t addrlen)
1624
{
1625
    void *addr;
1626
    abi_long ret;
1627

    
1628
    if ((int)addrlen < 0) {
1629
        return -TARGET_EINVAL;
1630
    }
1631

    
1632
    addr = alloca(addrlen);
1633

    
1634
    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1635
    if (ret)
1636
        return ret;
1637

    
1638
    return get_errno(connect(sockfd, addr, addrlen));
1639
}
1640

    
1641
/* do_sendrecvmsg() Must return target values and target errnos. */
1642
static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1643
                               int flags, int send)
1644
{
1645
    abi_long ret, len;
1646
    struct target_msghdr *msgp;
1647
    struct msghdr msg;
1648
    int count;
1649
    struct iovec *vec;
1650
    abi_ulong target_vec;
1651

    
1652
    /* FIXME */
1653
    if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1654
                          msgp,
1655
                          target_msg,
1656
                          send ? 1 : 0))
1657
        return -TARGET_EFAULT;
1658
    if (msgp->msg_name) {
1659
        msg.msg_namelen = tswap32(msgp->msg_namelen);
1660
        msg.msg_name = alloca(msg.msg_namelen);
1661
        ret = target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
1662
                                msg.msg_namelen);
1663
        if (ret) {
1664
            unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1665
            return ret;
1666
        }
1667
    } else {
1668
        msg.msg_name = NULL;
1669
        msg.msg_namelen = 0;
1670
    }
1671
    msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
1672
    msg.msg_control = alloca(msg.msg_controllen);
1673
    msg.msg_flags = tswap32(msgp->msg_flags);
1674

    
1675
    count = tswapl(msgp->msg_iovlen);
1676
    vec = alloca(count * sizeof(struct iovec));
1677
    target_vec = tswapl(msgp->msg_iov);
1678
    lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1679
    msg.msg_iovlen = count;
1680
    msg.msg_iov = vec;
1681

    
1682
    if (send) {
1683
        ret = target_to_host_cmsg(&msg, msgp);
1684
        if (ret == 0)
1685
            ret = get_errno(sendmsg(fd, &msg, flags));
1686
    } else {
1687
        ret = get_errno(recvmsg(fd, &msg, flags));
1688
        if (!is_error(ret)) {
1689
            len = ret;
1690
            ret = host_to_target_cmsg(msgp, &msg);
1691
            if (!is_error(ret))
1692
                ret = len;
1693
        }
1694
    }
1695
    unlock_iovec(vec, target_vec, count, !send);
1696
    unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1697
    return ret;
1698
}
1699

    
1700
/* do_accept() Must return target values and target errnos. */
1701
static abi_long do_accept(int fd, abi_ulong target_addr,
1702
                          abi_ulong target_addrlen_addr)
1703
{
1704
    socklen_t addrlen;
1705
    void *addr;
1706
    abi_long ret;
1707

    
1708
    if (target_addr == 0)
1709
       return get_errno(accept(fd, NULL, NULL));
1710

    
1711
    /* linux returns EINVAL if addrlen pointer is invalid */
1712
    if (get_user_u32(addrlen, target_addrlen_addr))
1713
        return -TARGET_EINVAL;
1714

    
1715
    if ((int)addrlen < 0) {
1716
        return -TARGET_EINVAL;
1717
    }
1718

    
1719
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1720
        return -TARGET_EINVAL;
1721

    
1722
    addr = alloca(addrlen);
1723

    
1724
    ret = get_errno(accept(fd, addr, &addrlen));
1725
    if (!is_error(ret)) {
1726
        host_to_target_sockaddr(target_addr, addr, addrlen);
1727
        if (put_user_u32(addrlen, target_addrlen_addr))
1728
            ret = -TARGET_EFAULT;
1729
    }
1730
    return ret;
1731
}
1732

    
1733
/* do_getpeername() Must return target values and target errnos. */
1734
static abi_long do_getpeername(int fd, abi_ulong target_addr,
1735
                               abi_ulong target_addrlen_addr)
1736
{
1737
    socklen_t addrlen;
1738
    void *addr;
1739
    abi_long ret;
1740

    
1741
    if (get_user_u32(addrlen, target_addrlen_addr))
1742
        return -TARGET_EFAULT;
1743

    
1744
    if ((int)addrlen < 0) {
1745
        return -TARGET_EINVAL;
1746
    }
1747

    
1748
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1749
        return -TARGET_EFAULT;
1750

    
1751
    addr = alloca(addrlen);
1752

    
1753
    ret = get_errno(getpeername(fd, addr, &addrlen));
1754
    if (!is_error(ret)) {
1755
        host_to_target_sockaddr(target_addr, addr, addrlen);
1756
        if (put_user_u32(addrlen, target_addrlen_addr))
1757
            ret = -TARGET_EFAULT;
1758
    }
1759
    return ret;
1760
}
1761

    
1762
/* do_getsockname() Must return target values and target errnos. */
1763
static abi_long do_getsockname(int fd, abi_ulong target_addr,
1764
                               abi_ulong target_addrlen_addr)
1765
{
1766
    socklen_t addrlen;
1767
    void *addr;
1768
    abi_long ret;
1769

    
1770
    if (get_user_u32(addrlen, target_addrlen_addr))
1771
        return -TARGET_EFAULT;
1772

    
1773
    if ((int)addrlen < 0) {
1774
        return -TARGET_EINVAL;
1775
    }
1776

    
1777
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1778
        return -TARGET_EFAULT;
1779

    
1780
    addr = alloca(addrlen);
1781

    
1782
    ret = get_errno(getsockname(fd, addr, &addrlen));
1783
    if (!is_error(ret)) {
1784
        host_to_target_sockaddr(target_addr, addr, addrlen);
1785
        if (put_user_u32(addrlen, target_addrlen_addr))
1786
            ret = -TARGET_EFAULT;
1787
    }
1788
    return ret;
1789
}
1790

    
1791
/* do_socketpair() Must return target values and target errnos. */
1792
static abi_long do_socketpair(int domain, int type, int protocol,
1793
                              abi_ulong target_tab_addr)
1794
{
1795
    int tab[2];
1796
    abi_long ret;
1797

    
1798
    ret = get_errno(socketpair(domain, type, protocol, tab));
1799
    if (!is_error(ret)) {
1800
        if (put_user_s32(tab[0], target_tab_addr)
1801
            || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1802
            ret = -TARGET_EFAULT;
1803
    }
1804
    return ret;
1805
}
1806

    
1807
/* do_sendto() Must return target values and target errnos. */
1808
static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
1809
                          abi_ulong target_addr, socklen_t addrlen)
1810
{
1811
    void *addr;
1812
    void *host_msg;
1813
    abi_long ret;
1814

    
1815
    if ((int)addrlen < 0) {
1816
        return -TARGET_EINVAL;
1817
    }
1818

    
1819
    host_msg = lock_user(VERIFY_READ, msg, len, 1);
1820
    if (!host_msg)
1821
        return -TARGET_EFAULT;
1822
    if (target_addr) {
1823
        addr = alloca(addrlen);
1824
        ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1825
        if (ret) {
1826
            unlock_user(host_msg, msg, 0);
1827
            return ret;
1828
        }
1829
        ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
1830
    } else {
1831
        ret = get_errno(send(fd, host_msg, len, flags));
1832
    }
1833
    unlock_user(host_msg, msg, 0);
1834
    return ret;
1835
}
1836

    
1837
/* do_recvfrom() Must return target values and target errnos. */
1838
static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
1839
                            abi_ulong target_addr,
1840
                            abi_ulong target_addrlen)
1841
{
1842
    socklen_t addrlen;
1843
    void *addr;
1844
    void *host_msg;
1845
    abi_long ret;
1846

    
1847
    host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
1848
    if (!host_msg)
1849
        return -TARGET_EFAULT;
1850
    if (target_addr) {
1851
        if (get_user_u32(addrlen, target_addrlen)) {
1852
            ret = -TARGET_EFAULT;
1853
            goto fail;
1854
        }
1855
        if ((int)addrlen < 0) {
1856
            ret = -TARGET_EINVAL;
1857
            goto fail;
1858
        }
1859
        addr = alloca(addrlen);
1860
        ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
1861
    } else {
1862
        addr = NULL; /* To keep compiler quiet.  */
1863
        ret = get_errno(recv(fd, host_msg, len, flags));
1864
    }
1865
    if (!is_error(ret)) {
1866
        if (target_addr) {
1867
            host_to_target_sockaddr(target_addr, addr, addrlen);
1868
            if (put_user_u32(addrlen, target_addrlen)) {
1869
                ret = -TARGET_EFAULT;
1870
                goto fail;
1871
            }
1872
        }
1873
        unlock_user(host_msg, msg, len);
1874
    } else {
1875
fail:
1876
        unlock_user(host_msg, msg, 0);
1877
    }
1878
    return ret;
1879
}
1880

    
1881
#ifdef TARGET_NR_socketcall
1882
/* do_socketcall() Must return target values and target errnos. */
1883
static abi_long do_socketcall(int num, abi_ulong vptr)
1884
{
1885
    abi_long ret;
1886
    const int n = sizeof(abi_ulong);
1887

    
1888
    switch(num) {
1889
    case SOCKOP_socket:
1890
        {
1891
            abi_ulong domain, type, protocol;
1892

    
1893
            if (get_user_ual(domain, vptr)
1894
                || get_user_ual(type, vptr + n)
1895
                || get_user_ual(protocol, vptr + 2 * n))
1896
                return -TARGET_EFAULT;
1897

    
1898
            ret = do_socket(domain, type, protocol);
1899
        }
1900
        break;
1901
    case SOCKOP_bind:
1902
        {
1903
            abi_ulong sockfd;
1904
            abi_ulong target_addr;
1905
            socklen_t addrlen;
1906

    
1907
            if (get_user_ual(sockfd, vptr)
1908
                || get_user_ual(target_addr, vptr + n)
1909
                || get_user_ual(addrlen, vptr + 2 * n))
1910
                return -TARGET_EFAULT;
1911

    
1912
            ret = do_bind(sockfd, target_addr, addrlen);
1913
        }
1914
        break;
1915
    case SOCKOP_connect:
1916
        {
1917
            abi_ulong sockfd;
1918
            abi_ulong target_addr;
1919
            socklen_t addrlen;
1920

    
1921
            if (get_user_ual(sockfd, vptr)
1922
                || get_user_ual(target_addr, vptr + n)
1923
                || get_user_ual(addrlen, vptr + 2 * n))
1924
                return -TARGET_EFAULT;
1925

    
1926
            ret = do_connect(sockfd, target_addr, addrlen);
1927
        }
1928
        break;
1929
    case SOCKOP_listen:
1930
        {
1931
            abi_ulong sockfd, backlog;
1932

    
1933
            if (get_user_ual(sockfd, vptr)
1934
                || get_user_ual(backlog, vptr + n))
1935
                return -TARGET_EFAULT;
1936

    
1937
            ret = get_errno(listen(sockfd, backlog));
1938
        }
1939
        break;
1940
    case SOCKOP_accept:
1941
        {
1942
            abi_ulong sockfd;
1943
            abi_ulong target_addr, target_addrlen;
1944

    
1945
            if (get_user_ual(sockfd, vptr)
1946
                || get_user_ual(target_addr, vptr + n)
1947
                || get_user_ual(target_addrlen, vptr + 2 * n))
1948
                return -TARGET_EFAULT;
1949

    
1950
            ret = do_accept(sockfd, target_addr, target_addrlen);
1951
        }
1952
        break;
1953
    case SOCKOP_getsockname:
1954
        {
1955
            abi_ulong sockfd;
1956
            abi_ulong target_addr, target_addrlen;
1957

    
1958
            if (get_user_ual(sockfd, vptr)
1959
                || get_user_ual(target_addr, vptr + n)
1960
                || get_user_ual(target_addrlen, vptr + 2 * n))
1961
                return -TARGET_EFAULT;
1962

    
1963
            ret = do_getsockname(sockfd, target_addr, target_addrlen);
1964
        }
1965
        break;
1966
    case SOCKOP_getpeername:
1967
        {
1968
            abi_ulong sockfd;
1969
            abi_ulong target_addr, target_addrlen;
1970

    
1971
            if (get_user_ual(sockfd, vptr)
1972
                || get_user_ual(target_addr, vptr + n)
1973
                || get_user_ual(target_addrlen, vptr + 2 * n))
1974
                return -TARGET_EFAULT;
1975

    
1976
            ret = do_getpeername(sockfd, target_addr, target_addrlen);
1977
        }
1978
        break;
1979
    case SOCKOP_socketpair:
1980
        {
1981
            abi_ulong domain, type, protocol;
1982
            abi_ulong tab;
1983

    
1984
            if (get_user_ual(domain, vptr)
1985
                || get_user_ual(type, vptr + n)
1986
                || get_user_ual(protocol, vptr + 2 * n)
1987
                || get_user_ual(tab, vptr + 3 * n))
1988
                return -TARGET_EFAULT;
1989

    
1990
            ret = do_socketpair(domain, type, protocol, tab);
1991
        }
1992
        break;
1993
    case SOCKOP_send:
1994
        {
1995
            abi_ulong sockfd;
1996
            abi_ulong msg;
1997
            size_t len;
1998
            abi_ulong flags;
1999

    
2000
            if (get_user_ual(sockfd, vptr)
2001
                || get_user_ual(msg, vptr + n)
2002
                || get_user_ual(len, vptr + 2 * n)
2003
                || get_user_ual(flags, vptr + 3 * n))
2004
                return -TARGET_EFAULT;
2005

    
2006
            ret = do_sendto(sockfd, msg, len, flags, 0, 0);
2007
        }
2008
        break;
2009
    case SOCKOP_recv:
2010
        {
2011
            abi_ulong sockfd;
2012
            abi_ulong msg;
2013
            size_t len;
2014
            abi_ulong flags;
2015

    
2016
            if (get_user_ual(sockfd, vptr)
2017
                || get_user_ual(msg, vptr + n)
2018
                || get_user_ual(len, vptr + 2 * n)
2019
                || get_user_ual(flags, vptr + 3 * n))
2020
                return -TARGET_EFAULT;
2021

    
2022
            ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
2023
        }
2024
        break;
2025
    case SOCKOP_sendto:
2026
        {
2027
            abi_ulong sockfd;
2028
            abi_ulong msg;
2029
            size_t len;
2030
            abi_ulong flags;
2031
            abi_ulong addr;
2032
            socklen_t addrlen;
2033

    
2034
            if (get_user_ual(sockfd, vptr)
2035
                || get_user_ual(msg, vptr + n)
2036
                || get_user_ual(len, vptr + 2 * n)
2037
                || get_user_ual(flags, vptr + 3 * n)
2038
                || get_user_ual(addr, vptr + 4 * n)
2039
                || get_user_ual(addrlen, vptr + 5 * n))
2040
                return -TARGET_EFAULT;
2041

    
2042
            ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
2043
        }
2044
        break;
2045
    case SOCKOP_recvfrom:
2046
        {
2047
            abi_ulong sockfd;
2048
            abi_ulong msg;
2049
            size_t len;
2050
            abi_ulong flags;
2051
            abi_ulong addr;
2052
            socklen_t addrlen;
2053

    
2054
            if (get_user_ual(sockfd, vptr)
2055
                || get_user_ual(msg, vptr + n)
2056
                || get_user_ual(len, vptr + 2 * n)
2057
                || get_user_ual(flags, vptr + 3 * n)
2058
                || get_user_ual(addr, vptr + 4 * n)
2059
                || get_user_ual(addrlen, vptr + 5 * n))
2060
                return -TARGET_EFAULT;
2061

    
2062
            ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
2063
        }
2064
        break;
2065
    case SOCKOP_shutdown:
2066
        {
2067
            abi_ulong sockfd, how;
2068

    
2069
            if (get_user_ual(sockfd, vptr)
2070
                || get_user_ual(how, vptr + n))
2071
                return -TARGET_EFAULT;
2072

    
2073
            ret = get_errno(shutdown(sockfd, how));
2074
        }
2075
        break;
2076
    case SOCKOP_sendmsg:
2077
    case SOCKOP_recvmsg:
2078
        {
2079
            abi_ulong fd;
2080
            abi_ulong target_msg;
2081
            abi_ulong flags;
2082

    
2083
            if (get_user_ual(fd, vptr)
2084
                || get_user_ual(target_msg, vptr + n)
2085
                || get_user_ual(flags, vptr + 2 * n))
2086
                return -TARGET_EFAULT;
2087

    
2088
            ret = do_sendrecvmsg(fd, target_msg, flags,
2089
                                 (num == SOCKOP_sendmsg));
2090
        }
2091
        break;
2092
    case SOCKOP_setsockopt:
2093
        {
2094
            abi_ulong sockfd;
2095
            abi_ulong level;
2096
            abi_ulong optname;
2097
            abi_ulong optval;
2098
            socklen_t optlen;
2099

    
2100
            if (get_user_ual(sockfd, vptr)
2101
                || get_user_ual(level, vptr + n)
2102
                || get_user_ual(optname, vptr + 2 * n)
2103
                || get_user_ual(optval, vptr + 3 * n)
2104
                || get_user_ual(optlen, vptr + 4 * n))
2105
                return -TARGET_EFAULT;
2106

    
2107
            ret = do_setsockopt(sockfd, level, optname, optval, optlen);
2108
        }
2109
        break;
2110
    case SOCKOP_getsockopt:
2111
        {
2112
            abi_ulong sockfd;
2113
            abi_ulong level;
2114
            abi_ulong optname;
2115
            abi_ulong optval;
2116
            socklen_t optlen;
2117

    
2118
            if (get_user_ual(sockfd, vptr)
2119
                || get_user_ual(level, vptr + n)
2120
                || get_user_ual(optname, vptr + 2 * n)
2121
                || get_user_ual(optval, vptr + 3 * n)
2122
                || get_user_ual(optlen, vptr + 4 * n))
2123
                return -TARGET_EFAULT;
2124

    
2125
            ret = do_getsockopt(sockfd, level, optname, optval, optlen);
2126
        }
2127
        break;
2128
    default:
2129
        gemu_log("Unsupported socketcall: %d\n", num);
2130
        ret = -TARGET_ENOSYS;
2131
        break;
2132
    }
2133
    return ret;
2134
}
2135
#endif
2136

    
2137
#define N_SHM_REGIONS        32
2138

    
2139
static struct shm_region {
2140
    abi_ulong        start;
2141
    abi_ulong        size;
2142
} shm_regions[N_SHM_REGIONS];
2143

    
2144
struct target_ipc_perm
2145
{
2146
    abi_long __key;
2147
    abi_ulong uid;
2148
    abi_ulong gid;
2149
    abi_ulong cuid;
2150
    abi_ulong cgid;
2151
    unsigned short int mode;
2152
    unsigned short int __pad1;
2153
    unsigned short int __seq;
2154
    unsigned short int __pad2;
2155
    abi_ulong __unused1;
2156
    abi_ulong __unused2;
2157
};
2158

    
2159
struct target_semid_ds
2160
{
2161
  struct target_ipc_perm sem_perm;
2162
  abi_ulong sem_otime;
2163
  abi_ulong __unused1;
2164
  abi_ulong sem_ctime;
2165
  abi_ulong __unused2;
2166
  abi_ulong sem_nsems;
2167
  abi_ulong __unused3;
2168
  abi_ulong __unused4;
2169
};
2170

    
2171
static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
2172
                                               abi_ulong target_addr)
2173
{
2174
    struct target_ipc_perm *target_ip;
2175
    struct target_semid_ds *target_sd;
2176

    
2177
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2178
        return -TARGET_EFAULT;
2179
    target_ip = &(target_sd->sem_perm);
2180
    host_ip->__key = tswapl(target_ip->__key);
2181
    host_ip->uid = tswapl(target_ip->uid);
2182
    host_ip->gid = tswapl(target_ip->gid);
2183
    host_ip->cuid = tswapl(target_ip->cuid);
2184
    host_ip->cgid = tswapl(target_ip->cgid);
2185
    host_ip->mode = tswapl(target_ip->mode);
2186
    unlock_user_struct(target_sd, target_addr, 0);
2187
    return 0;
2188
}
2189

    
2190
static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
2191
                                               struct ipc_perm *host_ip)
2192
{
2193
    struct target_ipc_perm *target_ip;
2194
    struct target_semid_ds *target_sd;
2195

    
2196
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2197
        return -TARGET_EFAULT;
2198
    target_ip = &(target_sd->sem_perm);
2199
    target_ip->__key = tswapl(host_ip->__key);
2200
    target_ip->uid = tswapl(host_ip->uid);
2201
    target_ip->gid = tswapl(host_ip->gid);
2202
    target_ip->cuid = tswapl(host_ip->cuid);
2203
    target_ip->cgid = tswapl(host_ip->cgid);
2204
    target_ip->mode = tswapl(host_ip->mode);
2205
    unlock_user_struct(target_sd, target_addr, 1);
2206
    return 0;
2207
}
2208

    
2209
static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
2210
                                               abi_ulong target_addr)
2211
{
2212
    struct target_semid_ds *target_sd;
2213

    
2214
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2215
        return -TARGET_EFAULT;
2216
    if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr))
2217
        return -TARGET_EFAULT;
2218
    host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
2219
    host_sd->sem_otime = tswapl(target_sd->sem_otime);
2220
    host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
2221
    unlock_user_struct(target_sd, target_addr, 0);
2222
    return 0;
2223
}
2224

    
2225
static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
2226
                                               struct semid_ds *host_sd)
2227
{
2228
    struct target_semid_ds *target_sd;
2229

    
2230
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2231
        return -TARGET_EFAULT;
2232
    if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
2233
        return -TARGET_EFAULT;;
2234
    target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
2235
    target_sd->sem_otime = tswapl(host_sd->sem_otime);
2236
    target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
2237
    unlock_user_struct(target_sd, target_addr, 1);
2238
    return 0;
2239
}
2240

    
2241
struct target_seminfo {
2242
    int semmap;
2243
    int semmni;
2244
    int semmns;
2245
    int semmnu;
2246
    int semmsl;
2247
    int semopm;
2248
    int semume;
2249
    int semusz;
2250
    int semvmx;
2251
    int semaem;
2252
};
2253

    
2254
static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
2255
                                              struct seminfo *host_seminfo)
2256
{
2257
    struct target_seminfo *target_seminfo;
2258
    if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
2259
        return -TARGET_EFAULT;
2260
    __put_user(host_seminfo->semmap, &target_seminfo->semmap);
2261
    __put_user(host_seminfo->semmni, &target_seminfo->semmni);
2262
    __put_user(host_seminfo->semmns, &target_seminfo->semmns);
2263
    __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
2264
    __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
2265
    __put_user(host_seminfo->semopm, &target_seminfo->semopm);
2266
    __put_user(host_seminfo->semume, &target_seminfo->semume);
2267
    __put_user(host_seminfo->semusz, &target_seminfo->semusz);
2268
    __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
2269
    __put_user(host_seminfo->semaem, &target_seminfo->semaem);
2270
    unlock_user_struct(target_seminfo, target_addr, 1);
2271
    return 0;
2272
}
2273

    
2274
union semun {
2275
        int val;
2276
        struct semid_ds *buf;
2277
        unsigned short *array;
2278
        struct seminfo *__buf;
2279
};
2280

    
2281
union target_semun {
2282
        int val;
2283
        abi_ulong buf;
2284
        abi_ulong array;
2285
        abi_ulong __buf;
2286
};
2287

    
2288
static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
2289
                                               abi_ulong target_addr)
2290
{
2291
    int nsems;
2292
    unsigned short *array;
2293
    union semun semun;
2294
    struct semid_ds semid_ds;
2295
    int i, ret;
2296

    
2297
    semun.buf = &semid_ds;
2298

    
2299
    ret = semctl(semid, 0, IPC_STAT, semun);
2300
    if (ret == -1)
2301
        return get_errno(ret);
2302

    
2303
    nsems = semid_ds.sem_nsems;
2304

    
2305
    *host_array = malloc(nsems*sizeof(unsigned short));
2306
    array = lock_user(VERIFY_READ, target_addr,
2307
                      nsems*sizeof(unsigned short), 1);
2308
    if (!array)
2309
        return -TARGET_EFAULT;
2310

    
2311
    for(i=0; i<nsems; i++) {
2312
        __get_user((*host_array)[i], &array[i]);
2313
    }
2314
    unlock_user(array, target_addr, 0);
2315

    
2316
    return 0;
2317
}
2318

    
2319
static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
2320
                                               unsigned short **host_array)
2321
{
2322
    int nsems;
2323
    unsigned short *array;
2324
    union semun semun;
2325
    struct semid_ds semid_ds;
2326
    int i, ret;
2327

    
2328
    semun.buf = &semid_ds;
2329

    
2330
    ret = semctl(semid, 0, IPC_STAT, semun);
2331
    if (ret == -1)
2332
        return get_errno(ret);
2333

    
2334
    nsems = semid_ds.sem_nsems;
2335

    
2336
    array = lock_user(VERIFY_WRITE, target_addr,
2337
                      nsems*sizeof(unsigned short), 0);
2338
    if (!array)
2339
        return -TARGET_EFAULT;
2340

    
2341
    for(i=0; i<nsems; i++) {
2342
        __put_user((*host_array)[i], &array[i]);
2343
    }
2344
    free(*host_array);
2345
    unlock_user(array, target_addr, 1);
2346

    
2347
    return 0;
2348
}
2349

    
2350
static inline abi_long do_semctl(int semid, int semnum, int cmd,
2351
                                 union target_semun target_su)
2352
{
2353
    union semun arg;
2354
    struct semid_ds dsarg;
2355
    unsigned short *array = NULL;
2356
    struct seminfo seminfo;
2357
    abi_long ret = -TARGET_EINVAL;
2358
    abi_long err;
2359
    cmd &= 0xff;
2360

    
2361
    switch( cmd ) {
2362
        case GETVAL:
2363
        case SETVAL:
2364
            arg.val = tswapl(target_su.val);
2365
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2366
            target_su.val = tswapl(arg.val);
2367
            break;
2368
        case GETALL:
2369
        case SETALL:
2370
            err = target_to_host_semarray(semid, &array, target_su.array);
2371
            if (err)
2372
                return err;
2373
            arg.array = array;
2374
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2375
            err = host_to_target_semarray(semid, target_su.array, &array);
2376
            if (err)
2377
                return err;
2378
            break;
2379
        case IPC_STAT:
2380
        case IPC_SET:
2381
        case SEM_STAT:
2382
            err = target_to_host_semid_ds(&dsarg, target_su.buf);
2383
            if (err)
2384
                return err;
2385
            arg.buf = &dsarg;
2386
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2387
            err = host_to_target_semid_ds(target_su.buf, &dsarg);
2388
            if (err)
2389
                return err;
2390
            break;
2391
        case IPC_INFO:
2392
        case SEM_INFO:
2393
            arg.__buf = &seminfo;
2394
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2395
            err = host_to_target_seminfo(target_su.__buf, &seminfo);
2396
            if (err)
2397
                return err;
2398
            break;
2399
        case IPC_RMID:
2400
        case GETPID:
2401
        case GETNCNT:
2402
        case GETZCNT:
2403
            ret = get_errno(semctl(semid, semnum, cmd, NULL));
2404
            break;
2405
    }
2406

    
2407
    return ret;
2408
}
2409

    
2410
struct target_sembuf {
2411
    unsigned short sem_num;
2412
    short sem_op;
2413
    short sem_flg;
2414
};
2415

    
2416
static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
2417
                                             abi_ulong target_addr,
2418
                                             unsigned nsops)
2419
{
2420
    struct target_sembuf *target_sembuf;
2421
    int i;
2422

    
2423
    target_sembuf = lock_user(VERIFY_READ, target_addr,
2424
                              nsops*sizeof(struct target_sembuf), 1);
2425
    if (!target_sembuf)
2426
        return -TARGET_EFAULT;
2427

    
2428
    for(i=0; i<nsops; i++) {
2429
        __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
2430
        __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
2431
        __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
2432
    }
2433

    
2434
    unlock_user(target_sembuf, target_addr, 0);
2435

    
2436
    return 0;
2437
}
2438

    
2439
static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
2440
{
2441
    struct sembuf sops[nsops];
2442

    
2443
    if (target_to_host_sembuf(sops, ptr, nsops))
2444
        return -TARGET_EFAULT;
2445

    
2446
    return semop(semid, sops, nsops);
2447
}
2448

    
2449
struct target_msqid_ds
2450
{
2451
    struct target_ipc_perm msg_perm;
2452
    abi_ulong msg_stime;
2453
#if TARGET_ABI_BITS == 32
2454
    abi_ulong __unused1;
2455
#endif
2456
    abi_ulong msg_rtime;
2457
#if TARGET_ABI_BITS == 32
2458
    abi_ulong __unused2;
2459
#endif
2460
    abi_ulong msg_ctime;
2461
#if TARGET_ABI_BITS == 32
2462
    abi_ulong __unused3;
2463
#endif
2464
    abi_ulong __msg_cbytes;
2465
    abi_ulong msg_qnum;
2466
    abi_ulong msg_qbytes;
2467
    abi_ulong msg_lspid;
2468
    abi_ulong msg_lrpid;
2469
    abi_ulong __unused4;
2470
    abi_ulong __unused5;
2471
};
2472

    
2473
static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
2474
                                               abi_ulong target_addr)
2475
{
2476
    struct target_msqid_ds *target_md;
2477

    
2478
    if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
2479
        return -TARGET_EFAULT;
2480
    if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
2481
        return -TARGET_EFAULT;
2482
    host_md->msg_stime = tswapl(target_md->msg_stime);
2483
    host_md->msg_rtime = tswapl(target_md->msg_rtime);
2484
    host_md->msg_ctime = tswapl(target_md->msg_ctime);
2485
    host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
2486
    host_md->msg_qnum = tswapl(target_md->msg_qnum);
2487
    host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
2488
    host_md->msg_lspid = tswapl(target_md->msg_lspid);
2489
    host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
2490
    unlock_user_struct(target_md, target_addr, 0);
2491
    return 0;
2492
}
2493

    
2494
static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
2495
                                               struct msqid_ds *host_md)
2496
{
2497
    struct target_msqid_ds *target_md;
2498

    
2499
    if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
2500
        return -TARGET_EFAULT;
2501
    if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
2502
        return -TARGET_EFAULT;
2503
    target_md->msg_stime = tswapl(host_md->msg_stime);
2504
    target_md->msg_rtime = tswapl(host_md->msg_rtime);
2505
    target_md->msg_ctime = tswapl(host_md->msg_ctime);
2506
    target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
2507
    target_md->msg_qnum = tswapl(host_md->msg_qnum);
2508
    target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
2509
    target_md->msg_lspid = tswapl(host_md->msg_lspid);
2510
    target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
2511
    unlock_user_struct(target_md, target_addr, 1);
2512
    return 0;
2513
}
2514

    
2515
struct target_msginfo {
2516
    int msgpool;
2517
    int msgmap;
2518
    int msgmax;
2519
    int msgmnb;
2520
    int msgmni;
2521
    int msgssz;
2522
    int msgtql;
2523
    unsigned short int msgseg;
2524
};
2525

    
2526
static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
2527
                                              struct msginfo *host_msginfo)
2528
{
2529
    struct target_msginfo *target_msginfo;
2530
    if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
2531
        return -TARGET_EFAULT;
2532
    __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
2533
    __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
2534
    __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
2535
    __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
2536
    __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
2537
    __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
2538
    __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
2539
    __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
2540
    unlock_user_struct(target_msginfo, target_addr, 1);
2541
    return 0;
2542
}
2543

    
2544
static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
2545
{
2546
    struct msqid_ds dsarg;
2547
    struct msginfo msginfo;
2548
    abi_long ret = -TARGET_EINVAL;
2549

    
2550
    cmd &= 0xff;
2551

    
2552
    switch (cmd) {
2553
    case IPC_STAT:
2554
    case IPC_SET:
2555
    case MSG_STAT:
2556
        if (target_to_host_msqid_ds(&dsarg,ptr))
2557
            return -TARGET_EFAULT;
2558
        ret = get_errno(msgctl(msgid, cmd, &dsarg));
2559
        if (host_to_target_msqid_ds(ptr,&dsarg))
2560
            return -TARGET_EFAULT;
2561
        break;
2562
    case IPC_RMID:
2563
        ret = get_errno(msgctl(msgid, cmd, NULL));
2564
        break;
2565
    case IPC_INFO:
2566
    case MSG_INFO:
2567
        ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
2568
        if (host_to_target_msginfo(ptr, &msginfo))
2569
            return -TARGET_EFAULT;
2570
        break;
2571
    }
2572

    
2573
    return ret;
2574
}
2575

    
2576
struct target_msgbuf {
2577
    abi_long mtype;
2578
    char        mtext[1];
2579
};
2580

    
2581
static inline abi_long do_msgsnd(int msqid, abi_long msgp,
2582
                                 unsigned int msgsz, int msgflg)
2583
{
2584
    struct target_msgbuf *target_mb;
2585
    struct msgbuf *host_mb;
2586
    abi_long ret = 0;
2587

    
2588
    if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
2589
        return -TARGET_EFAULT;
2590
    host_mb = malloc(msgsz+sizeof(long));
2591
    host_mb->mtype = (abi_long) tswapl(target_mb->mtype);
2592
    memcpy(host_mb->mtext, target_mb->mtext, msgsz);
2593
    ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
2594
    free(host_mb);
2595
    unlock_user_struct(target_mb, msgp, 0);
2596

    
2597
    return ret;
2598
}
2599

    
2600
static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2601
                                 unsigned int msgsz, abi_long msgtyp,
2602
                                 int msgflg)
2603
{
2604
    struct target_msgbuf *target_mb;
2605
    char *target_mtext;
2606
    struct msgbuf *host_mb;
2607
    abi_long ret = 0;
2608

    
2609
    if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2610
        return -TARGET_EFAULT;
2611

    
2612
    host_mb = malloc(msgsz+sizeof(long));
2613
    ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapl(msgtyp), msgflg));
2614

    
2615
    if (ret > 0) {
2616
        abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2617
        target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2618
        if (!target_mtext) {
2619
            ret = -TARGET_EFAULT;
2620
            goto end;
2621
        }
2622
        memcpy(target_mb->mtext, host_mb->mtext, ret);
2623
        unlock_user(target_mtext, target_mtext_addr, ret);
2624
    }
2625

    
2626
    target_mb->mtype = tswapl(host_mb->mtype);
2627
    free(host_mb);
2628

    
2629
end:
2630
    if (target_mb)
2631
        unlock_user_struct(target_mb, msgp, 1);
2632
    return ret;
2633
}
2634

    
2635
struct target_shmid_ds
2636
{
2637
    struct target_ipc_perm shm_perm;
2638
    abi_ulong shm_segsz;
2639
    abi_ulong shm_atime;
2640
#if TARGET_ABI_BITS == 32
2641
    abi_ulong __unused1;
2642
#endif
2643
    abi_ulong shm_dtime;
2644
#if TARGET_ABI_BITS == 32
2645
    abi_ulong __unused2;
2646
#endif
2647
    abi_ulong shm_ctime;
2648
#if TARGET_ABI_BITS == 32
2649
    abi_ulong __unused3;
2650
#endif
2651
    int shm_cpid;
2652
    int shm_lpid;
2653
    abi_ulong shm_nattch;
2654
    unsigned long int __unused4;
2655
    unsigned long int __unused5;
2656
};
2657

    
2658
static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
2659
                                               abi_ulong target_addr)
2660
{
2661
    struct target_shmid_ds *target_sd;
2662

    
2663
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2664
        return -TARGET_EFAULT;
2665
    if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr))
2666
        return -TARGET_EFAULT;
2667
    __get_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2668
    __get_user(host_sd->shm_atime, &target_sd->shm_atime);
2669
    __get_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2670
    __get_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2671
    __get_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2672
    __get_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2673
    __get_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2674
    unlock_user_struct(target_sd, target_addr, 0);
2675
    return 0;
2676
}
2677

    
2678
static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
2679
                                               struct shmid_ds *host_sd)
2680
{
2681
    struct target_shmid_ds *target_sd;
2682

    
2683
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2684
        return -TARGET_EFAULT;
2685
    if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm)))
2686
        return -TARGET_EFAULT;
2687
    __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2688
    __put_user(host_sd->shm_atime, &target_sd->shm_atime);
2689
    __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2690
    __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2691
    __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2692
    __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2693
    __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2694
    unlock_user_struct(target_sd, target_addr, 1);
2695
    return 0;
2696
}
2697

    
2698
struct  target_shminfo {
2699
    abi_ulong shmmax;
2700
    abi_ulong shmmin;
2701
    abi_ulong shmmni;
2702
    abi_ulong shmseg;
2703
    abi_ulong shmall;
2704
};
2705

    
2706
static inline abi_long host_to_target_shminfo(abi_ulong target_addr,
2707
                                              struct shminfo *host_shminfo)
2708
{
2709
    struct target_shminfo *target_shminfo;
2710
    if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0))
2711
        return -TARGET_EFAULT;
2712
    __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
2713
    __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
2714
    __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
2715
    __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
2716
    __put_user(host_shminfo->shmall, &target_shminfo->shmall);
2717
    unlock_user_struct(target_shminfo, target_addr, 1);
2718
    return 0;
2719
}
2720

    
2721
struct target_shm_info {
2722
    int used_ids;
2723
    abi_ulong shm_tot;
2724
    abi_ulong shm_rss;
2725
    abi_ulong shm_swp;
2726
    abi_ulong swap_attempts;
2727
    abi_ulong swap_successes;
2728
};
2729

    
2730
static inline abi_long host_to_target_shm_info(abi_ulong target_addr,
2731
                                               struct shm_info *host_shm_info)
2732
{
2733
    struct target_shm_info *target_shm_info;
2734
    if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0))
2735
        return -TARGET_EFAULT;
2736
    __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
2737
    __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
2738
    __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
2739
    __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
2740
    __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts);
2741
    __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes);
2742
    unlock_user_struct(target_shm_info, target_addr, 1);
2743
    return 0;
2744
}
2745

    
2746
static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
2747
{
2748
    struct shmid_ds dsarg;
2749
    struct shminfo shminfo;
2750
    struct shm_info shm_info;
2751
    abi_long ret = -TARGET_EINVAL;
2752

    
2753
    cmd &= 0xff;
2754

    
2755
    switch(cmd) {
2756
    case IPC_STAT:
2757
    case IPC_SET:
2758
    case SHM_STAT:
2759
        if (target_to_host_shmid_ds(&dsarg, buf))
2760
            return -TARGET_EFAULT;
2761
        ret = get_errno(shmctl(shmid, cmd, &dsarg));
2762
        if (host_to_target_shmid_ds(buf, &dsarg))
2763
            return -TARGET_EFAULT;
2764
        break;
2765
    case IPC_INFO:
2766
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
2767
        if (host_to_target_shminfo(buf, &shminfo))
2768
            return -TARGET_EFAULT;
2769
        break;
2770
    case SHM_INFO:
2771
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
2772
        if (host_to_target_shm_info(buf, &shm_info))
2773
            return -TARGET_EFAULT;
2774
        break;
2775
    case IPC_RMID:
2776
    case SHM_LOCK:
2777
    case SHM_UNLOCK:
2778
        ret = get_errno(shmctl(shmid, cmd, NULL));
2779
        break;
2780
    }
2781

    
2782
    return ret;
2783
}
2784

    
2785
static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
2786
{
2787
    abi_long raddr;
2788
    void *host_raddr;
2789
    struct shmid_ds shm_info;
2790
    int i,ret;
2791

    
2792
    /* find out the length of the shared memory segment */
2793
    ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
2794
    if (is_error(ret)) {
2795
        /* can't get length, bail out */
2796
        return ret;
2797
    }
2798

    
2799
    mmap_lock();
2800

    
2801
    if (shmaddr)
2802
        host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
2803
    else {
2804
        abi_ulong mmap_start;
2805

    
2806
        mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
2807

    
2808
        if (mmap_start == -1) {
2809
            errno = ENOMEM;
2810
            host_raddr = (void *)-1;
2811
        } else
2812
            host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);
2813
    }
2814

    
2815
    if (host_raddr == (void *)-1) {
2816
        mmap_unlock();
2817
        return get_errno((long)host_raddr);
2818
    }
2819
    raddr=h2g((unsigned long)host_raddr);
2820

    
2821
    page_set_flags(raddr, raddr + shm_info.shm_segsz,
2822
                   PAGE_VALID | PAGE_READ |
2823
                   ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
2824

    
2825
    for (i = 0; i < N_SHM_REGIONS; i++) {
2826
        if (shm_regions[i].start == 0) {
2827
            shm_regions[i].start = raddr;
2828
            shm_regions[i].size = shm_info.shm_segsz;
2829
            break;
2830
        }
2831
    }
2832

    
2833
    mmap_unlock();
2834
    return raddr;
2835

    
2836
}
2837

    
2838
static inline abi_long do_shmdt(abi_ulong shmaddr)
2839
{
2840
    int i;
2841

    
2842
    for (i = 0; i < N_SHM_REGIONS; ++i) {
2843
        if (shm_regions[i].start == shmaddr) {
2844
            shm_regions[i].start = 0;
2845
            page_set_flags(shmaddr, shmaddr + shm_regions[i].size, 0);
2846
            break;
2847
        }
2848
    }
2849

    
2850
    return get_errno(shmdt(g2h(shmaddr)));
2851
}
2852

    
2853
#ifdef TARGET_NR_ipc
2854
/* ??? This only works with linear mappings.  */
2855
/* do_ipc() must return target values and target errnos. */
2856
static abi_long do_ipc(unsigned int call, int first,
2857
                       int second, int third,
2858
                       abi_long ptr, abi_long fifth)
2859
{
2860
    int version;
2861
    abi_long ret = 0;
2862

    
2863
    version = call >> 16;
2864
    call &= 0xffff;
2865

    
2866
    switch (call) {
2867
    case IPCOP_semop:
2868
        ret = do_semop(first, ptr, second);
2869
        break;
2870

    
2871
    case IPCOP_semget:
2872
        ret = get_errno(semget(first, second, third));
2873
        break;
2874

    
2875
    case IPCOP_semctl:
2876
        ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr);
2877
        break;
2878

    
2879
    case IPCOP_msgget:
2880
        ret = get_errno(msgget(first, second));
2881
        break;
2882

    
2883
    case IPCOP_msgsnd:
2884
        ret = do_msgsnd(first, ptr, second, third);
2885
        break;
2886

    
2887
    case IPCOP_msgctl:
2888
        ret = do_msgctl(first, second, ptr);
2889
        break;
2890

    
2891
    case IPCOP_msgrcv:
2892
        switch (version) {
2893
        case 0:
2894
            {
2895
                struct target_ipc_kludge {
2896
                    abi_long msgp;
2897
                    abi_long msgtyp;
2898
                } *tmp;
2899

    
2900
                if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
2901
                    ret = -TARGET_EFAULT;
2902
                    break;
2903
                }
2904

    
2905
                ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
2906

    
2907
                unlock_user_struct(tmp, ptr, 0);
2908
                break;
2909
            }
2910
        default:
2911
            ret = do_msgrcv(first, ptr, second, fifth, third);
2912
        }
2913
        break;
2914

    
2915
    case IPCOP_shmat:
2916
        switch (version) {
2917
        default:
2918
        {
2919
            abi_ulong raddr;
2920
            raddr = do_shmat(first, ptr, second);
2921
            if (is_error(raddr))
2922
                return get_errno(raddr);
2923
            if (put_user_ual(raddr, third))
2924
                return -TARGET_EFAULT;
2925
            break;
2926
        }
2927
        case 1:
2928
            ret = -TARGET_EINVAL;
2929
            break;
2930
        }
2931
        break;
2932
    case IPCOP_shmdt:
2933
        ret = do_shmdt(ptr);
2934
        break;
2935

    
2936
    case IPCOP_shmget:
2937
        /* IPC_* flag values are the same on all linux platforms */
2938
        ret = get_errno(shmget(first, second, third));
2939
        break;
2940

    
2941
        /* IPC_* and SHM_* command values are the same on all linux platforms */
2942
    case IPCOP_shmctl:
2943
        ret = do_shmctl(first, second, third);
2944
        break;
2945
    default:
2946
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2947
        ret = -TARGET_ENOSYS;
2948
        break;
2949
    }
2950
    return ret;
2951
}
2952
#endif
2953

    
2954
/* kernel structure types definitions */
2955
#define IFNAMSIZ        16
2956

    
2957
#define STRUCT(name, ...) STRUCT_ ## name,
2958
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
2959
enum {
2960
#include "syscall_types.h"
2961
};
2962
#undef STRUCT
2963
#undef STRUCT_SPECIAL
2964

    
2965
#define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = {  __VA_ARGS__, TYPE_NULL };
2966
#define STRUCT_SPECIAL(name)
2967
#include "syscall_types.h"
2968
#undef STRUCT
2969
#undef STRUCT_SPECIAL
2970

    
2971
typedef struct IOCTLEntry IOCTLEntry;
2972

    
2973
typedef abi_long do_ioctl_fn(const IOCTLEntry *ie, uint8_t *buf_temp,
2974
                             int fd, abi_long cmd, abi_long arg);
2975

    
2976
struct IOCTLEntry {
2977
    unsigned int target_cmd;
2978
    unsigned int host_cmd;
2979
    const char *name;
2980
    int access;
2981
    do_ioctl_fn *do_ioctl;
2982
    const argtype arg_type[5];
2983
};
2984

    
2985
#define IOC_R 0x0001
2986
#define IOC_W 0x0002
2987
#define IOC_RW (IOC_R | IOC_W)
2988

    
2989
#define MAX_STRUCT_SIZE 4096
2990

    
2991
#ifdef CONFIG_FIEMAP
2992
/* So fiemap access checks don't overflow on 32 bit systems.
2993
 * This is very slightly smaller than the limit imposed by
2994
 * the underlying kernel.
2995
 */
2996
#define FIEMAP_MAX_EXTENTS ((UINT_MAX - sizeof(struct fiemap))  \
2997
                            / sizeof(struct fiemap_extent))
2998

    
2999
static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp,
3000
                                       int fd, abi_long cmd, abi_long arg)
3001
{
3002
    /* The parameter for this ioctl is a struct fiemap followed
3003
     * by an array of struct fiemap_extent whose size is set
3004
     * in fiemap->fm_extent_count. The array is filled in by the
3005
     * ioctl.
3006
     */
3007
    int target_size_in, target_size_out;
3008
    struct fiemap *fm;
3009
    const argtype *arg_type = ie->arg_type;
3010
    const argtype extent_arg_type[] = { MK_STRUCT(STRUCT_fiemap_extent) };
3011
    void *argptr, *p;
3012
    abi_long ret;
3013
    int i, extent_size = thunk_type_size(extent_arg_type, 0);
3014
    uint32_t outbufsz;
3015
    int free_fm = 0;
3016

    
3017
    assert(arg_type[0] == TYPE_PTR);
3018
    assert(ie->access == IOC_RW);
3019
    arg_type++;
3020
    target_size_in = thunk_type_size(arg_type, 0);
3021
    argptr = lock_user(VERIFY_READ, arg, target_size_in, 1);
3022
    if (!argptr) {
3023
        return -TARGET_EFAULT;
3024
    }
3025
    thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3026
    unlock_user(argptr, arg, 0);
3027
    fm = (struct fiemap *)buf_temp;
3028
    if (fm->fm_extent_count > FIEMAP_MAX_EXTENTS) {
3029
        return -TARGET_EINVAL;
3030
    }
3031

    
3032
    outbufsz = sizeof (*fm) +
3033
        (sizeof(struct fiemap_extent) * fm->fm_extent_count);
3034

    
3035
    if (outbufsz > MAX_STRUCT_SIZE) {
3036
        /* We can't fit all the extents into the fixed size buffer.
3037
         * Allocate one that is large enough and use it instead.
3038
         */
3039
        fm = malloc(outbufsz);
3040
        if (!fm) {
3041
            return -TARGET_ENOMEM;
3042
        }
3043
        memcpy(fm, buf_temp, sizeof(struct fiemap));
3044
        free_fm = 1;
3045
    }
3046
    ret = get_errno(ioctl(fd, ie->host_cmd, fm));
3047
    if (!is_error(ret)) {
3048
        target_size_out = target_size_in;
3049
        /* An extent_count of 0 means we were only counting the extents
3050
         * so there are no structs to copy
3051
         */
3052
        if (fm->fm_extent_count != 0) {
3053
            target_size_out += fm->fm_mapped_extents * extent_size;
3054
        }
3055
        argptr = lock_user(VERIFY_WRITE, arg, target_size_out, 0);
3056
        if (!argptr) {
3057
            ret = -TARGET_EFAULT;
3058
        } else {
3059
            /* Convert the struct fiemap */
3060
            thunk_convert(argptr, fm, arg_type, THUNK_TARGET);
3061
            if (fm->fm_extent_count != 0) {
3062
                p = argptr + target_size_in;
3063
                /* ...and then all the struct fiemap_extents */
3064
                for (i = 0; i < fm->fm_mapped_extents; i++) {
3065
                    thunk_convert(p, &fm->fm_extents[i], extent_arg_type,
3066
                                  THUNK_TARGET);
3067
                    p += extent_size;
3068
                }
3069
            }
3070
            unlock_user(argptr, arg, target_size_out);
3071
        }
3072
    }
3073
    if (free_fm) {
3074
        free(fm);
3075
    }
3076
    return ret;
3077
}
3078
#endif
3079

    
3080
static IOCTLEntry ioctl_entries[] = {
3081
#define IOCTL(cmd, access, ...) \
3082
    { TARGET_ ## cmd, cmd, #cmd, access, 0, {  __VA_ARGS__ } },
3083
#define IOCTL_SPECIAL(cmd, access, dofn, ...)                      \
3084
    { TARGET_ ## cmd, cmd, #cmd, access, dofn, {  __VA_ARGS__ } },
3085
#include "ioctls.h"
3086
    { 0, 0, },
3087
};
3088

    
3089
/* ??? Implement proper locking for ioctls.  */
3090
/* do_ioctl() Must return target values and target errnos. */
3091
static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
3092
{
3093
    const IOCTLEntry *ie;
3094
    const argtype *arg_type;
3095
    abi_long ret;
3096
    uint8_t buf_temp[MAX_STRUCT_SIZE];
3097
    int target_size;
3098
    void *argptr;
3099

    
3100
    ie = ioctl_entries;
3101
    for(;;) {
3102
        if (ie->target_cmd == 0) {
3103
            gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
3104
            return -TARGET_ENOSYS;
3105
        }
3106
        if (ie->target_cmd == cmd)
3107
            break;
3108
        ie++;
3109
    }
3110
    arg_type = ie->arg_type;
3111
#if defined(DEBUG)
3112
    gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
3113
#endif
3114
    if (ie->do_ioctl) {
3115
        return ie->do_ioctl(ie, buf_temp, fd, cmd, arg);
3116
    }
3117

    
3118
    switch(arg_type[0]) {
3119
    case TYPE_NULL:
3120
        /* no argument */
3121
        ret = get_errno(ioctl(fd, ie->host_cmd));
3122
        break;
3123
    case TYPE_PTRVOID:
3124
    case TYPE_INT:
3125
        /* int argment */
3126
        ret = get_errno(ioctl(fd, ie->host_cmd, arg));
3127
        break;
3128
    case TYPE_PTR:
3129
        arg_type++;
3130
        target_size = thunk_type_size(arg_type, 0);
3131
        switch(ie->access) {
3132
        case IOC_R:
3133
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3134
            if (!is_error(ret)) {
3135
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3136
                if (!argptr)
3137
                    return -TARGET_EFAULT;
3138
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
3139
                unlock_user(argptr, arg, target_size);
3140
            }
3141
            break;
3142
        case IOC_W:
3143
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3144
            if (!argptr)
3145
                return -TARGET_EFAULT;
3146
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3147
            unlock_user(argptr, arg, 0);
3148
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3149
            break;
3150
        default:
3151
        case IOC_RW:
3152
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3153
            if (!argptr)
3154
                return -TARGET_EFAULT;
3155
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3156
            unlock_user(argptr, arg, 0);
3157
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3158
            if (!is_error(ret)) {
3159
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3160
                if (!argptr)
3161
                    return -TARGET_EFAULT;
3162
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
3163
                unlock_user(argptr, arg, target_size);
3164
            }
3165
            break;
3166
        }
3167
        break;
3168
    default:
3169
        gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
3170
                 (long)cmd, arg_type[0]);
3171
        ret = -TARGET_ENOSYS;
3172
        break;
3173
    }
3174
    return ret;
3175
}
3176

    
3177
static const bitmask_transtbl iflag_tbl[] = {
3178
        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
3179
        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
3180
        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
3181
        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
3182
        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
3183
        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
3184
        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
3185
        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
3186
        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
3187
        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
3188
        { TARGET_IXON, TARGET_IXON, IXON, IXON },
3189
        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
3190
        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
3191
        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
3192
        { 0, 0, 0, 0 }
3193
};
3194

    
3195
static const bitmask_transtbl oflag_tbl[] = {
3196
        { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
3197
        { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
3198
        { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
3199
        { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
3200
        { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
3201
        { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
3202
        { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
3203
        { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
3204
        { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
3205
        { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
3206
        { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
3207
        { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
3208
        { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
3209
        { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
3210
        { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
3211
        { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
3212
        { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
3213
        { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
3214
        { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
3215
        { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
3216
        { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
3217
        { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
3218
        { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
3219
        { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
3220
        { 0, 0, 0, 0 }
3221
};
3222

    
3223
static const bitmask_transtbl cflag_tbl[] = {
3224
        { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
3225
        { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
3226
        { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
3227
        { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
3228
        { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
3229
        { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
3230
        { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
3231
        { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
3232
        { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
3233
        { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
3234
        { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
3235
        { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
3236
        { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
3237
        { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
3238
        { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
3239
        { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
3240
        { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
3241
        { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
3242
        { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
3243
        { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
3244
        { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
3245
        { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
3246
        { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
3247
        { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
3248
        { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
3249
        { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
3250
        { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
3251
        { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
3252
        { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
3253
        { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
3254
        { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
3255
        { 0, 0, 0, 0 }
3256
};
3257

    
3258
static const bitmask_transtbl lflag_tbl[] = {
3259
        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
3260
        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
3261
        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
3262
        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
3263
        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
3264
        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
3265
        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
3266
        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
3267
        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
3268
        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
3269
        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
3270
        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
3271
        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
3272
        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
3273
        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
3274
        { 0, 0, 0, 0 }
3275
};
3276

    
3277
static void target_to_host_termios (void *dst, const void *src)
3278
{
3279
    struct host_termios *host = dst;
3280
    const struct target_termios *target = src;
3281

    
3282
    host->c_iflag =
3283
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
3284
    host->c_oflag =
3285
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
3286
    host->c_cflag =
3287
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
3288
    host->c_lflag =
3289
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
3290
    host->c_line = target->c_line;
3291

    
3292
    memset(host->c_cc, 0, sizeof(host->c_cc));
3293
    host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
3294
    host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
3295
    host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
3296
    host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
3297
    host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
3298
    host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
3299
    host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
3300
    host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
3301
    host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
3302
    host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
3303
    host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
3304
    host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
3305
    host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
3306
    host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
3307
    host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
3308
    host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
3309
    host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
3310
}
3311

    
3312
static void host_to_target_termios (void *dst, const void *src)
3313
{
3314
    struct target_termios *target = dst;
3315
    const struct host_termios *host = src;
3316

    
3317
    target->c_iflag =
3318
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
3319
    target->c_oflag =
3320
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
3321
    target->c_cflag =
3322
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
3323
    target->c_lflag =
3324
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
3325
    target->c_line = host->c_line;
3326

    
3327
    memset(target->c_cc, 0, sizeof(target->c_cc));
3328
    target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
3329
    target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
3330
    target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
3331
    target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
3332
    target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
3333
    target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
3334
    target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
3335
    target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
3336
    target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
3337
    target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
3338
    target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
3339
    target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
3340
    target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
3341
    target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
3342
    target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
3343
    target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
3344
    target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
3345
}
3346

    
3347
static const StructEntry struct_termios_def = {
3348
    .convert = { host_to_target_termios, target_to_host_termios },
3349
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
3350
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
3351
};
3352

    
3353
static bitmask_transtbl mmap_flags_tbl[] = {
3354
        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
3355
        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
3356
        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
3357
        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
3358
        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
3359
        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
3360
        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
3361
        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
3362
        { 0, 0, 0, 0 }
3363
};
3364

    
3365
#if defined(TARGET_I386)
3366

    
3367
/* NOTE: there is really one LDT for all the threads */
3368
static uint8_t *ldt_table;
3369

    
3370
static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
3371
{
3372
    int size;
3373
    void *p;
3374

    
3375
    if (!ldt_table)
3376
        return 0;
3377
    size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
3378
    if (size > bytecount)
3379
        size = bytecount;
3380
    p = lock_user(VERIFY_WRITE, ptr, size, 0);
3381
    if (!p)
3382
        return -TARGET_EFAULT;
3383
    /* ??? Should this by byteswapped?  */
3384
    memcpy(p, ldt_table, size);
3385
    unlock_user(p, ptr, size);
3386
    return size;
3387
}
3388

    
3389
/* XXX: add locking support */
3390
static abi_long write_ldt(CPUX86State *env,
3391
                          abi_ulong ptr, unsigned long bytecount, int oldmode)
3392
{
3393
    struct target_modify_ldt_ldt_s ldt_info;
3394
    struct target_modify_ldt_ldt_s *target_ldt_info;
3395
    int seg_32bit, contents, read_exec_only, limit_in_pages;
3396
    int seg_not_present, useable, lm;
3397
    uint32_t *lp, entry_1, entry_2;
3398

    
3399
    if (bytecount != sizeof(ldt_info))
3400
        return -TARGET_EINVAL;
3401
    if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
3402
        return -TARGET_EFAULT;
3403
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3404
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
3405
    ldt_info.limit = tswap32(target_ldt_info->limit);
3406
    ldt_info.flags = tswap32(target_ldt_info->flags);
3407
    unlock_user_struct(target_ldt_info, ptr, 0);
3408

    
3409
    if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
3410
        return -TARGET_EINVAL;
3411
    seg_32bit = ldt_info.flags & 1;
3412
    contents = (ldt_info.flags >> 1) & 3;
3413
    read_exec_only = (ldt_info.flags >> 3) & 1;
3414
    limit_in_pages = (ldt_info.flags >> 4) & 1;
3415
    seg_not_present = (ldt_info.flags >> 5) & 1;
3416
    useable = (ldt_info.flags >> 6) & 1;
3417
#ifdef TARGET_ABI32
3418
    lm = 0;
3419
#else
3420
    lm = (ldt_info.flags >> 7) & 1;
3421
#endif
3422
    if (contents == 3) {
3423
        if (oldmode)
3424
            return -TARGET_EINVAL;
3425
        if (seg_not_present == 0)
3426
            return -TARGET_EINVAL;
3427
    }
3428
    /* allocate the LDT */
3429
    if (!ldt_table) {
3430
        env->ldt.base = target_mmap(0,
3431
                                    TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
3432
                                    PROT_READ|PROT_WRITE,
3433
                                    MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
3434
        if (env->ldt.base == -1)
3435
            return -TARGET_ENOMEM;
3436
        memset(g2h(env->ldt.base), 0,
3437
               TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
3438
        env->ldt.limit = 0xffff;
3439
        ldt_table = g2h(env->ldt.base);
3440
    }
3441

    
3442
    /* NOTE: same code as Linux kernel */
3443
    /* Allow LDTs to be cleared by the user. */
3444
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3445
        if (oldmode ||
3446
            (contents == 0                &&
3447
             read_exec_only == 1        &&
3448
             seg_32bit == 0                &&
3449
             limit_in_pages == 0        &&
3450
             seg_not_present == 1        &&
3451
             useable == 0 )) {
3452
            entry_1 = 0;
3453
            entry_2 = 0;
3454
            goto install;
3455
        }
3456
    }
3457

    
3458
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
3459
        (ldt_info.limit & 0x0ffff);
3460
    entry_2 = (ldt_info.base_addr & 0xff000000) |
3461
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3462
        (ldt_info.limit & 0xf0000) |
3463
        ((read_exec_only ^ 1) << 9) |
3464
        (contents << 10) |
3465
        ((seg_not_present ^ 1) << 15) |
3466
        (seg_32bit << 22) |
3467
        (limit_in_pages << 23) |
3468
        (lm << 21) |
3469
        0x7000;
3470
    if (!oldmode)
3471
        entry_2 |= (useable << 20);
3472

    
3473
    /* Install the new entry ...  */
3474
install:
3475
    lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
3476
    lp[0] = tswap32(entry_1);
3477
    lp[1] = tswap32(entry_2);
3478
    return 0;
3479
}
3480

    
3481
/* specific and weird i386 syscalls */
3482
static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
3483
                              unsigned long bytecount)
3484
{
3485
    abi_long ret;
3486

    
3487
    switch (func) {
3488
    case 0:
3489
        ret = read_ldt(ptr, bytecount);
3490
        break;
3491
    case 1:
3492
        ret = write_ldt(env, ptr, bytecount, 1);
3493
        break;
3494
    case 0x11:
3495
        ret = write_ldt(env, ptr, bytecount, 0);
3496
        break;
3497
    default:
3498
        ret = -TARGET_ENOSYS;
3499
        break;
3500
    }
3501
    return ret;
3502
}
3503

    
3504
#if defined(TARGET_I386) && defined(TARGET_ABI32)
3505
static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
3506
{
3507
    uint64_t *gdt_table = g2h(env->gdt.base);
3508
    struct target_modify_ldt_ldt_s ldt_info;
3509
    struct target_modify_ldt_ldt_s *target_ldt_info;
3510
    int seg_32bit, contents, read_exec_only, limit_in_pages;
3511
    int seg_not_present, useable, lm;
3512
    uint32_t *lp, entry_1, entry_2;
3513
    int i;
3514

    
3515
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3516
    if (!target_ldt_info)
3517
        return -TARGET_EFAULT;
3518
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3519
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
3520
    ldt_info.limit = tswap32(target_ldt_info->limit);
3521
    ldt_info.flags = tswap32(target_ldt_info->flags);
3522
    if (ldt_info.entry_number == -1) {
3523
        for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
3524
            if (gdt_table[i] == 0) {
3525
                ldt_info.entry_number = i;
3526
                target_ldt_info->entry_number = tswap32(i);
3527
                break;
3528
            }
3529
        }
3530
    }
3531
    unlock_user_struct(target_ldt_info, ptr, 1);
3532

    
3533
    if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || 
3534
        ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
3535
           return -TARGET_EINVAL;
3536
    seg_32bit = ldt_info.flags & 1;
3537
    contents = (ldt_info.flags >> 1) & 3;
3538
    read_exec_only = (ldt_info.flags >> 3) & 1;
3539
    limit_in_pages = (ldt_info.flags >> 4) & 1;
3540
    seg_not_present = (ldt_info.flags >> 5) & 1;
3541
    useable = (ldt_info.flags >> 6) & 1;
3542
#ifdef TARGET_ABI32
3543
    lm = 0;
3544
#else
3545
    lm = (ldt_info.flags >> 7) & 1;
3546
#endif
3547

    
3548
    if (contents == 3) {
3549
        if (seg_not_present == 0)
3550
            return -TARGET_EINVAL;
3551
    }
3552

    
3553
    /* NOTE: same code as Linux kernel */
3554
    /* Allow LDTs to be cleared by the user. */
3555
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3556
        if ((contents == 0             &&
3557
             read_exec_only == 1       &&
3558
             seg_32bit == 0            &&
3559
             limit_in_pages == 0       &&
3560
             seg_not_present == 1      &&
3561
             useable == 0 )) {
3562
            entry_1 = 0;
3563
            entry_2 = 0;
3564
            goto install;
3565
        }
3566
    }
3567

    
3568
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
3569
        (ldt_info.limit & 0x0ffff);
3570
    entry_2 = (ldt_info.base_addr & 0xff000000) |
3571
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3572
        (ldt_info.limit & 0xf0000) |
3573
        ((read_exec_only ^ 1) << 9) |
3574
        (contents << 10) |
3575
        ((seg_not_present ^ 1) << 15) |
3576
        (seg_32bit << 22) |
3577
        (limit_in_pages << 23) |
3578
        (useable << 20) |
3579
        (lm << 21) |
3580
        0x7000;
3581

    
3582
    /* Install the new entry ...  */
3583
install:
3584
    lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
3585
    lp[0] = tswap32(entry_1);
3586
    lp[1] = tswap32(entry_2);
3587
    return 0;
3588
}
3589

    
3590
static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
3591
{
3592
    struct target_modify_ldt_ldt_s *target_ldt_info;
3593
    uint64_t *gdt_table = g2h(env->gdt.base);
3594
    uint32_t base_addr, limit, flags;
3595
    int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
3596
    int seg_not_present, useable, lm;
3597
    uint32_t *lp, entry_1, entry_2;
3598

    
3599
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3600
    if (!target_ldt_info)
3601
        return -TARGET_EFAULT;
3602
    idx = tswap32(target_ldt_info->entry_number);
3603
    if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
3604
        idx > TARGET_GDT_ENTRY_TLS_MAX) {
3605
        unlock_user_struct(target_ldt_info, ptr, 1);
3606
        return -TARGET_EINVAL;
3607
    }
3608
    lp = (uint32_t *)(gdt_table + idx);
3609
    entry_1 = tswap32(lp[0]);
3610
    entry_2 = tswap32(lp[1]);
3611
    
3612
    read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
3613
    contents = (entry_2 >> 10) & 3;
3614
    seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
3615
    seg_32bit = (entry_2 >> 22) & 1;
3616
    limit_in_pages = (entry_2 >> 23) & 1;
3617
    useable = (entry_2 >> 20) & 1;
3618
#ifdef TARGET_ABI32
3619
    lm = 0;
3620
#else
3621
    lm = (entry_2 >> 21) & 1;
3622
#endif
3623
    flags = (seg_32bit << 0) | (contents << 1) |
3624
        (read_exec_only << 3) | (limit_in_pages << 4) |
3625
        (seg_not_present << 5) | (useable << 6) | (lm << 7);
3626
    limit = (entry_1 & 0xffff) | (entry_2  & 0xf0000);
3627
    base_addr = (entry_1 >> 16) | 
3628
        (entry_2 & 0xff000000) | 
3629
        ((entry_2 & 0xff) << 16);
3630
    target_ldt_info->base_addr = tswapl(base_addr);
3631
    target_ldt_info->limit = tswap32(limit);
3632
    target_ldt_info->flags = tswap32(flags);
3633
    unlock_user_struct(target_ldt_info, ptr, 1);
3634
    return 0;
3635
}
3636
#endif /* TARGET_I386 && TARGET_ABI32 */
3637

    
3638
#ifndef TARGET_ABI32
3639
static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
3640
{
3641
    abi_long ret;
3642
    abi_ulong val;
3643
    int idx;
3644
    
3645
    switch(code) {
3646
    case TARGET_ARCH_SET_GS:
3647
    case TARGET_ARCH_SET_FS:
3648
        if (code == TARGET_ARCH_SET_GS)
3649
            idx = R_GS;
3650
        else
3651
            idx = R_FS;
3652
        cpu_x86_load_seg(env, idx, 0);
3653
        env->segs[idx].base = addr;
3654
        break;
3655
    case TARGET_ARCH_GET_GS:
3656
    case TARGET_ARCH_GET_FS:
3657
        if (code == TARGET_ARCH_GET_GS)
3658
            idx = R_GS;
3659
        else
3660
            idx = R_FS;
3661
        val = env->segs[idx].base;
3662
        if (put_user(val, addr, abi_ulong))
3663
            return -TARGET_EFAULT;
3664
        break;
3665
    default:
3666
        ret = -TARGET_EINVAL;
3667
        break;
3668
    }
3669
    return 0;
3670
}
3671
#endif
3672

    
3673
#endif /* defined(TARGET_I386) */
3674

    
3675
#if defined(CONFIG_USE_NPTL)
3676

    
3677
#define NEW_STACK_SIZE PTHREAD_STACK_MIN
3678

    
3679
static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
3680
typedef struct {
3681
    CPUState *env;
3682
    pthread_mutex_t mutex;
3683
    pthread_cond_t cond;
3684
    pthread_t thread;
3685
    uint32_t tid;
3686
    abi_ulong child_tidptr;
3687
    abi_ulong parent_tidptr;
3688
    sigset_t sigmask;
3689
} new_thread_info;
3690

    
3691
static void *clone_func(void *arg)
3692
{
3693
    new_thread_info *info = arg;
3694
    CPUState *env;
3695
    TaskState *ts;
3696

    
3697
    env = info->env;
3698
    thread_env = env;
3699
    ts = (TaskState *)thread_env->opaque;
3700
    info->tid = gettid();
3701
    env->host_tid = info->tid;
3702
    task_settid(ts);
3703
    if (info->child_tidptr)
3704
        put_user_u32(info->tid, info->child_tidptr);
3705
    if (info->parent_tidptr)
3706
        put_user_u32(info->tid, info->parent_tidptr);
3707
    /* Enable signals.  */
3708
    sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
3709
    /* Signal to the parent that we're ready.  */
3710
    pthread_mutex_lock(&info->mutex);
3711
    pthread_cond_broadcast(&info->cond);
3712
    pthread_mutex_unlock(&info->mutex);
3713
    /* Wait until the parent has finshed initializing the tls state.  */
3714
    pthread_mutex_lock(&clone_lock);
3715
    pthread_mutex_unlock(&clone_lock);
3716
    cpu_loop(env);
3717
    /* never exits */
3718
    return NULL;
3719
}
3720
#else
3721
/* this stack is the equivalent of the kernel stack associated with a
3722
   thread/process */
3723
#define NEW_STACK_SIZE 8192
3724

    
3725
static int clone_func(void *arg)
3726
{
3727
    CPUState *env = arg;
3728
    cpu_loop(env);
3729
    /* never exits */
3730
    return 0;
3731
}
3732
#endif
3733

    
3734
/* do_fork() Must return host values and target errnos (unlike most
3735
   do_*() functions). */
3736
static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
3737
                   abi_ulong parent_tidptr, target_ulong newtls,
3738
                   abi_ulong child_tidptr)
3739
{
3740
    int ret;
3741
    TaskState *ts;
3742
    CPUState *new_env;
3743
#if defined(CONFIG_USE_NPTL)
3744
    unsigned int nptl_flags;
3745
    sigset_t sigmask;
3746
#else
3747
    uint8_t *new_stack;
3748
#endif
3749

    
3750
    /* Emulate vfork() with fork() */
3751
    if (flags & CLONE_VFORK)
3752
        flags &= ~(CLONE_VFORK | CLONE_VM);
3753

    
3754
    if (flags & CLONE_VM) {
3755
        TaskState *parent_ts = (TaskState *)env->opaque;
3756
#if defined(CONFIG_USE_NPTL)
3757
        new_thread_info info;
3758
        pthread_attr_t attr;
3759
#endif
3760
        ts = qemu_mallocz(sizeof(TaskState));
3761
        init_task_state(ts);
3762
        /* we create a new CPU instance. */
3763
        new_env = cpu_copy(env);
3764
#if defined(TARGET_I386) || defined(TARGET_SPARC) || defined(TARGET_PPC)
3765
        cpu_reset(new_env);
3766
#endif
3767
        /* Init regs that differ from the parent.  */
3768
        cpu_clone_regs(new_env, newsp);
3769
        new_env->opaque = ts;
3770
        ts->bprm = parent_ts->bprm;
3771
        ts->info = parent_ts->info;
3772
#if defined(CONFIG_USE_NPTL)
3773
        nptl_flags = flags;
3774
        flags &= ~CLONE_NPTL_FLAGS2;
3775

    
3776
        if (nptl_flags & CLONE_CHILD_CLEARTID) {
3777
            ts->child_tidptr = child_tidptr;
3778
        }
3779

    
3780
        if (nptl_flags & CLONE_SETTLS)
3781
            cpu_set_tls (new_env, newtls);
3782

    
3783
        /* Grab a mutex so that thread setup appears atomic.  */
3784
        pthread_mutex_lock(&clone_lock);
3785

    
3786
        memset(&info, 0, sizeof(info));
3787
        pthread_mutex_init(&info.mutex, NULL);
3788
        pthread_mutex_lock(&info.mutex);
3789
        pthread_cond_init(&info.cond, NULL);
3790
        info.env = new_env;
3791
        if (nptl_flags & CLONE_CHILD_SETTID)
3792
            info.child_tidptr = child_tidptr;
3793
        if (nptl_flags & CLONE_PARENT_SETTID)
3794
            info.parent_tidptr = parent_tidptr;
3795

    
3796
        ret = pthread_attr_init(&attr);
3797
        ret = pthread_attr_setstacksize(&attr, NEW_STACK_SIZE);
3798
        ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
3799
        /* It is not safe to deliver signals until the child has finished
3800
           initializing, so temporarily block all signals.  */
3801
        sigfillset(&sigmask);
3802
        sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
3803

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

    
3807
        sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
3808
        pthread_attr_destroy(&attr);
3809
        if (ret == 0) {
3810
            /* Wait for the child to initialize.  */
3811
            pthread_cond_wait(&info.cond, &info.mutex);
3812
            ret = info.tid;
3813
            if (flags & CLONE_PARENT_SETTID)
3814
                put_user_u32(ret, parent_tidptr);
3815
        } else {
3816
            ret = -1;
3817
        }
3818
        pthread_mutex_unlock(&info.mutex);
3819
        pthread_cond_destroy(&info.cond);
3820
        pthread_mutex_destroy(&info.mutex);
3821
        pthread_mutex_unlock(&clone_lock);
3822
#else
3823
        if (flags & CLONE_NPTL_FLAGS2)
3824
            return -EINVAL;
3825
        /* This is probably going to die very quickly, but do it anyway.  */
3826
        new_stack = qemu_mallocz (NEW_STACK_SIZE);
3827
#ifdef __ia64__
3828
        ret = __clone2(clone_func, new_stack, NEW_STACK_SIZE, flags, new_env);
3829
#else
3830
        ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
3831
#endif
3832
#endif
3833
    } else {
3834
        /* if no CLONE_VM, we consider it is a fork */
3835
        if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
3836
            return -EINVAL;
3837
        fork_start();
3838
        ret = fork();
3839
        if (ret == 0) {
3840
            /* Child Process.  */
3841
            cpu_clone_regs(env, newsp);
3842
            fork_end(1);
3843
#if defined(CONFIG_USE_NPTL)
3844
            /* There is a race condition here.  The parent process could
3845
               theoretically read the TID in the child process before the child
3846
               tid is set.  This would require using either ptrace
3847
               (not implemented) or having *_tidptr to point at a shared memory
3848
               mapping.  We can't repeat the spinlock hack used above because
3849
               the child process gets its own copy of the lock.  */
3850
            if (flags & CLONE_CHILD_SETTID)
3851
                put_user_u32(gettid(), child_tidptr);
3852
            if (flags & CLONE_PARENT_SETTID)
3853
                put_user_u32(gettid(), parent_tidptr);
3854
            ts = (TaskState *)env->opaque;
3855
            if (flags & CLONE_SETTLS)
3856
                cpu_set_tls (env, newtls);
3857
            if (flags & CLONE_CHILD_CLEARTID)
3858
                ts->child_tidptr = child_tidptr;
3859
#endif
3860
        } else {
3861
            fork_end(0);
3862
        }
3863
    }
3864
    return ret;
3865
}
3866

    
3867
/* warning : doesn't handle linux specific flags... */
3868
static int target_to_host_fcntl_cmd(int cmd)
3869
{
3870
    switch(cmd) {
3871
        case TARGET_F_DUPFD:
3872
        case TARGET_F_GETFD:
3873
        case TARGET_F_SETFD:
3874
        case TARGET_F_GETFL:
3875
        case TARGET_F_SETFL:
3876
            return cmd;
3877
        case TARGET_F_GETLK:
3878
            return F_GETLK;
3879
        case TARGET_F_SETLK:
3880
            return F_SETLK;
3881
        case TARGET_F_SETLKW:
3882
            return F_SETLKW;
3883
        case TARGET_F_GETOWN:
3884
            return F_GETOWN;
3885
        case TARGET_F_SETOWN:
3886
            return F_SETOWN;
3887
        case TARGET_F_GETSIG:
3888
            return F_GETSIG;
3889
        case TARGET_F_SETSIG:
3890
            return F_SETSIG;
3891
#if TARGET_ABI_BITS == 32
3892
        case TARGET_F_GETLK64:
3893
            return F_GETLK64;
3894
        case TARGET_F_SETLK64:
3895
            return F_SETLK64;
3896
        case TARGET_F_SETLKW64:
3897
            return F_SETLKW64;
3898
#endif
3899
        case TARGET_F_SETLEASE:
3900
            return F_SETLEASE;
3901
        case TARGET_F_GETLEASE:
3902
            return F_GETLEASE;
3903
#ifdef F_DUPFD_CLOEXEC
3904
        case TARGET_F_DUPFD_CLOEXEC:
3905
            return F_DUPFD_CLOEXEC;
3906
#endif
3907
        case TARGET_F_NOTIFY:
3908
            return F_NOTIFY;
3909
        default:
3910
            return -TARGET_EINVAL;
3911
    }
3912
    return -TARGET_EINVAL;
3913
}
3914

    
3915
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
3916
{
3917
    struct flock fl;
3918
    struct target_flock *target_fl;
3919
    struct flock64 fl64;
3920
    struct target_flock64 *target_fl64;
3921
    abi_long ret;
3922
    int host_cmd = target_to_host_fcntl_cmd(cmd);
3923

    
3924
    if (host_cmd == -TARGET_EINVAL)
3925
            return host_cmd;
3926

    
3927
    switch(cmd) {
3928
    case TARGET_F_GETLK:
3929
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3930
            return -TARGET_EFAULT;
3931
        fl.l_type = tswap16(target_fl->l_type);
3932
        fl.l_whence = tswap16(target_fl->l_whence);
3933
        fl.l_start = tswapl(target_fl->l_start);
3934
        fl.l_len = tswapl(target_fl->l_len);
3935
        fl.l_pid = tswap32(target_fl->l_pid);
3936
        unlock_user_struct(target_fl, arg, 0);
3937
        ret = get_errno(fcntl(fd, host_cmd, &fl));
3938
        if (ret == 0) {
3939
            if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
3940
                return -TARGET_EFAULT;
3941
            target_fl->l_type = tswap16(fl.l_type);
3942
            target_fl->l_whence = tswap16(fl.l_whence);
3943
            target_fl->l_start = tswapl(fl.l_start);
3944
            target_fl->l_len = tswapl(fl.l_len);
3945
            target_fl->l_pid = tswap32(fl.l_pid);
3946
            unlock_user_struct(target_fl, arg, 1);
3947
        }
3948
        break;
3949

    
3950
    case TARGET_F_SETLK:
3951
    case TARGET_F_SETLKW:
3952
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3953
            return -TARGET_EFAULT;
3954
        fl.l_type = tswap16(target_fl->l_type);
3955
        fl.l_whence = tswap16(target_fl->l_whence);
3956
        fl.l_start = tswapl(target_fl->l_start);
3957
        fl.l_len = tswapl(target_fl->l_len);
3958
        fl.l_pid = tswap32(target_fl->l_pid);
3959
        unlock_user_struct(target_fl, arg, 0);
3960
        ret = get_errno(fcntl(fd, host_cmd, &fl));
3961
        break;
3962

    
3963
    case TARGET_F_GETLK64:
3964
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3965
            return -TARGET_EFAULT;
3966
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3967
        fl64.l_whence = tswap16(target_fl64->l_whence);
3968
        fl64.l_start = tswapl(target_fl64->l_start);
3969
        fl64.l_len = tswapl(target_fl64->l_len);
3970
        fl64.l_pid = tswap32(target_fl64->l_pid);
3971
        unlock_user_struct(target_fl64, arg, 0);
3972
        ret = get_errno(fcntl(fd, host_cmd, &fl64));
3973
        if (ret == 0) {
3974
            if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
3975
                return -TARGET_EFAULT;
3976
            target_fl64->l_type = tswap16(fl64.l_type) >> 1;
3977
            target_fl64->l_whence = tswap16(fl64.l_whence);
3978
            target_fl64->l_start = tswapl(fl64.l_start);
3979
            target_fl64->l_len = tswapl(fl64.l_len);
3980
            target_fl64->l_pid = tswap32(fl64.l_pid);
3981
            unlock_user_struct(target_fl64, arg, 1);
3982
        }
3983
        break;
3984
    case TARGET_F_SETLK64:
3985
    case TARGET_F_SETLKW64:
3986
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3987
            return -TARGET_EFAULT;
3988
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3989
        fl64.l_whence = tswap16(target_fl64->l_whence);
3990
        fl64.l_start = tswapl(target_fl64->l_start);
3991
        fl64.l_len = tswapl(target_fl64->l_len);
3992
        fl64.l_pid = tswap32(target_fl64->l_pid);
3993
        unlock_user_struct(target_fl64, arg, 0);
3994
        ret = get_errno(fcntl(fd, host_cmd, &fl64));
3995
        break;
3996

    
3997
    case TARGET_F_GETFL:
3998
        ret = get_errno(fcntl(fd, host_cmd, arg));
3999
        if (ret >= 0) {
4000
            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
4001
        }
4002
        break;
4003

    
4004
    case TARGET_F_SETFL:
4005
        ret = get_errno(fcntl(fd, host_cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
4006
        break;
4007

    
4008
    case TARGET_F_SETOWN:
4009
    case TARGET_F_GETOWN:
4010
    case TARGET_F_SETSIG:
4011
    case TARGET_F_GETSIG:
4012
    case TARGET_F_SETLEASE:
4013
    case TARGET_F_GETLEASE:
4014
        ret = get_errno(fcntl(fd, host_cmd, arg));
4015
        break;
4016

    
4017
    default:
4018
        ret = get_errno(fcntl(fd, cmd, arg));
4019
        break;
4020
    }
4021
    return ret;
4022
}
4023

    
4024
#ifdef USE_UID16
4025

    
4026
static inline int high2lowuid(int uid)
4027
{
4028
    if (uid > 65535)
4029
        return 65534;
4030
    else
4031
        return uid;
4032
}
4033

    
4034
static inline int high2lowgid(int gid)
4035
{
4036
    if (gid > 65535)
4037
        return 65534;
4038
    else
4039
        return gid;
4040
}
4041

    
4042
static inline int low2highuid(int uid)
4043
{
4044
    if ((int16_t)uid == -1)
4045
        return -1;
4046
    else
4047
        return uid;
4048
}
4049

    
4050
static inline int low2highgid(int gid)
4051
{
4052
    if ((int16_t)gid == -1)
4053
        return -1;
4054
    else
4055
        return gid;
4056
}
4057

    
4058
#endif /* USE_UID16 */
4059

    
4060
void syscall_init(void)
4061
{
4062
    IOCTLEntry *ie;
4063
    const argtype *arg_type;
4064
    int size;
4065
    int i;
4066

    
4067
#define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
4068
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
4069
#include "syscall_types.h"
4070
#undef STRUCT
4071
#undef STRUCT_SPECIAL
4072

    
4073
    /* we patch the ioctl size if necessary. We rely on the fact that
4074
       no ioctl has all the bits at '1' in the size field */
4075
    ie = ioctl_entries;
4076
    while (ie->target_cmd != 0) {
4077
        if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
4078
            TARGET_IOC_SIZEMASK) {
4079
            arg_type = ie->arg_type;
4080
            if (arg_type[0] != TYPE_PTR) {
4081
                fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
4082
                        ie->target_cmd);
4083
                exit(1);
4084
            }
4085
            arg_type++;
4086
            size = thunk_type_size(arg_type, 0);
4087
            ie->target_cmd = (ie->target_cmd &
4088
                              ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
4089
                (size << TARGET_IOC_SIZESHIFT);
4090
        }
4091

    
4092
        /* Build target_to_host_errno_table[] table from
4093
         * host_to_target_errno_table[]. */
4094
        for (i=0; i < ERRNO_TABLE_SIZE; i++)
4095
                target_to_host_errno_table[host_to_target_errno_table[i]] = i;
4096

    
4097
        /* automatic consistency check if same arch */
4098
#if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
4099
    (defined(__x86_64__) && defined(TARGET_X86_64))
4100
        if (unlikely(ie->target_cmd != ie->host_cmd)) {
4101
            fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
4102
                    ie->name, ie->target_cmd, ie->host_cmd);
4103
        }
4104
#endif
4105
        ie++;
4106
    }
4107
}
4108

    
4109
#if TARGET_ABI_BITS == 32
4110
static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
4111
{
4112
#ifdef TARGET_WORDS_BIGENDIAN
4113
    return ((uint64_t)word0 << 32) | word1;
4114
#else
4115
    return ((uint64_t)word1 << 32) | word0;
4116
#endif
4117
}
4118
#else /* TARGET_ABI_BITS == 32 */
4119
static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
4120
{
4121
    return word0;
4122
}
4123
#endif /* TARGET_ABI_BITS != 32 */
4124

    
4125
#ifdef TARGET_NR_truncate64
4126
static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
4127
                                         abi_long arg2,
4128
                                         abi_long arg3,
4129
                                         abi_long arg4)
4130
{
4131
#ifdef TARGET_ARM
4132
    if (((CPUARMState *)cpu_env)->eabi)
4133
      {
4134
        arg2 = arg3;
4135
        arg3 = arg4;
4136
      }
4137
#endif
4138
    return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
4139
}
4140
#endif
4141

    
4142
#ifdef TARGET_NR_ftruncate64
4143
static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
4144
                                          abi_long arg2,
4145
                                          abi_long arg3,
4146
                                          abi_long arg4)
4147
{
4148
#ifdef TARGET_ARM
4149
    if (((CPUARMState *)cpu_env)->eabi)
4150
      {
4151
        arg2 = arg3;
4152
        arg3 = arg4;
4153
      }
4154
#endif
4155
    return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
4156
}
4157
#endif
4158

    
4159
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
4160
                                               abi_ulong target_addr)
4161
{
4162
    struct target_timespec *target_ts;
4163

    
4164
    if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
4165
        return -TARGET_EFAULT;
4166
    host_ts->tv_sec = tswapl(target_ts->tv_sec);
4167
    host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
4168
    unlock_user_struct(target_ts, target_addr, 0);
4169
    return 0;
4170
}
4171

    
4172
static inline abi_long host_to_target_timespec(abi_ulong target_addr,
4173
                                               struct timespec *host_ts)
4174
{
4175
    struct target_timespec *target_ts;
4176

    
4177
    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
4178
        return -TARGET_EFAULT;
4179
    target_ts->tv_sec = tswapl(host_ts->tv_sec);
4180
    target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
4181
    unlock_user_struct(target_ts, target_addr, 1);
4182
    return 0;
4183
}
4184

    
4185
#if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
4186
static inline abi_long host_to_target_stat64(void *cpu_env,
4187
                                             abi_ulong target_addr,
4188
                                             struct stat *host_st)
4189
{
4190
#ifdef TARGET_ARM
4191
    if (((CPUARMState *)cpu_env)->eabi) {
4192
        struct target_eabi_stat64 *target_st;
4193

    
4194
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
4195
            return -TARGET_EFAULT;
4196
        memset(target_st, 0, sizeof(struct target_eabi_stat64));
4197
        __put_user(host_st->st_dev, &target_st->st_dev);
4198
        __put_user(host_st->st_ino, &target_st->st_ino);
4199
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4200
        __put_user(host_st->st_ino, &target_st->__st_ino);
4201
#endif
4202
        __put_user(host_st->st_mode, &target_st->st_mode);
4203
        __put_user(host_st->st_nlink, &target_st->st_nlink);
4204
        __put_user(host_st->st_uid, &target_st->st_uid);
4205
        __put_user(host_st->st_gid, &target_st->st_gid);
4206
        __put_user(host_st->st_rdev, &target_st->st_rdev);
4207
        __put_user(host_st->st_size, &target_st->st_size);
4208
        __put_user(host_st->st_blksize, &target_st->st_blksize);
4209
        __put_user(host_st->st_blocks, &target_st->st_blocks);
4210
        __put_user(host_st->st_atime, &target_st->target_st_atime);
4211
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
4212
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
4213
        unlock_user_struct(target_st, target_addr, 1);
4214
    } else
4215
#endif
4216
    {
4217
#if TARGET_ABI_BITS == 64 && !defined(TARGET_ALPHA)
4218
        struct target_stat *target_st;
4219
#else
4220
        struct target_stat64 *target_st;
4221
#endif
4222

    
4223
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
4224
            return -TARGET_EFAULT;
4225
        memset(target_st, 0, sizeof(*target_st));
4226
        __put_user(host_st->st_dev, &target_st->st_dev);
4227
        __put_user(host_st->st_ino, &target_st->st_ino);
4228
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4229
        __put_user(host_st->st_ino, &target_st->__st_ino);
4230
#endif
4231
        __put_user(host_st->st_mode, &target_st->st_mode);
4232
        __put_user(host_st->st_nlink, &target_st->st_nlink);
4233
        __put_user(host_st->st_uid, &target_st->st_uid);
4234
        __put_user(host_st->st_gid, &target_st->st_gid);
4235
        __put_user(host_st->st_rdev, &target_st->st_rdev);
4236
        /* XXX: better use of kernel struct */
4237
        __put_user(host_st->st_size, &target_st->st_size);
4238
        __put_user(host_st->st_blksize, &target_st->st_blksize);
4239
        __put_user(host_st->st_blocks, &target_st->st_blocks);
4240
        __put_user(host_st->st_atime, &target_st->target_st_atime);
4241
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
4242
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
4243
        unlock_user_struct(target_st, target_addr, 1);
4244
    }
4245

    
4246
    return 0;
4247
}
4248
#endif
4249

    
4250
#if defined(CONFIG_USE_NPTL)
4251
/* ??? Using host futex calls even when target atomic operations
4252
   are not really atomic probably breaks things.  However implementing
4253
   futexes locally would make futexes shared between multiple processes
4254
   tricky.  However they're probably useless because guest atomic
4255
   operations won't work either.  */
4256
static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
4257
                    target_ulong uaddr2, int val3)
4258
{
4259
    struct timespec ts, *pts;
4260
    int base_op;
4261

    
4262
    /* ??? We assume FUTEX_* constants are the same on both host
4263
       and target.  */
4264
#ifdef FUTEX_CMD_MASK
4265
    base_op = op & FUTEX_CMD_MASK;
4266
#else
4267
    base_op = op;
4268
#endif
4269
    switch (base_op) {
4270
    case FUTEX_WAIT:
4271
        if (timeout) {
4272
            pts = &ts;
4273
            target_to_host_timespec(pts, timeout);
4274
        } else {
4275
            pts = NULL;
4276
        }
4277
        return get_errno(sys_futex(g2h(uaddr), op, tswap32(val),
4278
                         pts, NULL, 0));
4279
    case FUTEX_WAKE:
4280
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4281
    case FUTEX_FD:
4282
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4283
    case FUTEX_REQUEUE:
4284
    case FUTEX_CMP_REQUEUE:
4285
    case FUTEX_WAKE_OP:
4286
        /* For FUTEX_REQUEUE, FUTEX_CMP_REQUEUE, and FUTEX_WAKE_OP, the
4287
           TIMEOUT parameter is interpreted as a uint32_t by the kernel.
4288
           But the prototype takes a `struct timespec *'; insert casts
4289
           to satisfy the compiler.  We do not need to tswap TIMEOUT
4290
           since it's not compared to guest memory.  */
4291
        pts = (struct timespec *)(uintptr_t) timeout;
4292
        return get_errno(sys_futex(g2h(uaddr), op, val, pts,
4293
                                   g2h(uaddr2),
4294
                                   (base_op == FUTEX_CMP_REQUEUE
4295
                                    ? tswap32(val3)
4296
                                    : val3)));
4297
    default:
4298
        return -TARGET_ENOSYS;
4299
    }
4300
}
4301
#endif
4302

    
4303
/* Map host to target signal numbers for the wait family of syscalls.
4304
   Assume all other status bits are the same.  */
4305
static int host_to_target_waitstatus(int status)
4306
{
4307
    if (WIFSIGNALED(status)) {
4308
        return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f);
4309
    }
4310
    if (WIFSTOPPED(status)) {
4311
        return (host_to_target_signal(WSTOPSIG(status)) << 8)
4312
               | (status & 0xff);
4313
    }
4314
    return status;
4315
}
4316

    
4317
int get_osversion(void)
4318
{
4319
    static int osversion;
4320
    struct new_utsname buf;
4321
    const char *s;
4322
    int i, n, tmp;
4323
    if (osversion)
4324
        return osversion;
4325
    if (qemu_uname_release && *qemu_uname_release) {
4326
        s = qemu_uname_release;
4327
    } else {
4328
        if (sys_uname(&buf))
4329
            return 0;
4330
        s = buf.release;
4331
    }
4332
    tmp = 0;
4333
    for (i = 0; i < 3; i++) {
4334
        n = 0;
4335
        while (*s >= '0' && *s <= '9') {
4336
            n *= 10;
4337
            n += *s - '0';
4338
            s++;
4339
        }
4340
        tmp = (tmp << 8) + n;
4341
        if (*s == '.')
4342
            s++;
4343
    }
4344
    osversion = tmp;
4345
    return osversion;
4346
}
4347

    
4348
/* do_syscall() should always have a single exit point at the end so
4349
   that actions, such as logging of syscall results, can be performed.
4350
   All errnos that do_syscall() returns must be -TARGET_<errcode>. */
4351
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4352
                    abi_long arg2, abi_long arg3, abi_long arg4,
4353
                    abi_long arg5, abi_long arg6)
4354
{
4355
    abi_long ret;
4356
    struct stat st;
4357
    struct statfs stfs;
4358
    void *p;
4359

    
4360
#ifdef DEBUG
4361
    gemu_log("syscall %d", num);
4362
#endif
4363
    if(do_strace)
4364
        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
4365

    
4366
    switch(num) {
4367
    case TARGET_NR_exit:
4368
#ifdef CONFIG_USE_NPTL
4369
      /* In old applications this may be used to implement _exit(2).
4370
         However in threaded applictions it is used for thread termination,
4371
         and _exit_group is used for application termination.
4372
         Do thread termination if we have more then one thread.  */
4373
      /* FIXME: This probably breaks if a signal arrives.  We should probably
4374
         be disabling signals.  */
4375
      if (first_cpu->next_cpu) {
4376
          TaskState *ts;
4377
          CPUState **lastp;
4378
          CPUState *p;
4379

    
4380
          cpu_list_lock();
4381
          lastp = &first_cpu;
4382
          p = first_cpu;
4383
          while (p && p != (CPUState *)cpu_env) {
4384
              lastp = &p->next_cpu;
4385
              p = p->next_cpu;
4386
          }
4387
          /* If we didn't find the CPU for this thread then something is
4388
             horribly wrong.  */
4389
          if (!p)
4390
              abort();
4391
          /* Remove the CPU from the list.  */
4392
          *lastp = p->next_cpu;
4393
          cpu_list_unlock();
4394
          ts = ((CPUState *)cpu_env)->opaque;
4395
          if (ts->child_tidptr) {
4396
              put_user_u32(0, ts->child_tidptr);
4397
              sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
4398
                        NULL, NULL, 0);
4399
          }
4400
          thread_env = NULL;
4401
          qemu_free(cpu_env);
4402
          qemu_free(ts);
4403
          pthread_exit(NULL);
4404
      }
4405
#endif
4406
#ifdef TARGET_GPROF
4407
        _mcleanup();
4408
#endif
4409
        gdb_exit(cpu_env, arg1);
4410
        _exit(arg1);
4411
        ret = 0; /* avoid warning */
4412
        break;
4413
    case TARGET_NR_read:
4414
        if (arg3 == 0)
4415
            ret = 0;
4416
        else {
4417
            if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
4418
                goto efault;
4419
            ret = get_errno(read(arg1, p, arg3));
4420
            unlock_user(p, arg2, ret);
4421
        }
4422
        break;
4423
    case TARGET_NR_write:
4424
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
4425
            goto efault;
4426
        ret = get_errno(write(arg1, p, arg3));
4427
        unlock_user(p, arg2, 0);
4428
        break;
4429
    case TARGET_NR_open:
4430
        if (!(p = lock_user_string(arg1)))
4431
            goto efault;
4432
        ret = get_errno(open(path(p),
4433
                             target_to_host_bitmask(arg2, fcntl_flags_tbl),
4434
                             arg3));
4435
        unlock_user(p, arg1, 0);
4436
        break;
4437
#if defined(TARGET_NR_openat) && defined(__NR_openat)
4438
    case TARGET_NR_openat:
4439
        if (!(p = lock_user_string(arg2)))
4440
            goto efault;
4441
        ret = get_errno(sys_openat(arg1,
4442
                                   path(p),
4443
                                   target_to_host_bitmask(arg3, fcntl_flags_tbl),
4444
                                   arg4));
4445
        unlock_user(p, arg2, 0);
4446
        break;
4447
#endif
4448
    case TARGET_NR_close:
4449
        ret = get_errno(close(arg1));
4450
        break;
4451
    case TARGET_NR_brk:
4452
        ret = do_brk(arg1);
4453
        break;
4454
    case TARGET_NR_fork:
4455
        ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
4456
        break;
4457
#ifdef TARGET_NR_waitpid
4458
    case TARGET_NR_waitpid:
4459
        {
4460
            int status;
4461
            ret = get_errno(waitpid(arg1, &status, arg3));
4462
            if (!is_error(ret) && arg2
4463
                && put_user_s32(host_to_target_waitstatus(status), arg2))
4464
                goto efault;
4465
        }
4466
        break;
4467
#endif
4468
#ifdef TARGET_NR_waitid
4469
    case TARGET_NR_waitid:
4470
        {
4471
            siginfo_t info;
4472
            info.si_pid = 0;
4473
            ret = get_errno(waitid(arg1, arg2, &info, arg4));
4474
            if (!is_error(ret) && arg3 && info.si_pid != 0) {
4475
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
4476
                    goto efault;
4477
                host_to_target_siginfo(p, &info);
4478
                unlock_user(p, arg3, sizeof(target_siginfo_t));
4479
            }
4480
        }
4481
        break;
4482
#endif
4483
#ifdef TARGET_NR_creat /* not on alpha */
4484
    case TARGET_NR_creat:
4485
        if (!(p = lock_user_string(arg1)))
4486
            goto efault;
4487
        ret = get_errno(creat(p, arg2));
4488
        unlock_user(p, arg1, 0);
4489
        break;
4490
#endif
4491
    case TARGET_NR_link:
4492
        {
4493
            void * p2;
4494
            p = lock_user_string(arg1);
4495
            p2 = lock_user_string(arg2);
4496
            if (!p || !p2)
4497
                ret = -TARGET_EFAULT;
4498
            else
4499
                ret = get_errno(link(p, p2));
4500
            unlock_user(p2, arg2, 0);
4501
            unlock_user(p, arg1, 0);
4502
        }
4503
        break;
4504
#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
4505
    case TARGET_NR_linkat:
4506
        {
4507
            void * p2 = NULL;
4508
            if (!arg2 || !arg4)
4509
                goto efault;
4510
            p  = lock_user_string(arg2);
4511
            p2 = lock_user_string(arg4);
4512
            if (!p || !p2)
4513
                ret = -TARGET_EFAULT;
4514
            else
4515
                ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
4516
            unlock_user(p, arg2, 0);
4517
            unlock_user(p2, arg4, 0);
4518
        }
4519
        break;
4520
#endif
4521
    case TARGET_NR_unlink:
4522
        if (!(p = lock_user_string(arg1)))
4523
            goto efault;
4524
        ret = get_errno(unlink(p));
4525
        unlock_user(p, arg1, 0);
4526
        break;
4527
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
4528
    case TARGET_NR_unlinkat:
4529
        if (!(p = lock_user_string(arg2)))
4530
            goto efault;
4531
        ret = get_errno(sys_unlinkat(arg1, p, arg3));
4532
        unlock_user(p, arg2, 0);
4533
        break;
4534
#endif
4535
    case TARGET_NR_execve:
4536
        {
4537
            char **argp, **envp;
4538
            int argc, envc;
4539
            abi_ulong gp;
4540
            abi_ulong guest_argp;
4541
            abi_ulong guest_envp;
4542
            abi_ulong addr;
4543
            char **q;
4544

    
4545
            argc = 0;
4546
            guest_argp = arg2;
4547
            for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
4548
                if (get_user_ual(addr, gp))
4549
                    goto efault;
4550
                if (!addr)
4551
                    break;
4552
                argc++;
4553
            }
4554
            envc = 0;
4555
            guest_envp = arg3;
4556
            for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
4557
                if (get_user_ual(addr, gp))
4558
                    goto efault;
4559
                if (!addr)
4560
                    break;
4561
                envc++;
4562
            }
4563

    
4564
            argp = alloca((argc + 1) * sizeof(void *));
4565
            envp = alloca((envc + 1) * sizeof(void *));
4566

    
4567
            for (gp = guest_argp, q = argp; gp;
4568
                  gp += sizeof(abi_ulong), q++) {
4569
                if (get_user_ual(addr, gp))
4570
                    goto execve_efault;
4571
                if (!addr)
4572
                    break;
4573
                if (!(*q = lock_user_string(addr)))
4574
                    goto execve_efault;
4575
            }
4576
            *q = NULL;
4577

    
4578
            for (gp = guest_envp, q = envp; gp;
4579
                  gp += sizeof(abi_ulong), q++) {
4580
                if (get_user_ual(addr, gp))
4581
                    goto execve_efault;
4582
                if (!addr)
4583
                    break;
4584
                if (!(*q = lock_user_string(addr)))
4585
                    goto execve_efault;
4586
            }
4587
            *q = NULL;
4588

    
4589
            if (!(p = lock_user_string(arg1)))
4590
                goto execve_efault;
4591
            ret = get_errno(execve(p, argp, envp));
4592
            unlock_user(p, arg1, 0);
4593

    
4594
            goto execve_end;
4595

    
4596
        execve_efault:
4597
            ret = -TARGET_EFAULT;
4598

    
4599
        execve_end:
4600
            for (gp = guest_argp, q = argp; *q;
4601
                  gp += sizeof(abi_ulong), q++) {
4602
                if (get_user_ual(addr, gp)
4603
                    || !addr)
4604
                    break;
4605
                unlock_user(*q, addr, 0);
4606
            }
4607
            for (gp = guest_envp, q = envp; *q;
4608
                  gp += sizeof(abi_ulong), q++) {
4609
                if (get_user_ual(addr, gp)
4610
                    || !addr)
4611
                    break;
4612
                unlock_user(*q, addr, 0);
4613
            }
4614
        }
4615
        break;
4616
    case TARGET_NR_chdir:
4617
        if (!(p = lock_user_string(arg1)))
4618
            goto efault;
4619
        ret = get_errno(chdir(p));
4620
        unlock_user(p, arg1, 0);
4621
        break;
4622
#ifdef TARGET_NR_time
4623
    case TARGET_NR_time:
4624
        {
4625
            time_t host_time;
4626
            ret = get_errno(time(&host_time));
4627
            if (!is_error(ret)
4628
                && arg1
4629
                && put_user_sal(host_time, arg1))
4630
                goto efault;
4631
        }
4632
        break;
4633
#endif
4634
    case TARGET_NR_mknod:
4635
        if (!(p = lock_user_string(arg1)))
4636
            goto efault;
4637
        ret = get_errno(mknod(p, arg2, arg3));
4638
        unlock_user(p, arg1, 0);
4639
        break;
4640
#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
4641
    case TARGET_NR_mknodat:
4642
        if (!(p = lock_user_string(arg2)))
4643
            goto efault;
4644
        ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
4645
        unlock_user(p, arg2, 0);
4646
        break;
4647
#endif
4648
    case TARGET_NR_chmod:
4649
        if (!(p = lock_user_string(arg1)))
4650
            goto efault;
4651
        ret = get_errno(chmod(p, arg2));
4652
        unlock_user(p, arg1, 0);
4653
        break;
4654
#ifdef TARGET_NR_break
4655
    case TARGET_NR_break:
4656
        goto unimplemented;
4657
#endif
4658
#ifdef TARGET_NR_oldstat
4659
    case TARGET_NR_oldstat:
4660
        goto unimplemented;
4661
#endif
4662
    case TARGET_NR_lseek:
4663
        ret = get_errno(lseek(arg1, arg2, arg3));
4664
        break;
4665
#if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA)
4666
    /* Alpha specific */
4667
    case TARGET_NR_getxpid:
4668
        ((CPUAlphaState *)cpu_env)->ir[IR_A4] = getppid();
4669
        ret = get_errno(getpid());
4670
        break;
4671
#endif
4672
#ifdef TARGET_NR_getpid
4673
    case TARGET_NR_getpid:
4674
        ret = get_errno(getpid());
4675
        break;
4676
#endif
4677
    case TARGET_NR_mount:
4678
                {
4679
                        /* need to look at the data field */
4680
                        void *p2, *p3;
4681
                        p = lock_user_string(arg1);
4682
                        p2 = lock_user_string(arg2);
4683
                        p3 = lock_user_string(arg3);
4684
                        if (!p || !p2 || !p3)
4685
                            ret = -TARGET_EFAULT;
4686
                        else {
4687
                            /* FIXME - arg5 should be locked, but it isn't clear how to
4688
                             * do that since it's not guaranteed to be a NULL-terminated
4689
                             * string.
4690
                             */
4691
                            if ( ! arg5 )
4692
                                ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, NULL));
4693
                            else
4694
                                ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
4695
                        }
4696
                        unlock_user(p, arg1, 0);
4697
                        unlock_user(p2, arg2, 0);
4698
                        unlock_user(p3, arg3, 0);
4699
                        break;
4700
                }
4701
#ifdef TARGET_NR_umount
4702
    case TARGET_NR_umount:
4703
        if (!(p = lock_user_string(arg1)))
4704
            goto efault;
4705
        ret = get_errno(umount(p));
4706
        unlock_user(p, arg1, 0);
4707
        break;
4708
#endif
4709
#ifdef TARGET_NR_stime /* not on alpha */
4710
    case TARGET_NR_stime:
4711
        {
4712
            time_t host_time;
4713
            if (get_user_sal(host_time, arg1))
4714
                goto efault;
4715
            ret = get_errno(stime(&host_time));
4716
        }
4717
        break;
4718
#endif
4719
    case TARGET_NR_ptrace:
4720
        goto unimplemented;
4721
#ifdef TARGET_NR_alarm /* not on alpha */
4722
    case TARGET_NR_alarm:
4723
        ret = alarm(arg1);
4724
        break;
4725
#endif
4726
#ifdef TARGET_NR_oldfstat
4727
    case TARGET_NR_oldfstat:
4728
        goto unimplemented;
4729
#endif
4730
#ifdef TARGET_NR_pause /* not on alpha */
4731
    case TARGET_NR_pause:
4732
        ret = get_errno(pause());
4733
        break;
4734
#endif
4735
#ifdef TARGET_NR_utime
4736
    case TARGET_NR_utime:
4737
        {
4738
            struct utimbuf tbuf, *host_tbuf;
4739
            struct target_utimbuf *target_tbuf;
4740
            if (arg2) {
4741
                if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
4742
                    goto efault;
4743
                tbuf.actime = tswapl(target_tbuf->actime);
4744
                tbuf.modtime = tswapl(target_tbuf->modtime);
4745
                unlock_user_struct(target_tbuf, arg2, 0);
4746
                host_tbuf = &tbuf;
4747
            } else {
4748
                host_tbuf = NULL;
4749
            }
4750
            if (!(p = lock_user_string(arg1)))
4751
                goto efault;
4752
            ret = get_errno(utime(p, host_tbuf));
4753
            unlock_user(p, arg1, 0);
4754
        }
4755
        break;
4756
#endif
4757
    case TARGET_NR_utimes:
4758
        {
4759
            struct timeval *tvp, tv[2];
4760
            if (arg2) {
4761
                if (copy_from_user_timeval(&tv[0], arg2)
4762
                    || copy_from_user_timeval(&tv[1],
4763
                                              arg2 + sizeof(struct target_timeval)))
4764
                    goto efault;
4765
                tvp = tv;
4766
            } else {
4767
                tvp = NULL;
4768
            }
4769
            if (!(p = lock_user_string(arg1)))
4770
                goto efault;
4771
            ret = get_errno(utimes(p, tvp));
4772
            unlock_user(p, arg1, 0);
4773
        }
4774
        break;
4775
#if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
4776
    case TARGET_NR_futimesat:
4777
        {
4778
            struct timeval *tvp, tv[2];
4779
            if (arg3) {
4780
                if (copy_from_user_timeval(&tv[0], arg3)
4781
                    || copy_from_user_timeval(&tv[1],
4782
                                              arg3 + sizeof(struct target_timeval)))
4783
                    goto efault;
4784
                tvp = tv;
4785
            } else {
4786
                tvp = NULL;
4787
            }
4788
            if (!(p = lock_user_string(arg2)))
4789
                goto efault;
4790
            ret = get_errno(sys_futimesat(arg1, path(p), tvp));
4791
            unlock_user(p, arg2, 0);
4792
        }
4793
        break;
4794
#endif
4795
#ifdef TARGET_NR_stty
4796
    case TARGET_NR_stty:
4797
        goto unimplemented;
4798
#endif
4799
#ifdef TARGET_NR_gtty
4800
    case TARGET_NR_gtty:
4801
        goto unimplemented;
4802
#endif
4803
    case TARGET_NR_access:
4804
        if (!(p = lock_user_string(arg1)))
4805
            goto efault;
4806
        ret = get_errno(access(path(p), arg2));
4807
        unlock_user(p, arg1, 0);
4808
        break;
4809
#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
4810
    case TARGET_NR_faccessat:
4811
        if (!(p = lock_user_string(arg2)))
4812
            goto efault;
4813
        ret = get_errno(sys_faccessat(arg1, p, arg3));
4814
        unlock_user(p, arg2, 0);
4815
        break;
4816
#endif
4817
#ifdef TARGET_NR_nice /* not on alpha */
4818
    case TARGET_NR_nice:
4819
        ret = get_errno(nice(arg1));
4820
        break;
4821
#endif
4822
#ifdef TARGET_NR_ftime
4823
    case TARGET_NR_ftime:
4824
        goto unimplemented;
4825
#endif
4826
    case TARGET_NR_sync:
4827
        sync();
4828
        ret = 0;
4829
        break;
4830
    case TARGET_NR_kill:
4831
        ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
4832
        break;
4833
    case TARGET_NR_rename:
4834
        {
4835
            void *p2;
4836
            p = lock_user_string(arg1);
4837
            p2 = lock_user_string(arg2);
4838
            if (!p || !p2)
4839
                ret = -TARGET_EFAULT;
4840
            else
4841
                ret = get_errno(rename(p, p2));
4842
            unlock_user(p2, arg2, 0);
4843
            unlock_user(p, arg1, 0);
4844
        }
4845
        break;
4846
#if defined(TARGET_NR_renameat) && defined(__NR_renameat)
4847
    case TARGET_NR_renameat:
4848
        {
4849
            void *p2;
4850
            p  = lock_user_string(arg2);
4851
            p2 = lock_user_string(arg4);
4852
            if (!p || !p2)
4853
                ret = -TARGET_EFAULT;
4854
            else
4855
                ret = get_errno(sys_renameat(arg1, p, arg3, p2));
4856
            unlock_user(p2, arg4, 0);
4857
            unlock_user(p, arg2, 0);
4858
        }
4859
        break;
4860
#endif
4861
    case TARGET_NR_mkdir:
4862
        if (!(p = lock_user_string(arg1)))
4863
            goto efault;
4864
        ret = get_errno(mkdir(p, arg2));
4865
        unlock_user(p, arg1, 0);
4866
        break;
4867
#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
4868
    case TARGET_NR_mkdirat:
4869
        if (!(p = lock_user_string(arg2)))
4870
            goto efault;
4871
        ret = get_errno(sys_mkdirat(arg1, p, arg3));
4872
        unlock_user(p, arg2, 0);
4873
        break;
4874
#endif
4875
    case TARGET_NR_rmdir:
4876
        if (!(p = lock_user_string(arg1)))
4877
            goto efault;
4878
        ret = get_errno(rmdir(p));
4879
        unlock_user(p, arg1, 0);
4880
        break;
4881
    case TARGET_NR_dup:
4882
        ret = get_errno(dup(arg1));
4883
        break;
4884
    case TARGET_NR_pipe:
4885
        ret = do_pipe(cpu_env, arg1, 0, 0);
4886
        break;
4887
#ifdef TARGET_NR_pipe2
4888
    case TARGET_NR_pipe2:
4889
        ret = do_pipe(cpu_env, arg1, arg2, 1);
4890
        break;
4891
#endif
4892
    case TARGET_NR_times:
4893
        {
4894
            struct target_tms *tmsp;
4895
            struct tms tms;
4896
            ret = get_errno(times(&tms));
4897
            if (arg1) {
4898
                tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
4899
                if (!tmsp)
4900
                    goto efault;
4901
                tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
4902
                tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
4903
                tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
4904
                tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime));
4905
            }
4906
            if (!is_error(ret))
4907
                ret = host_to_target_clock_t(ret);
4908
        }
4909
        break;
4910
#ifdef TARGET_NR_prof
4911
    case TARGET_NR_prof:
4912
        goto unimplemented;
4913
#endif
4914
#ifdef TARGET_NR_signal
4915
    case TARGET_NR_signal:
4916
        goto unimplemented;
4917
#endif
4918
    case TARGET_NR_acct:
4919
        if (arg1 == 0) {
4920
            ret = get_errno(acct(NULL));
4921
        } else {
4922
            if (!(p = lock_user_string(arg1)))
4923
                goto efault;
4924
            ret = get_errno(acct(path(p)));
4925
            unlock_user(p, arg1, 0);
4926
        }
4927
        break;
4928
#ifdef TARGET_NR_umount2 /* not on alpha */
4929
    case TARGET_NR_umount2:
4930
        if (!(p = lock_user_string(arg1)))
4931
            goto efault;
4932
        ret = get_errno(umount2(p, arg2));
4933
        unlock_user(p, arg1, 0);
4934
        break;
4935
#endif
4936
#ifdef TARGET_NR_lock
4937
    case TARGET_NR_lock:
4938
        goto unimplemented;
4939
#endif
4940
    case TARGET_NR_ioctl:
4941
        ret = do_ioctl(arg1, arg2, arg3);
4942
        break;
4943
    case TARGET_NR_fcntl:
4944
        ret = do_fcntl(arg1, arg2, arg3);
4945
        break;
4946
#ifdef TARGET_NR_mpx
4947
    case TARGET_NR_mpx:
4948
        goto unimplemented;
4949
#endif
4950
    case TARGET_NR_setpgid:
4951
        ret = get_errno(setpgid(arg1, arg2));
4952
        break;
4953
#ifdef TARGET_NR_ulimit
4954
    case TARGET_NR_ulimit:
4955
        goto unimplemented;
4956
#endif
4957
#ifdef TARGET_NR_oldolduname
4958
    case TARGET_NR_oldolduname:
4959
        goto unimplemented;
4960
#endif
4961
    case TARGET_NR_umask:
4962
        ret = get_errno(umask(arg1));
4963
        break;
4964
    case TARGET_NR_chroot:
4965
        if (!(p = lock_user_string(arg1)))
4966
            goto efault;
4967
        ret = get_errno(chroot(p));
4968
        unlock_user(p, arg1, 0);
4969
        break;
4970
    case TARGET_NR_ustat:
4971
        goto unimplemented;
4972
    case TARGET_NR_dup2:
4973
        ret = get_errno(dup2(arg1, arg2));
4974
        break;
4975
#if defined(CONFIG_DUP3) && defined(TARGET_NR_dup3)
4976
    case TARGET_NR_dup3:
4977
        ret = get_errno(dup3(arg1, arg2, arg3));
4978
        break;
4979
#endif
4980
#ifdef TARGET_NR_getppid /* not on alpha */
4981
    case TARGET_NR_getppid:
4982
        ret = get_errno(getppid());
4983
        break;
4984
#endif
4985
    case TARGET_NR_getpgrp:
4986
        ret = get_errno(getpgrp());
4987
        break;
4988
    case TARGET_NR_setsid:
4989
        ret = get_errno(setsid());
4990
        break;
4991
#ifdef TARGET_NR_sigaction
4992
    case TARGET_NR_sigaction:
4993
        {
4994
#if defined(TARGET_ALPHA)
4995
            struct target_sigaction act, oact, *pact = 0;
4996
            struct target_old_sigaction *old_act;
4997
            if (arg2) {
4998
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4999
                    goto efault;
5000
                act._sa_handler = old_act->_sa_handler;
5001
                target_siginitset(&act.sa_mask, old_act->sa_mask);
5002
                act.sa_flags = old_act->sa_flags;
5003
                act.sa_restorer = 0;
5004
                unlock_user_struct(old_act, arg2, 0);
5005
                pact = &act;
5006
            }
5007
            ret = get_errno(do_sigaction(arg1, pact, &oact));
5008
            if (!is_error(ret) && arg3) {
5009
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
5010
                    goto efault;
5011
                old_act->_sa_handler = oact._sa_handler;
5012
                old_act->sa_mask = oact.sa_mask.sig[0];
5013
                old_act->sa_flags = oact.sa_flags;
5014
                unlock_user_struct(old_act, arg3, 1);
5015
            }
5016
#elif defined(TARGET_MIPS)
5017
            struct target_sigaction act, oact, *pact, *old_act;
5018

    
5019
            if (arg2) {
5020
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
5021
                    goto efault;
5022
                act._sa_handler = old_act->_sa_handler;
5023
                target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
5024
                act.sa_flags = old_act->sa_flags;
5025
                unlock_user_struct(old_act, arg2, 0);
5026
                pact = &act;
5027
            } else {
5028
                pact = NULL;
5029
            }
5030

    
5031
            ret = get_errno(do_sigaction(arg1, pact, &oact));
5032

    
5033
            if (!is_error(ret) && arg3) {
5034
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
5035
                    goto efault;
5036
                old_act->_sa_handler = oact._sa_handler;
5037
                old_act->sa_flags = oact.sa_flags;
5038
                old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
5039
                old_act->sa_mask.sig[1] = 0;
5040
                old_act->sa_mask.sig[2] = 0;
5041
                old_act->sa_mask.sig[3] = 0;
5042
                unlock_user_struct(old_act, arg3, 1);
5043
            }
5044
#else
5045
            struct target_old_sigaction *old_act;
5046
            struct target_sigaction act, oact, *pact;
5047
            if (arg2) {
5048
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
5049
                    goto efault;
5050
                act._sa_handler = old_act->_sa_handler;
5051
                target_siginitset(&act.sa_mask, old_act->sa_mask);
5052
                act.sa_flags = old_act->sa_flags;
5053
                act.sa_restorer = old_act->sa_restorer;
5054
                unlock_user_struct(old_act, arg2, 0);
5055
                pact = &act;
5056
            } else {
5057
                pact = NULL;
5058
            }
5059
            ret = get_errno(do_sigaction(arg1, pact, &oact));
5060
            if (!is_error(ret) && arg3) {
5061
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
5062
                    goto efault;
5063
                old_act->_sa_handler = oact._sa_handler;
5064
                old_act->sa_mask = oact.sa_mask.sig[0];
5065
                old_act->sa_flags = oact.sa_flags;
5066
                old_act->sa_restorer = oact.sa_restorer;
5067
                unlock_user_struct(old_act, arg3, 1);
5068
            }
5069
#endif
5070
        }
5071
        break;
5072
#endif
5073
    case TARGET_NR_rt_sigaction:
5074
        {
5075
#if defined(TARGET_ALPHA)
5076
            struct target_sigaction act, oact, *pact = 0;
5077
            struct target_rt_sigaction *rt_act;
5078
            /* ??? arg4 == sizeof(sigset_t).  */
5079
            if (arg2) {
5080
                if (!lock_user_struct(VERIFY_READ, rt_act, arg2, 1))
5081
                    goto efault;
5082
                act._sa_handler = rt_act->_sa_handler;
5083
                act.sa_mask = rt_act->sa_mask;
5084
                act.sa_flags = rt_act->sa_flags;
5085
                act.sa_restorer = arg5;
5086
                unlock_user_struct(rt_act, arg2, 0);
5087
                pact = &act;
5088
            }
5089
            ret = get_errno(do_sigaction(arg1, pact, &oact));
5090
            if (!is_error(ret) && arg3) {
5091
                if (!lock_user_struct(VERIFY_WRITE, rt_act, arg3, 0))
5092
                    goto efault;
5093
                rt_act->_sa_handler = oact._sa_handler;
5094
                rt_act->sa_mask = oact.sa_mask;
5095
                rt_act->sa_flags = oact.sa_flags;
5096
                unlock_user_struct(rt_act, arg3, 1);
5097
            }
5098
#else
5099
            struct target_sigaction *act;
5100
            struct target_sigaction *oact;
5101

    
5102
            if (arg2) {
5103
                if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
5104
                    goto efault;
5105
            } else
5106
                act = NULL;
5107
            if (arg3) {
5108
                if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
5109
                    ret = -TARGET_EFAULT;
5110
                    goto rt_sigaction_fail;
5111
                }
5112
            } else
5113
                oact = NULL;
5114
            ret = get_errno(do_sigaction(arg1, act, oact));
5115
        rt_sigaction_fail:
5116
            if (act)
5117
                unlock_user_struct(act, arg2, 0);
5118
            if (oact)
5119
                unlock_user_struct(oact, arg3, 1);
5120
#endif
5121
        }
5122
        break;
5123
#ifdef TARGET_NR_sgetmask /* not on alpha */
5124
    case TARGET_NR_sgetmask:
5125
        {
5126
            sigset_t cur_set;
5127
            abi_ulong target_set;
5128
            sigprocmask(0, NULL, &cur_set);
5129
            host_to_target_old_sigset(&target_set, &cur_set);
5130
            ret = target_set;
5131
        }
5132
        break;
5133
#endif
5134
#ifdef TARGET_NR_ssetmask /* not on alpha */
5135
    case TARGET_NR_ssetmask:
5136
        {
5137
            sigset_t set, oset, cur_set;
5138
            abi_ulong target_set = arg1;
5139
            sigprocmask(0, NULL, &cur_set);
5140
            target_to_host_old_sigset(&set, &target_set);
5141
            sigorset(&set, &set, &cur_set);
5142
            sigprocmask(SIG_SETMASK, &set, &oset);
5143
            host_to_target_old_sigset(&target_set, &oset);
5144
            ret = target_set;
5145
        }
5146
        break;
5147
#endif
5148
#ifdef TARGET_NR_sigprocmask
5149
    case TARGET_NR_sigprocmask:
5150
        {
5151
#if defined(TARGET_ALPHA)
5152
            sigset_t set, oldset;
5153
            abi_ulong mask;
5154
            int how;
5155

    
5156
            switch (arg1) {
5157
            case TARGET_SIG_BLOCK:
5158
                how = SIG_BLOCK;
5159
                break;
5160
            case TARGET_SIG_UNBLOCK:
5161
                how = SIG_UNBLOCK;
5162
                break;
5163
            case TARGET_SIG_SETMASK:
5164
                how = SIG_SETMASK;
5165
                break;
5166
            default:
5167
                ret = -TARGET_EINVAL;
5168
                goto fail;
5169
            }
5170
            mask = arg2;
5171
            target_to_host_old_sigset(&set, &mask);
5172

    
5173
            ret = get_errno(sigprocmask(how, &set, &oldset));
5174

    
5175
            if (!is_error(ret)) {
5176
                host_to_target_old_sigset(&mask, &oldset);
5177
                ret = mask;
5178
                ((CPUAlphaState *)cpu_env)->[IR_V0] = 0; /* force no error */
5179
            }
5180
#else
5181
            sigset_t set, oldset, *set_ptr;
5182
            int how;
5183

    
5184
            if (arg2) {
5185
                switch (arg1) {
5186
                case TARGET_SIG_BLOCK:
5187
                    how = SIG_BLOCK;
5188
                    break;
5189
                case TARGET_SIG_UNBLOCK:
5190
                    how = SIG_UNBLOCK;
5191
                    break;
5192
                case TARGET_SIG_SETMASK:
5193
                    how = SIG_SETMASK;
5194
                    break;
5195
                default:
5196
                    ret = -TARGET_EINVAL;
5197
                    goto fail;
5198
                }
5199
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
5200
                    goto efault;
5201
                target_to_host_old_sigset(&set, p);
5202
                unlock_user(p, arg2, 0);
5203
                set_ptr = &set;
5204
            } else {
5205
                how = 0;
5206
                set_ptr = NULL;
5207
            }
5208
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
5209
            if (!is_error(ret) && arg3) {
5210
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
5211
                    goto efault;
5212
                host_to_target_old_sigset(p, &oldset);
5213
                unlock_user(p, arg3, sizeof(target_sigset_t));
5214
            }
5215
#endif
5216
        }
5217
        break;
5218
#endif
5219
    case TARGET_NR_rt_sigprocmask:
5220
        {
5221
            int how = arg1;
5222
            sigset_t set, oldset, *set_ptr;
5223

    
5224
            if (arg2) {
5225
                switch(how) {
5226
                case TARGET_SIG_BLOCK:
5227
                    how = SIG_BLOCK;
5228
                    break;
5229
                case TARGET_SIG_UNBLOCK:
5230
                    how = SIG_UNBLOCK;
5231
                    break;
5232
                case TARGET_SIG_SETMASK:
5233
                    how = SIG_SETMASK;
5234
                    break;
5235
                default:
5236
                    ret = -TARGET_EINVAL;
5237
                    goto fail;
5238
                }
5239
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
5240
                    goto efault;
5241
                target_to_host_sigset(&set, p);
5242
                unlock_user(p, arg2, 0);
5243
                set_ptr = &set;
5244
            } else {
5245
                how = 0;
5246
                set_ptr = NULL;
5247
            }
5248
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
5249
            if (!is_error(ret) && arg3) {
5250
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
5251
                    goto efault;
5252
                host_to_target_sigset(p, &oldset);
5253
                unlock_user(p, arg3, sizeof(target_sigset_t));
5254
            }
5255
        }
5256
        break;
5257
#ifdef TARGET_NR_sigpending
5258
    case TARGET_NR_sigpending:
5259
        {
5260
            sigset_t set;
5261
            ret = get_errno(sigpending(&set));
5262
            if (!is_error(ret)) {
5263
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
5264
                    goto efault;
5265
                host_to_target_old_sigset(p, &set);
5266
                unlock_user(p, arg1, sizeof(target_sigset_t));
5267
            }
5268
        }
5269
        break;
5270
#endif
5271
    case TARGET_NR_rt_sigpending:
5272
        {
5273
            sigset_t set;
5274
            ret = get_errno(sigpending(&set));
5275
            if (!is_error(ret)) {
5276
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
5277
                    goto efault;
5278
                host_to_target_sigset(p, &set);
5279
                unlock_user(p, arg1, sizeof(target_sigset_t));
5280
            }
5281
        }
5282
        break;
5283
#ifdef TARGET_NR_sigsuspend
5284
    case TARGET_NR_sigsuspend:
5285
        {
5286
            sigset_t set;
5287
#if defined(TARGET_ALPHA)
5288
            abi_ulong mask = arg1;
5289
            target_to_host_old_sigset(&set, &mask);
5290
#else
5291
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
5292
                goto efault;
5293
            target_to_host_old_sigset(&set, p);
5294
            unlock_user(p, arg1, 0);
5295
#endif
5296
            ret = get_errno(sigsuspend(&set));
5297
        }
5298
        break;
5299
#endif
5300
    case TARGET_NR_rt_sigsuspend:
5301
        {
5302
            sigset_t set;
5303
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
5304
                goto efault;
5305
            target_to_host_sigset(&set, p);
5306
            unlock_user(p, arg1, 0);
5307
            ret = get_errno(sigsuspend(&set));
5308
        }
5309
        break;
5310
    case TARGET_NR_rt_sigtimedwait:
5311
        {
5312
            sigset_t set;
5313
            struct timespec uts, *puts;
5314
            siginfo_t uinfo;
5315

    
5316
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
5317
                goto efault;
5318
            target_to_host_sigset(&set, p);
5319
            unlock_user(p, arg1, 0);
5320
            if (arg3) {
5321
                puts = &uts;
5322
                target_to_host_timespec(puts, arg3);
5323
            } else {
5324
                puts = NULL;
5325
            }
5326
            ret = get_errno(sigtimedwait(&set, &uinfo, puts));
5327
            if (!is_error(ret) && arg2) {
5328
                if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
5329
                    goto efault;
5330
                host_to_target_siginfo(p, &uinfo);
5331
                unlock_user(p, arg2, sizeof(target_siginfo_t));
5332
            }
5333
        }
5334
        break;
5335
    case TARGET_NR_rt_sigqueueinfo:
5336
        {
5337
            siginfo_t uinfo;
5338
            if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
5339
                goto efault;
5340
            target_to_host_siginfo(&uinfo, p);
5341
            unlock_user(p, arg1, 0);
5342
            ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
5343
        }
5344
        break;
5345
#ifdef TARGET_NR_sigreturn
5346
    case TARGET_NR_sigreturn:
5347
        /* NOTE: ret is eax, so not transcoding must be done */
5348
        ret = do_sigreturn(cpu_env);
5349
        break;
5350
#endif
5351
    case TARGET_NR_rt_sigreturn:
5352
        /* NOTE: ret is eax, so not transcoding must be done */
5353
        ret = do_rt_sigreturn(cpu_env);
5354
        break;
5355
    case TARGET_NR_sethostname:
5356
        if (!(p = lock_user_string(arg1)))
5357
            goto efault;
5358
        ret = get_errno(sethostname(p, arg2));
5359
        unlock_user(p, arg1, 0);
5360
        break;
5361
    case TARGET_NR_setrlimit:
5362
        {
5363
            int resource = arg1;
5364
            struct target_rlimit *target_rlim;
5365
            struct rlimit rlim;
5366
            if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
5367
                goto efault;
5368
            rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur);
5369
            rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max);
5370
            unlock_user_struct(target_rlim, arg2, 0);
5371
            ret = get_errno(setrlimit(resource, &rlim));
5372
        }
5373
        break;
5374
    case TARGET_NR_getrlimit:
5375
        {
5376
            int resource = arg1;
5377
            struct target_rlimit *target_rlim;
5378
            struct rlimit rlim;
5379

    
5380
            ret = get_errno(getrlimit(resource, &rlim));
5381
            if (!is_error(ret)) {
5382
                if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
5383
                    goto efault;
5384
                target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
5385
                target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
5386
                unlock_user_struct(target_rlim, arg2, 1);
5387
            }
5388
        }
5389
        break;
5390
    case TARGET_NR_getrusage:
5391
        {
5392
            struct rusage rusage;
5393
            ret = get_errno(getrusage(arg1, &rusage));
5394
            if (!is_error(ret)) {
5395
                host_to_target_rusage(arg2, &rusage);
5396
            }
5397
        }
5398
        break;
5399
    case TARGET_NR_gettimeofday:
5400
        {
5401
            struct timeval tv;
5402
            ret = get_errno(gettimeofday(&tv, NULL));
5403
            if (!is_error(ret)) {
5404
                if (copy_to_user_timeval(arg1, &tv))
5405
                    goto efault;
5406
            }
5407
        }
5408
        break;
5409
    case TARGET_NR_settimeofday:
5410
        {
5411
            struct timeval tv;
5412
            if (copy_from_user_timeval(&tv, arg1))
5413
                goto efault;
5414
            ret = get_errno(settimeofday(&tv, NULL));
5415
        }
5416
        break;
5417
#ifdef TARGET_NR_select
5418
    case TARGET_NR_select:
5419
        {
5420
            struct target_sel_arg_struct *sel;
5421
            abi_ulong inp, outp, exp, tvp;
5422
            long nsel;
5423

    
5424
            if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
5425
                goto efault;
5426
            nsel = tswapl(sel->n);
5427
            inp = tswapl(sel->inp);
5428
            outp = tswapl(sel->outp);
5429
            exp = tswapl(sel->exp);
5430
            tvp = tswapl(sel->tvp);
5431
            unlock_user_struct(sel, arg1, 0);
5432
            ret = do_select(nsel, inp, outp, exp, tvp);
5433
        }
5434
        break;
5435
#endif
5436
#ifdef TARGET_NR_pselect6
5437
    case TARGET_NR_pselect6:
5438
            goto unimplemented_nowarn;
5439
#endif
5440
    case TARGET_NR_symlink:
5441
        {
5442
            void *p2;
5443
            p = lock_user_string(arg1);
5444
            p2 = lock_user_string(arg2);
5445
            if (!p || !p2)
5446
                ret = -TARGET_EFAULT;
5447
            else
5448
                ret = get_errno(symlink(p, p2));
5449
            unlock_user(p2, arg2, 0);
5450
            unlock_user(p, arg1, 0);
5451
        }
5452
        break;
5453
#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
5454
    case TARGET_NR_symlinkat:
5455
        {
5456
            void *p2;
5457
            p  = lock_user_string(arg1);
5458
            p2 = lock_user_string(arg3);
5459
            if (!p || !p2)
5460
                ret = -TARGET_EFAULT;
5461
            else
5462
                ret = get_errno(sys_symlinkat(p, arg2, p2));
5463
            unlock_user(p2, arg3, 0);
5464
            unlock_user(p, arg1, 0);
5465
        }
5466
        break;
5467
#endif
5468
#ifdef TARGET_NR_oldlstat
5469
    case TARGET_NR_oldlstat:
5470
        goto unimplemented;
5471
#endif
5472
    case TARGET_NR_readlink:
5473
        {
5474
            void *p2, *temp;
5475
            p = lock_user_string(arg1);
5476
            p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
5477
            if (!p || !p2)
5478
                ret = -TARGET_EFAULT;
5479
            else {
5480
                if (strncmp((const char *)p, "/proc/self/exe", 14) == 0) {
5481
                    char real[PATH_MAX];
5482
                    temp = realpath(exec_path,real);
5483
                    ret = (temp==NULL) ? get_errno(-1) : strlen(real) ;
5484
                    snprintf((char *)p2, arg3, "%s", real);
5485
                    }
5486
                else
5487
                    ret = get_errno(readlink(path(p), p2, arg3));
5488
            }
5489
            unlock_user(p2, arg2, ret);
5490
            unlock_user(p, arg1, 0);
5491
        }
5492
        break;
5493
#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
5494
    case TARGET_NR_readlinkat:
5495
        {
5496
            void *p2;
5497
            p  = lock_user_string(arg2);
5498
            p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
5499
            if (!p || !p2)
5500
                ret = -TARGET_EFAULT;
5501
            else
5502
                ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
5503
            unlock_user(p2, arg3, ret);
5504
            unlock_user(p, arg2, 0);
5505
        }
5506
        break;
5507
#endif
5508
#ifdef TARGET_NR_uselib
5509
    case TARGET_NR_uselib:
5510
        goto unimplemented;
5511
#endif
5512
#ifdef TARGET_NR_swapon
5513
    case TARGET_NR_swapon:
5514
        if (!(p = lock_user_string(arg1)))
5515
            goto efault;
5516
        ret = get_errno(swapon(p, arg2));
5517
        unlock_user(p, arg1, 0);
5518
        break;
5519
#endif
5520
    case TARGET_NR_reboot:
5521
        goto unimplemented;
5522
#ifdef TARGET_NR_readdir
5523
    case TARGET_NR_readdir:
5524
        goto unimplemented;
5525
#endif
5526
#ifdef TARGET_NR_mmap
5527
    case TARGET_NR_mmap:
5528
#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE)
5529
        {
5530
            abi_ulong *v;
5531
            abi_ulong v1, v2, v3, v4, v5, v6;
5532
            if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
5533
                goto efault;
5534
            v1 = tswapl(v[0]);
5535
            v2 = tswapl(v[1]);
5536
            v3 = tswapl(v[2]);
5537
            v4 = tswapl(v[3]);
5538
            v5 = tswapl(v[4]);
5539
            v6 = tswapl(v[5]);
5540
            unlock_user(v, arg1, 0);
5541
            ret = get_errno(target_mmap(v1, v2, v3,
5542
                                        target_to_host_bitmask(v4, mmap_flags_tbl),
5543
                                        v5, v6));
5544
        }
5545
#else
5546
        ret = get_errno(target_mmap(arg1, arg2, arg3,
5547
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
5548
                                    arg5,
5549
                                    arg6));
5550
#endif
5551
        break;
5552
#endif
5553
#ifdef TARGET_NR_mmap2
5554
    case TARGET_NR_mmap2:
5555
#ifndef MMAP_SHIFT
5556
#define MMAP_SHIFT 12
5557
#endif
5558
        ret = get_errno(target_mmap(arg1, arg2, arg3,
5559
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
5560
                                    arg5,
5561
                                    arg6 << MMAP_SHIFT));
5562
        break;
5563
#endif
5564
    case TARGET_NR_munmap:
5565
        ret = get_errno(target_munmap(arg1, arg2));
5566
        break;
5567
    case TARGET_NR_mprotect:
5568
        {
5569
            TaskState *ts = ((CPUState *)cpu_env)->opaque;
5570
            /* Special hack to detect libc making the stack executable.  */
5571
            if ((arg3 & PROT_GROWSDOWN)
5572
                && arg1 >= ts->info->stack_limit
5573
                && arg1 <= ts->info->start_stack) {
5574
                arg3 &= ~PROT_GROWSDOWN;
5575
                arg2 = arg2 + arg1 - ts->info->stack_limit;
5576
                arg1 = ts->info->stack_limit;
5577
            }
5578
        }
5579
        ret = get_errno(target_mprotect(arg1, arg2, arg3));
5580
        break;
5581
#ifdef TARGET_NR_mremap
5582
    case TARGET_NR_mremap:
5583
        ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
5584
        break;
5585
#endif
5586
        /* ??? msync/mlock/munlock are broken for softmmu.  */
5587
#ifdef TARGET_NR_msync
5588
    case TARGET_NR_msync:
5589
        ret = get_errno(msync(g2h(arg1), arg2, arg3));
5590
        break;
5591
#endif
5592
#ifdef TARGET_NR_mlock
5593
    case TARGET_NR_mlock:
5594
        ret = get_errno(mlock(g2h(arg1), arg2));
5595
        break;
5596
#endif
5597
#ifdef TARGET_NR_munlock
5598
    case TARGET_NR_munlock:
5599
        ret = get_errno(munlock(g2h(arg1), arg2));
5600
        break;
5601
#endif
5602
#ifdef TARGET_NR_mlockall
5603
    case TARGET_NR_mlockall:
5604
        ret = get_errno(mlockall(arg1));
5605
        break;
5606
#endif
5607
#ifdef TARGET_NR_munlockall
5608
    case TARGET_NR_munlockall:
5609
        ret = get_errno(munlockall());
5610
        break;
5611
#endif
5612
    case TARGET_NR_truncate:
5613
        if (!(p = lock_user_string(arg1)))
5614
            goto efault;
5615
        ret = get_errno(truncate(p, arg2));
5616
        unlock_user(p, arg1, 0);
5617
        break;
5618
    case TARGET_NR_ftruncate:
5619
        ret = get_errno(ftruncate(arg1, arg2));
5620
        break;
5621
    case TARGET_NR_fchmod:
5622
        ret = get_errno(fchmod(arg1, arg2));
5623
        break;
5624
#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
5625
    case TARGET_NR_fchmodat:
5626
        if (!(p = lock_user_string(arg2)))
5627
            goto efault;
5628
        ret = get_errno(sys_fchmodat(arg1, p, arg3));
5629
        unlock_user(p, arg2, 0);
5630
        break;
5631
#endif
5632
    case TARGET_NR_getpriority:
5633
        /* libc does special remapping of the return value of
5634
         * sys_getpriority() so it's just easiest to call
5635
         * sys_getpriority() directly rather than through libc. */
5636
        ret = get_errno(sys_getpriority(arg1, arg2));
5637
        break;
5638
    case TARGET_NR_setpriority:
5639
        ret = get_errno(setpriority(arg1, arg2, arg3));
5640
        break;
5641
#ifdef TARGET_NR_profil
5642
    case TARGET_NR_profil:
5643
        goto unimplemented;
5644
#endif
5645
    case TARGET_NR_statfs:
5646
        if (!(p = lock_user_string(arg1)))
5647
            goto efault;
5648
        ret = get_errno(statfs(path(p), &stfs));
5649
        unlock_user(p, arg1, 0);
5650
    convert_statfs:
5651
        if (!is_error(ret)) {
5652
            struct target_statfs *target_stfs;
5653

    
5654
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
5655
                goto efault;
5656
            __put_user(stfs.f_type, &target_stfs->f_type);
5657
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
5658
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
5659
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
5660
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
5661
            __put_user(stfs.f_files, &target_stfs->f_files);
5662
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
5663
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
5664
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
5665
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
5666
            unlock_user_struct(target_stfs, arg2, 1);
5667
        }
5668
        break;
5669
    case TARGET_NR_fstatfs:
5670
        ret = get_errno(fstatfs(arg1, &stfs));
5671
        goto convert_statfs;
5672
#ifdef TARGET_NR_statfs64
5673
    case TARGET_NR_statfs64:
5674
        if (!(p = lock_user_string(arg1)))
5675
            goto efault;
5676
        ret = get_errno(statfs(path(p), &stfs));
5677
        unlock_user(p, arg1, 0);
5678
    convert_statfs64:
5679
        if (!is_error(ret)) {
5680
            struct target_statfs64 *target_stfs;
5681

    
5682
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
5683
                goto efault;
5684
            __put_user(stfs.f_type, &target_stfs->f_type);
5685
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
5686
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
5687
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
5688
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
5689
            __put_user(stfs.f_files, &target_stfs->f_files);
5690
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
5691
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
5692
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
5693
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
5694
            unlock_user_struct(target_stfs, arg3, 1);
5695
        }
5696
        break;
5697
    case TARGET_NR_fstatfs64:
5698
        ret = get_errno(fstatfs(arg1, &stfs));
5699
        goto convert_statfs64;
5700
#endif
5701
#ifdef TARGET_NR_ioperm
5702
    case TARGET_NR_ioperm:
5703
        goto unimplemented;
5704
#endif
5705
#ifdef TARGET_NR_socketcall
5706
    case TARGET_NR_socketcall:
5707
        ret = do_socketcall(arg1, arg2);
5708
        break;
5709
#endif
5710
#ifdef TARGET_NR_accept
5711
    case TARGET_NR_accept:
5712
        ret = do_accept(arg1, arg2, arg3);
5713
        break;
5714
#endif
5715
#ifdef TARGET_NR_bind
5716
    case TARGET_NR_bind:
5717
        ret = do_bind(arg1, arg2, arg3);
5718
        break;
5719
#endif
5720
#ifdef TARGET_NR_connect
5721
    case TARGET_NR_connect:
5722
        ret = do_connect(arg1, arg2, arg3);
5723
        break;
5724
#endif
5725
#ifdef TARGET_NR_getpeername
5726
    case TARGET_NR_getpeername:
5727
        ret = do_getpeername(arg1, arg2, arg3);
5728
        break;
5729
#endif
5730
#ifdef TARGET_NR_getsockname
5731
    case TARGET_NR_getsockname:
5732
        ret = do_getsockname(arg1, arg2, arg3);
5733
        break;
5734
#endif
5735
#ifdef TARGET_NR_getsockopt
5736
    case TARGET_NR_getsockopt:
5737
        ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
5738
        break;
5739
#endif
5740
#ifdef TARGET_NR_listen
5741
    case TARGET_NR_listen:
5742
        ret = get_errno(listen(arg1, arg2));
5743
        break;
5744
#endif
5745
#ifdef TARGET_NR_recv
5746
    case TARGET_NR_recv:
5747
        ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
5748
        break;
5749
#endif
5750
#ifdef TARGET_NR_recvfrom
5751
    case TARGET_NR_recvfrom:
5752
        ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
5753
        break;
5754
#endif
5755
#ifdef TARGET_NR_recvmsg
5756
    case TARGET_NR_recvmsg:
5757
        ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
5758
        break;
5759
#endif
5760
#ifdef TARGET_NR_send
5761
    case TARGET_NR_send:
5762
        ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
5763
        break;
5764
#endif
5765
#ifdef TARGET_NR_sendmsg
5766
    case TARGET_NR_sendmsg:
5767
        ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
5768
        break;
5769
#endif
5770
#ifdef TARGET_NR_sendto
5771
    case TARGET_NR_sendto:
5772
        ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
5773
        break;
5774
#endif
5775
#ifdef TARGET_NR_shutdown
5776
    case TARGET_NR_shutdown:
5777
        ret = get_errno(shutdown(arg1, arg2));
5778
        break;
5779
#endif
5780
#ifdef TARGET_NR_socket
5781
    case TARGET_NR_socket:
5782
        ret = do_socket(arg1, arg2, arg3);
5783
        break;
5784
#endif
5785
#ifdef TARGET_NR_socketpair
5786
    case TARGET_NR_socketpair:
5787
        ret = do_socketpair(arg1, arg2, arg3, arg4);
5788
        break;
5789
#endif
5790
#ifdef TARGET_NR_setsockopt
5791
    case TARGET_NR_setsockopt:
5792
        ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
5793
        break;
5794
#endif
5795

    
5796
    case TARGET_NR_syslog:
5797
        if (!(p = lock_user_string(arg2)))
5798
            goto efault;
5799
        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
5800
        unlock_user(p, arg2, 0);
5801
        break;
5802

    
5803
    case TARGET_NR_setitimer:
5804
        {
5805
            struct itimerval value, ovalue, *pvalue;
5806

    
5807
            if (arg2) {
5808
                pvalue = &value;
5809
                if (copy_from_user_timeval(&pvalue->it_interval, arg2)
5810
                    || copy_from_user_timeval(&pvalue->it_value,
5811
                                              arg2 + sizeof(struct target_timeval)))
5812
                    goto efault;
5813
            } else {
5814
                pvalue = NULL;
5815
            }
5816
            ret = get_errno(setitimer(arg1, pvalue, &ovalue));
5817
            if (!is_error(ret) && arg3) {
5818
                if (copy_to_user_timeval(arg3,
5819
                                         &ovalue.it_interval)
5820
                    || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
5821
                                            &ovalue.it_value))
5822
                    goto efault;
5823
            }
5824
        }
5825
        break;
5826
    case TARGET_NR_getitimer:
5827
        {
5828
            struct itimerval value;
5829

    
5830
            ret = get_errno(getitimer(arg1, &value));
5831
            if (!is_error(ret) && arg2) {
5832
                if (copy_to_user_timeval(arg2,
5833
                                         &value.it_interval)
5834
                    || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
5835
                                            &value.it_value))
5836
                    goto efault;
5837
            }
5838
        }
5839
        break;
5840
    case TARGET_NR_stat:
5841
        if (!(p = lock_user_string(arg1)))
5842
            goto efault;
5843
        ret = get_errno(stat(path(p), &st));
5844
        unlock_user(p, arg1, 0);
5845
        goto do_stat;
5846
    case TARGET_NR_lstat:
5847
        if (!(p = lock_user_string(arg1)))
5848
            goto efault;
5849
        ret = get_errno(lstat(path(p), &st));
5850
        unlock_user(p, arg1, 0);
5851
        goto do_stat;
5852
    case TARGET_NR_fstat:
5853
        {
5854
            ret = get_errno(fstat(arg1, &st));
5855
        do_stat:
5856
            if (!is_error(ret)) {
5857
                struct target_stat *target_st;
5858

    
5859
                if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
5860
                    goto efault;
5861
                memset(target_st, 0, sizeof(*target_st));
5862
                __put_user(st.st_dev, &target_st->st_dev);
5863
                __put_user(st.st_ino, &target_st->st_ino);
5864
                __put_user(st.st_mode, &target_st->st_mode);
5865
                __put_user(st.st_uid, &target_st->st_uid);
5866
                __put_user(st.st_gid, &target_st->st_gid);
5867
                __put_user(st.st_nlink, &target_st->st_nlink);
5868
                __put_user(st.st_rdev, &target_st->st_rdev);
5869
                __put_user(st.st_size, &target_st->st_size);
5870
                __put_user(st.st_blksize, &target_st->st_blksize);
5871
                __put_user(st.st_blocks, &target_st->st_blocks);
5872
                __put_user(st.st_atime, &target_st->target_st_atime);
5873
                __put_user(st.st_mtime, &target_st->target_st_mtime);
5874
                __put_user(st.st_ctime, &target_st->target_st_ctime);
5875
                unlock_user_struct(target_st, arg2, 1);
5876
            }
5877
        }
5878
        break;
5879
#ifdef TARGET_NR_olduname
5880
    case TARGET_NR_olduname:
5881
        goto unimplemented;
5882
#endif
5883
#ifdef TARGET_NR_iopl
5884
    case TARGET_NR_iopl:
5885
        goto unimplemented;
5886
#endif
5887
    case TARGET_NR_vhangup:
5888
        ret = get_errno(vhangup());
5889
        break;
5890
#ifdef TARGET_NR_idle
5891
    case TARGET_NR_idle:
5892
        goto unimplemented;
5893
#endif
5894
#ifdef TARGET_NR_syscall
5895
    case TARGET_NR_syscall:
5896
            ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
5897
            break;
5898
#endif
5899
    case TARGET_NR_wait4:
5900
        {
5901
            int status;
5902
            abi_long status_ptr = arg2;
5903
            struct rusage rusage, *rusage_ptr;
5904
            abi_ulong target_rusage = arg4;
5905
            if (target_rusage)
5906
                rusage_ptr = &rusage;
5907
            else
5908
                rusage_ptr = NULL;
5909
            ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
5910
            if (!is_error(ret)) {
5911
                if (status_ptr) {
5912
                    status = host_to_target_waitstatus(status);
5913
                    if (put_user_s32(status, status_ptr))
5914
                        goto efault;
5915
                }
5916
                if (target_rusage)
5917
                    host_to_target_rusage(target_rusage, &rusage);
5918
            }
5919
        }
5920
        break;
5921
#ifdef TARGET_NR_swapoff
5922
    case TARGET_NR_swapoff:
5923
        if (!(p = lock_user_string(arg1)))
5924
            goto efault;
5925
        ret = get_errno(swapoff(p));
5926
        unlock_user(p, arg1, 0);
5927
        break;
5928
#endif
5929
    case TARGET_NR_sysinfo:
5930
        {
5931
            struct target_sysinfo *target_value;
5932
            struct sysinfo value;
5933
            ret = get_errno(sysinfo(&value));
5934
            if (!is_error(ret) && arg1)
5935
            {
5936
                if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
5937
                    goto efault;
5938
                __put_user(value.uptime, &target_value->uptime);
5939
                __put_user(value.loads[0], &target_value->loads[0]);
5940
                __put_user(value.loads[1], &target_value->loads[1]);
5941
                __put_user(value.loads[2], &target_value->loads[2]);
5942
                __put_user(value.totalram, &target_value->totalram);
5943
                __put_user(value.freeram, &target_value->freeram);
5944
                __put_user(value.sharedram, &target_value->sharedram);
5945
                __put_user(value.bufferram, &target_value->bufferram);
5946
                __put_user(value.totalswap, &target_value->totalswap);
5947
                __put_user(value.freeswap, &target_value->freeswap);
5948
                __put_user(value.procs, &target_value->procs);
5949
                __put_user(value.totalhigh, &target_value->totalhigh);
5950
                __put_user(value.freehigh, &target_value->freehigh);
5951
                __put_user(value.mem_unit, &target_value->mem_unit);
5952
                unlock_user_struct(target_value, arg1, 1);
5953
            }
5954
        }
5955
        break;
5956
#ifdef TARGET_NR_ipc
5957
    case TARGET_NR_ipc:
5958
        ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
5959
        break;
5960
#endif
5961
#ifdef TARGET_NR_semget
5962
    case TARGET_NR_semget:
5963
        ret = get_errno(semget(arg1, arg2, arg3));
5964
        break;
5965
#endif
5966
#ifdef TARGET_NR_semop
5967
    case TARGET_NR_semop:
5968
        ret = get_errno(do_semop(arg1, arg2, arg3));
5969
        break;
5970
#endif
5971
#ifdef TARGET_NR_semctl
5972
    case TARGET_NR_semctl:
5973
        ret = do_semctl(arg1, arg2, arg3, (union target_semun)(abi_ulong)arg4);
5974
        break;
5975
#endif
5976
#ifdef TARGET_NR_msgctl
5977
    case TARGET_NR_msgctl:
5978
        ret = do_msgctl(arg1, arg2, arg3);
5979
        break;
5980
#endif
5981
#ifdef TARGET_NR_msgget
5982
    case TARGET_NR_msgget:
5983
        ret = get_errno(msgget(arg1, arg2));
5984
        break;
5985
#endif
5986
#ifdef TARGET_NR_msgrcv
5987
    case TARGET_NR_msgrcv:
5988
        ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
5989
        break;
5990
#endif
5991
#ifdef TARGET_NR_msgsnd
5992
    case TARGET_NR_msgsnd:
5993
        ret = do_msgsnd(arg1, arg2, arg3, arg4);
5994
        break;
5995
#endif
5996
#ifdef TARGET_NR_shmget
5997
    case TARGET_NR_shmget:
5998
        ret = get_errno(shmget(arg1, arg2, arg3));
5999
        break;
6000
#endif
6001
#ifdef TARGET_NR_shmctl
6002
    case TARGET_NR_shmctl:
6003
        ret = do_shmctl(arg1, arg2, arg3);
6004
        break;
6005
#endif
6006
#ifdef TARGET_NR_shmat
6007
    case TARGET_NR_shmat:
6008
        ret = do_shmat(arg1, arg2, arg3);
6009
        break;
6010
#endif
6011
#ifdef TARGET_NR_shmdt
6012
    case TARGET_NR_shmdt:
6013
        ret = do_shmdt(arg1);
6014
        break;
6015
#endif
6016
    case TARGET_NR_fsync:
6017
        ret = get_errno(fsync(arg1));
6018
        break;
6019
    case TARGET_NR_clone:
6020
#if defined(TARGET_SH4) || defined(TARGET_ALPHA)
6021
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
6022
#elif defined(TARGET_CRIS)
6023
        ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg4, arg5));
6024
#else
6025
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
6026
#endif
6027
        break;
6028
#ifdef __NR_exit_group
6029
        /* new thread calls */
6030
    case TARGET_NR_exit_group:
6031
#ifdef TARGET_GPROF
6032
        _mcleanup();
6033
#endif
6034
        gdb_exit(cpu_env, arg1);
6035
        ret = get_errno(exit_group(arg1));
6036
        break;
6037
#endif
6038
    case TARGET_NR_setdomainname:
6039
        if (!(p = lock_user_string(arg1)))
6040
            goto efault;
6041
        ret = get_errno(setdomainname(p, arg2));
6042
        unlock_user(p, arg1, 0);
6043
        break;
6044
    case TARGET_NR_uname:
6045
        /* no need to transcode because we use the linux syscall */
6046
        {
6047
            struct new_utsname * buf;
6048

    
6049
            if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
6050
                goto efault;
6051
            ret = get_errno(sys_uname(buf));
6052
            if (!is_error(ret)) {
6053
                /* Overrite the native machine name with whatever is being
6054
                   emulated. */
6055
                strcpy (buf->machine, cpu_to_uname_machine(cpu_env));
6056
                /* Allow the user to override the reported release.  */
6057
                if (qemu_uname_release && *qemu_uname_release)
6058
                  strcpy (buf->release, qemu_uname_release);
6059
            }
6060
            unlock_user_struct(buf, arg1, 1);
6061
        }
6062
        break;
6063
#ifdef TARGET_I386
6064
    case TARGET_NR_modify_ldt:
6065
        ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
6066
        break;
6067
#if !defined(TARGET_X86_64)
6068
    case TARGET_NR_vm86old:
6069
        goto unimplemented;
6070
    case TARGET_NR_vm86:
6071
        ret = do_vm86(cpu_env, arg1, arg2);
6072
        break;
6073
#endif
6074
#endif
6075
    case TARGET_NR_adjtimex:
6076
        goto unimplemented;
6077
#ifdef TARGET_NR_create_module
6078
    case TARGET_NR_create_module:
6079
#endif
6080
    case TARGET_NR_init_module:
6081
    case TARGET_NR_delete_module:
6082
#ifdef TARGET_NR_get_kernel_syms
6083
    case TARGET_NR_get_kernel_syms:
6084
#endif
6085
        goto unimplemented;
6086
    case TARGET_NR_quotactl:
6087
        goto unimplemented;
6088
    case TARGET_NR_getpgid:
6089
        ret = get_errno(getpgid(arg1));
6090
        break;
6091
    case TARGET_NR_fchdir:
6092
        ret = get_errno(fchdir(arg1));
6093
        break;
6094
#ifdef TARGET_NR_bdflush /* not on x86_64 */
6095
    case TARGET_NR_bdflush:
6096
        goto unimplemented;
6097
#endif
6098
#ifdef TARGET_NR_sysfs
6099
    case TARGET_NR_sysfs:
6100
        goto unimplemented;
6101
#endif
6102
    case TARGET_NR_personality:
6103
        ret = get_errno(personality(arg1));
6104
        break;
6105
#ifdef TARGET_NR_afs_syscall
6106
    case TARGET_NR_afs_syscall:
6107
        goto unimplemented;
6108
#endif
6109
#ifdef TARGET_NR__llseek /* Not on alpha */
6110
    case TARGET_NR__llseek:
6111
        {
6112
#if !defined(__NR_llseek)
6113
            ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
6114
            if (put_user_s64(ret, arg4))
6115
                goto efault;
6116
#else
6117
            int64_t res;
6118
            ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
6119
            if (put_user_s64(res, arg4))
6120
                goto efault;
6121
#endif
6122
        }
6123
        break;
6124
#endif
6125
    case TARGET_NR_getdents:
6126
#if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
6127
        {
6128
            struct target_dirent *target_dirp;
6129
            struct linux_dirent *dirp;
6130
            abi_long count = arg3;
6131

    
6132
            dirp = malloc(count);
6133
            if (!dirp) {
6134
                ret = -TARGET_ENOMEM;
6135
                goto fail;
6136
            }
6137

    
6138
            ret = get_errno(sys_getdents(arg1, dirp, count));
6139
            if (!is_error(ret)) {
6140
                struct linux_dirent *de;
6141
                struct target_dirent *tde;
6142
                int len = ret;
6143
                int reclen, treclen;
6144
                int count1, tnamelen;
6145

    
6146
                count1 = 0;
6147
                de = dirp;
6148
                if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
6149
                    goto efault;
6150
                tde = target_dirp;
6151
                while (len > 0) {
6152
                    reclen = de->d_reclen;
6153
                    treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
6154
                    tde->d_reclen = tswap16(treclen);
6155
                    tde->d_ino = tswapl(de->d_ino);
6156
                    tde->d_off = tswapl(de->d_off);
6157
                    tnamelen = treclen - (2 * sizeof(abi_long) + 2);
6158
                    if (tnamelen > 256)
6159
                        tnamelen = 256;
6160
                    /* XXX: may not be correct */
6161
                    pstrcpy(tde->d_name, tnamelen, de->d_name);
6162
                    de = (struct linux_dirent *)((char *)de + reclen);
6163
                    len -= reclen;
6164
                    tde = (struct target_dirent *)((char *)tde + treclen);
6165
                    count1 += treclen;
6166
                }
6167
                ret = count1;
6168
                unlock_user(target_dirp, arg2, ret);
6169
            }
6170
            free(dirp);
6171
        }
6172
#else
6173
        {
6174
            struct linux_dirent *dirp;
6175
            abi_long count = arg3;
6176

    
6177
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
6178
                goto efault;
6179
            ret = get_errno(sys_getdents(arg1, dirp, count));
6180
            if (!is_error(ret)) {
6181
                struct linux_dirent *de;
6182
                int len = ret;
6183
                int reclen;
6184
                de = dirp;
6185
                while (len > 0) {
6186
                    reclen = de->d_reclen;
6187
                    if (reclen > len)
6188
                        break;
6189
                    de->d_reclen = tswap16(reclen);
6190
                    tswapls(&de->d_ino);
6191
                    tswapls(&de->d_off);
6192
                    de = (struct linux_dirent *)((char *)de + reclen);
6193
                    len -= reclen;
6194
                }
6195
            }
6196
            unlock_user(dirp, arg2, ret);
6197
        }
6198
#endif
6199
        break;
6200
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
6201
    case TARGET_NR_getdents64:
6202
        {
6203
            struct linux_dirent64 *dirp;
6204
            abi_long count = arg3;
6205
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
6206
                goto efault;
6207
            ret = get_errno(sys_getdents64(arg1, dirp, count));
6208
            if (!is_error(ret)) {
6209
                struct linux_dirent64 *de;
6210
                int len = ret;
6211
                int reclen;
6212
                de = dirp;
6213
                while (len > 0) {
6214
                    reclen = de->d_reclen;
6215
                    if (reclen > len)
6216
                        break;
6217
                    de->d_reclen = tswap16(reclen);
6218
                    tswap64s((uint64_t *)&de->d_ino);
6219
                    tswap64s((uint64_t *)&de->d_off);
6220
                    de = (struct linux_dirent64 *)((char *)de + reclen);
6221
                    len -= reclen;
6222
                }
6223
            }
6224
            unlock_user(dirp, arg2, ret);
6225
        }
6226
        break;
6227
#endif /* TARGET_NR_getdents64 */
6228
#ifdef TARGET_NR__newselect
6229
    case TARGET_NR__newselect:
6230
        ret = do_select(arg1, arg2, arg3, arg4, arg5);
6231
        break;
6232
#endif
6233
#ifdef TARGET_NR_poll
6234
    case TARGET_NR_poll:
6235
        {
6236
            struct target_pollfd *target_pfd;
6237
            unsigned int nfds = arg2;
6238
            int timeout = arg3;
6239
            struct pollfd *pfd;
6240
            unsigned int i;
6241

    
6242
            target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
6243
            if (!target_pfd)
6244
                goto efault;
6245
            pfd = alloca(sizeof(struct pollfd) * nfds);
6246
            for(i = 0; i < nfds; i++) {
6247
                pfd[i].fd = tswap32(target_pfd[i].fd);
6248
                pfd[i].events = tswap16(target_pfd[i].events);
6249
            }
6250
            ret = get_errno(poll(pfd, nfds, timeout));
6251
            if (!is_error(ret)) {
6252
                for(i = 0; i < nfds; i++) {
6253
                    target_pfd[i].revents = tswap16(pfd[i].revents);
6254
                }
6255
                ret += nfds * (sizeof(struct target_pollfd)
6256
                               - sizeof(struct pollfd));
6257
            }
6258
            unlock_user(target_pfd, arg1, ret);
6259
        }
6260
        break;
6261
#endif
6262
    case TARGET_NR_flock:
6263
        /* NOTE: the flock constant seems to be the same for every
6264
           Linux platform */
6265
        ret = get_errno(flock(arg1, arg2));
6266
        break;
6267
    case TARGET_NR_readv:
6268
        {
6269
            int count = arg3;
6270
            struct iovec *vec;
6271

    
6272
            vec = alloca(count * sizeof(struct iovec));
6273
            if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
6274
                goto efault;
6275
            ret = get_errno(readv(arg1, vec, count));
6276
            unlock_iovec(vec, arg2, count, 1);
6277
        }
6278
        break;
6279
    case TARGET_NR_writev:
6280
        {
6281
            int count = arg3;
6282
            struct iovec *vec;
6283

    
6284
            vec = alloca(count * sizeof(struct iovec));
6285
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
6286
                goto efault;
6287
            ret = get_errno(writev(arg1, vec, count));
6288
            unlock_iovec(vec, arg2, count, 0);
6289
        }
6290
        break;
6291
    case TARGET_NR_getsid:
6292
        ret = get_errno(getsid(arg1));
6293
        break;
6294
#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
6295
    case TARGET_NR_fdatasync:
6296
        ret = get_errno(fdatasync(arg1));
6297
        break;
6298
#endif
6299
    case TARGET_NR__sysctl:
6300
        /* We don't implement this, but ENOTDIR is always a safe
6301
           return value. */
6302
        ret = -TARGET_ENOTDIR;
6303
        break;
6304
    case TARGET_NR_sched_setparam:
6305
        {
6306
            struct sched_param *target_schp;
6307
            struct sched_param schp;
6308

    
6309
            if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
6310
                goto efault;
6311
            schp.sched_priority = tswap32(target_schp->sched_priority);
6312
            unlock_user_struct(target_schp, arg2, 0);
6313
            ret = get_errno(sched_setparam(arg1, &schp));
6314
        }
6315
        break;
6316
    case TARGET_NR_sched_getparam:
6317
        {
6318
            struct sched_param *target_schp;
6319
            struct sched_param schp;
6320
            ret = get_errno(sched_getparam(arg1, &schp));
6321
            if (!is_error(ret)) {
6322
                if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
6323
                    goto efault;
6324
                target_schp->sched_priority = tswap32(schp.sched_priority);
6325
                unlock_user_struct(target_schp, arg2, 1);
6326
            }
6327
        }
6328
        break;
6329
    case TARGET_NR_sched_setscheduler:
6330
        {
6331
            struct sched_param *target_schp;
6332
            struct sched_param schp;
6333
            if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
6334
                goto efault;
6335
            schp.sched_priority = tswap32(target_schp->sched_priority);
6336
            unlock_user_struct(target_schp, arg3, 0);
6337
            ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
6338
        }
6339
        break;
6340
    case TARGET_NR_sched_getscheduler:
6341
        ret = get_errno(sched_getscheduler(arg1));
6342
        break;
6343
    case TARGET_NR_sched_yield:
6344
        ret = get_errno(sched_yield());
6345
        break;
6346
    case TARGET_NR_sched_get_priority_max:
6347
        ret = get_errno(sched_get_priority_max(arg1));
6348
        break;
6349
    case TARGET_NR_sched_get_priority_min:
6350
        ret = get_errno(sched_get_priority_min(arg1));
6351
        break;
6352
    case TARGET_NR_sched_rr_get_interval:
6353
        {
6354
            struct timespec ts;
6355
            ret = get_errno(sched_rr_get_interval(arg1, &ts));
6356
            if (!is_error(ret)) {
6357
                host_to_target_timespec(arg2, &ts);
6358
            }
6359
        }
6360
        break;
6361
    case TARGET_NR_nanosleep:
6362
        {
6363
            struct timespec req, rem;
6364
            target_to_host_timespec(&req, arg1);
6365
            ret = get_errno(nanosleep(&req, &rem));
6366
            if (is_error(ret) && arg2) {
6367
                host_to_target_timespec(arg2, &rem);
6368
            }
6369
        }
6370
        break;
6371
#ifdef TARGET_NR_query_module
6372
    case TARGET_NR_query_module:
6373
        goto unimplemented;
6374
#endif
6375
#ifdef TARGET_NR_nfsservctl
6376
    case TARGET_NR_nfsservctl:
6377
        goto unimplemented;
6378
#endif
6379
    case TARGET_NR_prctl:
6380
        switch (arg1)
6381
            {
6382
            case PR_GET_PDEATHSIG:
6383
                {
6384
                    int deathsig;
6385
                    ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
6386
                    if (!is_error(ret) && arg2
6387
                        && put_user_ual(deathsig, arg2))
6388
                        goto efault;
6389
                }
6390
                break;
6391
            default:
6392
                ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
6393
                break;
6394
            }
6395
        break;
6396
#ifdef TARGET_NR_arch_prctl
6397
    case TARGET_NR_arch_prctl:
6398
#if defined(TARGET_I386) && !defined(TARGET_ABI32)
6399
        ret = do_arch_prctl(cpu_env, arg1, arg2);
6400
        break;
6401
#else
6402
        goto unimplemented;
6403
#endif
6404
#endif
6405
#ifdef TARGET_NR_pread
6406
    case TARGET_NR_pread:
6407
#ifdef TARGET_ARM
6408
        if (((CPUARMState *)cpu_env)->eabi)
6409
            arg4 = arg5;
6410
#endif
6411
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
6412
            goto efault;
6413
        ret = get_errno(pread(arg1, p, arg3, arg4));
6414
        unlock_user(p, arg2, ret);
6415
        break;
6416
    case TARGET_NR_pwrite:
6417
#ifdef TARGET_ARM
6418
        if (((CPUARMState *)cpu_env)->eabi)
6419
            arg4 = arg5;
6420
#endif
6421
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
6422
            goto efault;
6423
        ret = get_errno(pwrite(arg1, p, arg3, arg4));
6424
        unlock_user(p, arg2, 0);
6425
        break;
6426
#endif
6427
#ifdef TARGET_NR_pread64
6428
    case TARGET_NR_pread64:
6429
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
6430
            goto efault;
6431
        ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
6432
        unlock_user(p, arg2, ret);
6433
        break;
6434
    case TARGET_NR_pwrite64:
6435
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
6436
            goto efault;
6437
        ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
6438
        unlock_user(p, arg2, 0);
6439
        break;
6440
#endif
6441
    case TARGET_NR_getcwd:
6442
        if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
6443
            goto efault;
6444
        ret = get_errno(sys_getcwd1(p, arg2));
6445
        unlock_user(p, arg1, ret);
6446
        break;
6447
    case TARGET_NR_capget:
6448
        goto unimplemented;
6449
    case TARGET_NR_capset:
6450
        goto unimplemented;
6451
    case TARGET_NR_sigaltstack:
6452
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
6453
    defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA) || \
6454
    defined(TARGET_M68K)
6455
        ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env));
6456
        break;
6457
#else
6458
        goto unimplemented;
6459
#endif
6460
    case TARGET_NR_sendfile:
6461
        goto unimplemented;
6462
#ifdef TARGET_NR_getpmsg
6463
    case TARGET_NR_getpmsg:
6464
        goto unimplemented;
6465
#endif
6466
#ifdef TARGET_NR_putpmsg
6467
    case TARGET_NR_putpmsg:
6468
        goto unimplemented;
6469
#endif
6470
#ifdef TARGET_NR_vfork
6471
    case TARGET_NR_vfork:
6472
        ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
6473
                        0, 0, 0, 0));
6474
        break;
6475
#endif
6476
#ifdef TARGET_NR_ugetrlimit
6477
    case TARGET_NR_ugetrlimit:
6478
    {
6479
        struct rlimit rlim;
6480
        ret = get_errno(getrlimit(arg1, &rlim));
6481
        if (!is_error(ret)) {
6482
            struct target_rlimit *target_rlim;
6483
            if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
6484
                goto efault;
6485
            target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
6486
            target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
6487
            unlock_user_struct(target_rlim, arg2, 1);
6488
        }
6489
        break;
6490
    }
6491
#endif
6492
#ifdef TARGET_NR_truncate64
6493
    case TARGET_NR_truncate64:
6494
        if (!(p = lock_user_string(arg1)))
6495
            goto efault;
6496
        ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
6497
        unlock_user(p, arg1, 0);
6498
        break;
6499
#endif
6500
#ifdef TARGET_NR_ftruncate64
6501
    case TARGET_NR_ftruncate64:
6502
        ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
6503
        break;
6504
#endif
6505
#ifdef TARGET_NR_stat64
6506
    case TARGET_NR_stat64:
6507
        if (!(p = lock_user_string(arg1)))
6508
            goto efault;
6509
        ret = get_errno(stat(path(p), &st));
6510
        unlock_user(p, arg1, 0);
6511
        if (!is_error(ret))
6512
            ret = host_to_target_stat64(cpu_env, arg2, &st);
6513
        break;
6514
#endif
6515
#ifdef TARGET_NR_lstat64
6516
    case TARGET_NR_lstat64:
6517
        if (!(p = lock_user_string(arg1)))
6518
            goto efault;
6519
        ret = get_errno(lstat(path(p), &st));
6520
        unlock_user(p, arg1, 0);
6521
        if (!is_error(ret))
6522
            ret = host_to_target_stat64(cpu_env, arg2, &st);
6523
        break;
6524
#endif
6525
#ifdef TARGET_NR_fstat64
6526
    case TARGET_NR_fstat64:
6527
        ret = get_errno(fstat(arg1, &st));
6528
        if (!is_error(ret))
6529
            ret = host_to_target_stat64(cpu_env, arg2, &st);
6530
        break;
6531
#endif
6532
#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
6533
        (defined(__NR_fstatat64) || defined(__NR_newfstatat))
6534
#ifdef TARGET_NR_fstatat64
6535
    case TARGET_NR_fstatat64:
6536
#endif
6537
#ifdef TARGET_NR_newfstatat
6538
    case TARGET_NR_newfstatat:
6539
#endif
6540
        if (!(p = lock_user_string(arg2)))
6541
            goto efault;
6542
#ifdef __NR_fstatat64
6543
        ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
6544
#else
6545
        ret = get_errno(sys_newfstatat(arg1, path(p), &st, arg4));
6546
#endif
6547
        if (!is_error(ret))
6548
            ret = host_to_target_stat64(cpu_env, arg3, &st);
6549
        break;
6550
#endif
6551
#ifdef USE_UID16
6552
    case TARGET_NR_lchown:
6553
        if (!(p = lock_user_string(arg1)))
6554
            goto efault;
6555
        ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
6556
        unlock_user(p, arg1, 0);
6557
        break;
6558
    case TARGET_NR_getuid:
6559
        ret = get_errno(high2lowuid(getuid()));
6560
        break;
6561
    case TARGET_NR_getgid:
6562
        ret = get_errno(high2lowgid(getgid()));
6563
        break;
6564
    case TARGET_NR_geteuid:
6565
        ret = get_errno(high2lowuid(geteuid()));
6566
        break;
6567
    case TARGET_NR_getegid:
6568
        ret = get_errno(high2lowgid(getegid()));
6569
        break;
6570
    case TARGET_NR_setreuid:
6571
        ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
6572
        break;
6573
    case TARGET_NR_setregid:
6574
        ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
6575
        break;
6576
    case TARGET_NR_getgroups:
6577
        {
6578
            int gidsetsize = arg1;
6579
            uint16_t *target_grouplist;
6580
            gid_t *grouplist;
6581
            int i;
6582

    
6583
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6584
            ret = get_errno(getgroups(gidsetsize, grouplist));
6585
            if (gidsetsize == 0)
6586
                break;
6587
            if (!is_error(ret)) {
6588
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
6589
                if (!target_grouplist)
6590
                    goto efault;
6591
                for(i = 0;i < ret; i++)
6592
                    target_grouplist[i] = tswap16(grouplist[i]);
6593
                unlock_user(target_grouplist, arg2, gidsetsize * 2);
6594
            }
6595
        }
6596
        break;
6597
    case TARGET_NR_setgroups:
6598
        {
6599
            int gidsetsize = arg1;
6600
            uint16_t *target_grouplist;
6601
            gid_t *grouplist;
6602
            int i;
6603

    
6604
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6605
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
6606
            if (!target_grouplist) {
6607
                ret = -TARGET_EFAULT;
6608
                goto fail;
6609
            }
6610
            for(i = 0;i < gidsetsize; i++)
6611
                grouplist[i] = tswap16(target_grouplist[i]);
6612
            unlock_user(target_grouplist, arg2, 0);
6613
            ret = get_errno(setgroups(gidsetsize, grouplist));
6614
        }
6615
        break;
6616
    case TARGET_NR_fchown:
6617
        ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
6618
        break;
6619
#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
6620
    case TARGET_NR_fchownat:
6621
        if (!(p = lock_user_string(arg2))) 
6622
            goto efault;
6623
        ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
6624
        unlock_user(p, arg2, 0);
6625
        break;
6626
#endif
6627
#ifdef TARGET_NR_setresuid
6628
    case TARGET_NR_setresuid:
6629
        ret = get_errno(setresuid(low2highuid(arg1),
6630
                                  low2highuid(arg2),
6631
                                  low2highuid(arg3)));
6632
        break;
6633
#endif
6634
#ifdef TARGET_NR_getresuid
6635
    case TARGET_NR_getresuid:
6636
        {
6637
            uid_t ruid, euid, suid;
6638
            ret = get_errno(getresuid(&ruid, &euid, &suid));
6639
            if (!is_error(ret)) {
6640
                if (put_user_u16(high2lowuid(ruid), arg1)
6641
                    || put_user_u16(high2lowuid(euid), arg2)
6642
                    || put_user_u16(high2lowuid(suid), arg3))
6643
                    goto efault;
6644
            }
6645
        }
6646
        break;
6647
#endif
6648
#ifdef TARGET_NR_getresgid
6649
    case TARGET_NR_setresgid:
6650
        ret = get_errno(setresgid(low2highgid(arg1),
6651
                                  low2highgid(arg2),
6652
                                  low2highgid(arg3)));
6653
        break;
6654
#endif
6655
#ifdef TARGET_NR_getresgid
6656
    case TARGET_NR_getresgid:
6657
        {
6658
            gid_t rgid, egid, sgid;
6659
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
6660
            if (!is_error(ret)) {
6661
                if (put_user_u16(high2lowgid(rgid), arg1)
6662
                    || put_user_u16(high2lowgid(egid), arg2)
6663
                    || put_user_u16(high2lowgid(sgid), arg3))
6664
                    goto efault;
6665
            }
6666
        }
6667
        break;
6668
#endif
6669
    case TARGET_NR_chown:
6670
        if (!(p = lock_user_string(arg1)))
6671
            goto efault;
6672
        ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
6673
        unlock_user(p, arg1, 0);
6674
        break;
6675
    case TARGET_NR_setuid:
6676
        ret = get_errno(setuid(low2highuid(arg1)));
6677
        break;
6678
    case TARGET_NR_setgid:
6679
        ret = get_errno(setgid(low2highgid(arg1)));
6680
        break;
6681
    case TARGET_NR_setfsuid:
6682
        ret = get_errno(setfsuid(arg1));
6683
        break;
6684
    case TARGET_NR_setfsgid:
6685
        ret = get_errno(setfsgid(arg1));
6686
        break;
6687
#endif /* USE_UID16 */
6688

    
6689
#ifdef TARGET_NR_lchown32
6690
    case TARGET_NR_lchown32:
6691
        if (!(p = lock_user_string(arg1)))
6692
            goto efault;
6693
        ret = get_errno(lchown(p, arg2, arg3));
6694
        unlock_user(p, arg1, 0);
6695
        break;
6696
#endif
6697
#ifdef TARGET_NR_getuid32
6698
    case TARGET_NR_getuid32:
6699
        ret = get_errno(getuid());
6700
        break;
6701
#endif
6702

    
6703
#if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
6704
   /* Alpha specific */
6705
    case TARGET_NR_getxuid:
6706
         {
6707
            uid_t euid;
6708
            euid=geteuid();
6709
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
6710
         }
6711
        ret = get_errno(getuid());
6712
        break;
6713
#endif
6714
#if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
6715
   /* Alpha specific */
6716
    case TARGET_NR_getxgid:
6717
         {
6718
            uid_t egid;
6719
            egid=getegid();
6720
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
6721
         }
6722
        ret = get_errno(getgid());
6723
        break;
6724
#endif
6725
#if defined(TARGET_NR_osf_getsysinfo) && defined(TARGET_ALPHA)
6726
    /* Alpha specific */
6727
    case TARGET_NR_osf_getsysinfo:
6728
        ret = -TARGET_EOPNOTSUPP;
6729
        switch (arg1) {
6730
          case TARGET_GSI_IEEE_FP_CONTROL:
6731
            {
6732
                uint64_t swcr, fpcr = cpu_alpha_load_fpcr (cpu_env);
6733

    
6734
                /* Copied from linux ieee_fpcr_to_swcr.  */
6735
                swcr = (fpcr >> 35) & SWCR_STATUS_MASK;
6736
                swcr |= (fpcr >> 36) & SWCR_MAP_DMZ;
6737
                swcr |= (~fpcr >> 48) & (SWCR_TRAP_ENABLE_INV
6738
                                        | SWCR_TRAP_ENABLE_DZE
6739
                                        | SWCR_TRAP_ENABLE_OVF);
6740
                swcr |= (~fpcr >> 57) & (SWCR_TRAP_ENABLE_UNF
6741
                                        | SWCR_TRAP_ENABLE_INE);
6742
                swcr |= (fpcr >> 47) & SWCR_MAP_UMZ;
6743
                swcr |= (~fpcr >> 41) & SWCR_TRAP_ENABLE_DNO;
6744

    
6745
                if (put_user_u64 (swcr, arg2))
6746
                        goto efault;
6747
                ret = 0;
6748
            }
6749
            break;
6750

    
6751
          /* case GSI_IEEE_STATE_AT_SIGNAL:
6752
             -- Not implemented in linux kernel.
6753
             case GSI_UACPROC:
6754
             -- Retrieves current unaligned access state; not much used.
6755
             case GSI_PROC_TYPE:
6756
             -- Retrieves implver information; surely not used.
6757
             case GSI_GET_HWRPB:
6758
             -- Grabs a copy of the HWRPB; surely not used.
6759
          */
6760
        }
6761
        break;
6762
#endif
6763
#if defined(TARGET_NR_osf_setsysinfo) && defined(TARGET_ALPHA)
6764
    /* Alpha specific */
6765
    case TARGET_NR_osf_setsysinfo:
6766
        ret = -TARGET_EOPNOTSUPP;
6767
        switch (arg1) {
6768
          case TARGET_SSI_IEEE_FP_CONTROL:
6769
          case TARGET_SSI_IEEE_RAISE_EXCEPTION:
6770
            {
6771
                uint64_t swcr, fpcr, orig_fpcr;
6772

    
6773
                if (get_user_u64 (swcr, arg2))
6774
                    goto efault;
6775
                orig_fpcr = cpu_alpha_load_fpcr (cpu_env);
6776
                fpcr = orig_fpcr & FPCR_DYN_MASK;
6777

    
6778
                /* Copied from linux ieee_swcr_to_fpcr.  */
6779
                fpcr |= (swcr & SWCR_STATUS_MASK) << 35;
6780
                fpcr |= (swcr & SWCR_MAP_DMZ) << 36;
6781
                fpcr |= (~swcr & (SWCR_TRAP_ENABLE_INV
6782
                                  | SWCR_TRAP_ENABLE_DZE
6783
                                  | SWCR_TRAP_ENABLE_OVF)) << 48;
6784
                fpcr |= (~swcr & (SWCR_TRAP_ENABLE_UNF
6785
                                  | SWCR_TRAP_ENABLE_INE)) << 57;
6786
                fpcr |= (swcr & SWCR_MAP_UMZ ? FPCR_UNDZ | FPCR_UNFD : 0);
6787
                fpcr |= (~swcr & SWCR_TRAP_ENABLE_DNO) << 41;
6788

    
6789
                cpu_alpha_store_fpcr (cpu_env, fpcr);
6790
                ret = 0;
6791

    
6792
                if (arg1 == TARGET_SSI_IEEE_RAISE_EXCEPTION) {
6793
                    /* Old exceptions are not signaled.  */
6794
                    fpcr &= ~(orig_fpcr & FPCR_STATUS_MASK);
6795

    
6796
                    /* If any exceptions set by this call, and are unmasked,
6797
                       send a signal.  */
6798
                    /* ??? FIXME */
6799
                }
6800
            }
6801
            break;
6802

    
6803
          /* case SSI_NVPAIRS:
6804
             -- Used with SSIN_UACPROC to enable unaligned accesses.
6805
             case SSI_IEEE_STATE_AT_SIGNAL:
6806
             case SSI_IEEE_IGNORE_STATE_AT_SIGNAL:
6807
             -- Not implemented in linux kernel
6808
          */
6809
        }
6810
        break;
6811
#endif
6812
#ifdef TARGET_NR_osf_sigprocmask
6813
    /* Alpha specific.  */
6814
    case TARGET_NR_osf_sigprocmask:
6815
        {
6816
            abi_ulong mask;
6817
            int how = arg1;
6818
            sigset_t set, oldset;
6819

    
6820
            switch(arg1) {
6821
            case TARGET_SIG_BLOCK:
6822
                how = SIG_BLOCK;
6823
                break;
6824
            case TARGET_SIG_UNBLOCK:
6825
                how = SIG_UNBLOCK;
6826
                break;
6827
            case TARGET_SIG_SETMASK:
6828
                how = SIG_SETMASK;
6829
                break;
6830
            default:
6831
                ret = -TARGET_EINVAL;
6832
                goto fail;
6833
            }
6834
            mask = arg2;
6835
            target_to_host_old_sigset(&set, &mask);
6836
            sigprocmask(arg1, &set, &oldset);
6837
            host_to_target_old_sigset(&mask, &oldset);
6838
            ret = mask;
6839
        }
6840
        break;
6841
#endif
6842

    
6843
#ifdef TARGET_NR_getgid32
6844
    case TARGET_NR_getgid32:
6845
        ret = get_errno(getgid());
6846
        break;
6847
#endif
6848
#ifdef TARGET_NR_geteuid32
6849
    case TARGET_NR_geteuid32:
6850
        ret = get_errno(geteuid());
6851
        break;
6852
#endif
6853
#ifdef TARGET_NR_getegid32
6854
    case TARGET_NR_getegid32:
6855
        ret = get_errno(getegid());
6856
        break;
6857
#endif
6858
#ifdef TARGET_NR_setreuid32
6859
    case TARGET_NR_setreuid32:
6860
        ret = get_errno(setreuid(arg1, arg2));
6861
        break;
6862
#endif
6863
#ifdef TARGET_NR_setregid32
6864
    case TARGET_NR_setregid32:
6865
        ret = get_errno(setregid(arg1, arg2));
6866
        break;
6867
#endif
6868
#ifdef TARGET_NR_getgroups32
6869
    case TARGET_NR_getgroups32:
6870
        {
6871
            int gidsetsize = arg1;
6872
            uint32_t *target_grouplist;
6873
            gid_t *grouplist;
6874
            int i;
6875

    
6876
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6877
            ret = get_errno(getgroups(gidsetsize, grouplist));
6878
            if (gidsetsize == 0)
6879
                break;
6880
            if (!is_error(ret)) {
6881
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
6882
                if (!target_grouplist) {
6883
                    ret = -TARGET_EFAULT;
6884
                    goto fail;
6885
                }
6886
                for(i = 0;i < ret; i++)
6887
                    target_grouplist[i] = tswap32(grouplist[i]);
6888
                unlock_user(target_grouplist, arg2, gidsetsize * 4);
6889
            }
6890
        }
6891
        break;
6892
#endif
6893
#ifdef TARGET_NR_setgroups32
6894
    case TARGET_NR_setgroups32:
6895
        {
6896
            int gidsetsize = arg1;
6897
            uint32_t *target_grouplist;
6898
            gid_t *grouplist;
6899
            int i;
6900

    
6901
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6902
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
6903
            if (!target_grouplist) {
6904
                ret = -TARGET_EFAULT;
6905
                goto fail;
6906
            }
6907
            for(i = 0;i < gidsetsize; i++)
6908
                grouplist[i] = tswap32(target_grouplist[i]);
6909
            unlock_user(target_grouplist, arg2, 0);
6910
            ret = get_errno(setgroups(gidsetsize, grouplist));
6911
        }
6912
        break;
6913
#endif
6914
#ifdef TARGET_NR_fchown32
6915
    case TARGET_NR_fchown32:
6916
        ret = get_errno(fchown(arg1, arg2, arg3));
6917
        break;
6918
#endif
6919
#ifdef TARGET_NR_setresuid32
6920
    case TARGET_NR_setresuid32:
6921
        ret = get_errno(setresuid(arg1, arg2, arg3));
6922
        break;
6923
#endif
6924
#ifdef TARGET_NR_getresuid32
6925
    case TARGET_NR_getresuid32:
6926
        {
6927
            uid_t ruid, euid, suid;
6928
            ret = get_errno(getresuid(&ruid, &euid, &suid));
6929
            if (!is_error(ret)) {
6930
                if (put_user_u32(ruid, arg1)
6931
                    || put_user_u32(euid, arg2)
6932
                    || put_user_u32(suid, arg3))
6933
                    goto efault;
6934
            }
6935
        }
6936
        break;
6937
#endif
6938
#ifdef TARGET_NR_setresgid32
6939
    case TARGET_NR_setresgid32:
6940
        ret = get_errno(setresgid(arg1, arg2, arg3));
6941
        break;
6942
#endif
6943
#ifdef TARGET_NR_getresgid32
6944
    case TARGET_NR_getresgid32:
6945
        {
6946
            gid_t rgid, egid, sgid;
6947
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
6948
            if (!is_error(ret)) {
6949
                if (put_user_u32(rgid, arg1)
6950
                    || put_user_u32(egid, arg2)
6951
                    || put_user_u32(sgid, arg3))
6952
                    goto efault;
6953
            }
6954
        }
6955
        break;
6956
#endif
6957
#ifdef TARGET_NR_chown32
6958
    case TARGET_NR_chown32:
6959
        if (!(p = lock_user_string(arg1)))
6960
            goto efault;
6961
        ret = get_errno(chown(p, arg2, arg3));
6962
        unlock_user(p, arg1, 0);
6963
        break;
6964
#endif
6965
#ifdef TARGET_NR_setuid32
6966
    case TARGET_NR_setuid32:
6967
        ret = get_errno(setuid(arg1));
6968
        break;
6969
#endif
6970
#ifdef TARGET_NR_setgid32
6971
    case TARGET_NR_setgid32:
6972
        ret = get_errno(setgid(arg1));
6973
        break;
6974
#endif
6975
#ifdef TARGET_NR_setfsuid32
6976
    case TARGET_NR_setfsuid32:
6977
        ret = get_errno(setfsuid(arg1));
6978
        break;
6979
#endif
6980
#ifdef TARGET_NR_setfsgid32
6981
    case TARGET_NR_setfsgid32:
6982
        ret = get_errno(setfsgid(arg1));
6983
        break;
6984
#endif
6985

    
6986
    case TARGET_NR_pivot_root:
6987
        goto unimplemented;
6988
#ifdef TARGET_NR_mincore
6989
    case TARGET_NR_mincore:
6990
        {
6991
            void *a;
6992
            ret = -TARGET_EFAULT;
6993
            if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
6994
                goto efault;
6995
            if (!(p = lock_user_string(arg3)))
6996
                goto mincore_fail;
6997
            ret = get_errno(mincore(a, arg2, p));
6998
            unlock_user(p, arg3, ret);
6999
            mincore_fail:
7000
            unlock_user(a, arg1, 0);
7001
        }
7002
        break;
7003
#endif
7004
#ifdef TARGET_NR_arm_fadvise64_64
7005
    case TARGET_NR_arm_fadvise64_64:
7006
        {
7007
                /*
7008
                 * arm_fadvise64_64 looks like fadvise64_64 but
7009
                 * with different argument order
7010
                 */
7011
                abi_long temp;
7012
                temp = arg3;
7013
                arg3 = arg4;
7014
                arg4 = temp;
7015
        }
7016
#endif
7017
#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64) || defined(TARGET_NR_fadvise64)
7018
#ifdef TARGET_NR_fadvise64_64
7019
    case TARGET_NR_fadvise64_64:
7020
#endif
7021
#ifdef TARGET_NR_fadvise64
7022
    case TARGET_NR_fadvise64:
7023
#endif
7024
#ifdef TARGET_S390X
7025
        switch (arg4) {
7026
        case 4: arg4 = POSIX_FADV_NOREUSE + 1; break; /* make sure it's an invalid value */
7027
        case 5: arg4 = POSIX_FADV_NOREUSE + 2; break; /* ditto */
7028
        case 6: arg4 = POSIX_FADV_DONTNEED; break;
7029
        case 7: arg4 = POSIX_FADV_NOREUSE; break;
7030
        default: break;
7031
        }
7032
#endif
7033
        ret = -posix_fadvise(arg1, arg2, arg3, arg4);
7034
        break;
7035
#endif
7036
#ifdef TARGET_NR_madvise
7037
    case TARGET_NR_madvise:
7038
        /* A straight passthrough may not be safe because qemu sometimes
7039
           turns private flie-backed mappings into anonymous mappings.
7040
           This will break MADV_DONTNEED.
7041
           This is a hint, so ignoring and returning success is ok.  */
7042
        ret = get_errno(0);
7043
        break;
7044
#endif
7045
#if TARGET_ABI_BITS == 32
7046
    case TARGET_NR_fcntl64:
7047
    {
7048
        int cmd;
7049
        struct flock64 fl;
7050
        struct target_flock64 *target_fl;
7051
#ifdef TARGET_ARM
7052
        struct target_eabi_flock64 *target_efl;
7053
#endif
7054

    
7055
        cmd = target_to_host_fcntl_cmd(arg2);
7056
        if (cmd == -TARGET_EINVAL)
7057
                return cmd;
7058

    
7059
        switch(arg2) {
7060
        case TARGET_F_GETLK64:
7061
#ifdef TARGET_ARM
7062
            if (((CPUARMState *)cpu_env)->eabi) {
7063
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
7064
                    goto efault;
7065
                fl.l_type = tswap16(target_efl->l_type);
7066
                fl.l_whence = tswap16(target_efl->l_whence);
7067
                fl.l_start = tswap64(target_efl->l_start);
7068
                fl.l_len = tswap64(target_efl->l_len);
7069
                fl.l_pid = tswap32(target_efl->l_pid);
7070
                unlock_user_struct(target_efl, arg3, 0);
7071
            } else
7072
#endif
7073
            {
7074
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
7075
                    goto efault;
7076
                fl.l_type = tswap16(target_fl->l_type);
7077
                fl.l_whence = tswap16(target_fl->l_whence);
7078
                fl.l_start = tswap64(target_fl->l_start);
7079
                fl.l_len = tswap64(target_fl->l_len);
7080
                fl.l_pid = tswap32(target_fl->l_pid);
7081
                unlock_user_struct(target_fl, arg3, 0);
7082
            }
7083
            ret = get_errno(fcntl(arg1, cmd, &fl));
7084
            if (ret == 0) {
7085
#ifdef TARGET_ARM
7086
                if (((CPUARMState *)cpu_env)->eabi) {
7087
                    if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) 
7088
                        goto efault;
7089
                    target_efl->l_type = tswap16(fl.l_type);
7090
                    target_efl->l_whence = tswap16(fl.l_whence);
7091
                    target_efl->l_start = tswap64(fl.l_start);
7092
                    target_efl->l_len = tswap64(fl.l_len);
7093
                    target_efl->l_pid = tswap32(fl.l_pid);
7094
                    unlock_user_struct(target_efl, arg3, 1);
7095
                } else
7096
#endif
7097
                {
7098
                    if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) 
7099
                        goto efault;
7100
                    target_fl->l_type = tswap16(fl.l_type);
7101
                    target_fl->l_whence = tswap16(fl.l_whence);
7102
                    target_fl->l_start = tswap64(fl.l_start);
7103
                    target_fl->l_len = tswap64(fl.l_len);
7104
                    target_fl->l_pid = tswap32(fl.l_pid);
7105
                    unlock_user_struct(target_fl, arg3, 1);
7106
                }
7107
            }
7108
            break;
7109

    
7110
        case TARGET_F_SETLK64:
7111
        case TARGET_F_SETLKW64:
7112
#ifdef TARGET_ARM
7113
            if (((CPUARMState *)cpu_env)->eabi) {
7114
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
7115
                    goto efault;
7116
                fl.l_type = tswap16(target_efl->l_type);
7117
                fl.l_whence = tswap16(target_efl->l_whence);
7118
                fl.l_start = tswap64(target_efl->l_start);
7119
                fl.l_len = tswap64(target_efl->l_len);
7120
                fl.l_pid = tswap32(target_efl->l_pid);
7121
                unlock_user_struct(target_efl, arg3, 0);
7122
            } else
7123
#endif
7124
            {
7125
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
7126
                    goto efault;
7127
                fl.l_type = tswap16(target_fl->l_type);
7128
                fl.l_whence = tswap16(target_fl->l_whence);
7129
                fl.l_start = tswap64(target_fl->l_start);
7130
                fl.l_len = tswap64(target_fl->l_len);
7131
                fl.l_pid = tswap32(target_fl->l_pid);
7132
                unlock_user_struct(target_fl, arg3, 0);
7133
            }
7134
            ret = get_errno(fcntl(arg1, cmd, &fl));
7135
            break;
7136
        default:
7137
            ret = do_fcntl(arg1, arg2, arg3);
7138
            break;
7139
        }
7140
        break;
7141
    }
7142
#endif
7143
#ifdef TARGET_NR_cacheflush
7144
    case TARGET_NR_cacheflush:
7145
        /* self-modifying code is handled automatically, so nothing needed */
7146
        ret = 0;
7147
        break;
7148
#endif
7149
#ifdef TARGET_NR_security
7150
    case TARGET_NR_security:
7151
        goto unimplemented;
7152
#endif
7153
#ifdef TARGET_NR_getpagesize
7154
    case TARGET_NR_getpagesize:
7155
        ret = TARGET_PAGE_SIZE;
7156
        break;
7157
#endif
7158
    case TARGET_NR_gettid:
7159
        ret = get_errno(gettid());
7160
        break;
7161
#ifdef TARGET_NR_readahead
7162
    case TARGET_NR_readahead:
7163
#if TARGET_ABI_BITS == 32
7164
#ifdef TARGET_ARM
7165
        if (((CPUARMState *)cpu_env)->eabi)
7166
        {
7167
            arg2 = arg3;
7168
            arg3 = arg4;
7169
            arg4 = arg5;
7170
        }
7171
#endif
7172
        ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
7173
#else
7174
        ret = get_errno(readahead(arg1, arg2, arg3));
7175
#endif
7176
        break;
7177
#endif
7178
#ifdef TARGET_NR_setxattr
7179
    case TARGET_NR_setxattr:
7180
    case TARGET_NR_lsetxattr:
7181
    case TARGET_NR_fsetxattr:
7182
    case TARGET_NR_getxattr:
7183
    case TARGET_NR_lgetxattr:
7184
    case TARGET_NR_fgetxattr:
7185
    case TARGET_NR_listxattr:
7186
    case TARGET_NR_llistxattr:
7187
    case TARGET_NR_flistxattr:
7188
    case TARGET_NR_removexattr:
7189
    case TARGET_NR_lremovexattr:
7190
    case TARGET_NR_fremovexattr:
7191
        ret = -TARGET_EOPNOTSUPP;
7192
        break;
7193
#endif
7194
#ifdef TARGET_NR_set_thread_area
7195
    case TARGET_NR_set_thread_area:
7196
#if defined(TARGET_MIPS)
7197
      ((CPUMIPSState *) cpu_env)->tls_value = arg1;
7198
      ret = 0;
7199
      break;
7200
#elif defined(TARGET_CRIS)
7201
      if (arg1 & 0xff)
7202
          ret = -TARGET_EINVAL;
7203
      else {
7204
          ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
7205
          ret = 0;
7206
      }
7207
      break;
7208
#elif defined(TARGET_I386) && defined(TARGET_ABI32)
7209
      ret = do_set_thread_area(cpu_env, arg1);
7210
      break;
7211
#else
7212
      goto unimplemented_nowarn;
7213
#endif
7214
#endif
7215
#ifdef TARGET_NR_get_thread_area
7216
    case TARGET_NR_get_thread_area:
7217
#if defined(TARGET_I386) && defined(TARGET_ABI32)
7218
        ret = do_get_thread_area(cpu_env, arg1);
7219
#else
7220
        goto unimplemented_nowarn;
7221
#endif
7222
#endif
7223
#ifdef TARGET_NR_getdomainname
7224
    case TARGET_NR_getdomainname:
7225
        goto unimplemented_nowarn;
7226
#endif
7227

    
7228
#ifdef TARGET_NR_clock_gettime
7229
    case TARGET_NR_clock_gettime:
7230
    {
7231
        struct timespec ts;
7232
        ret = get_errno(clock_gettime(arg1, &ts));
7233
        if (!is_error(ret)) {
7234
            host_to_target_timespec(arg2, &ts);
7235
        }
7236
        break;
7237
    }
7238
#endif
7239
#ifdef TARGET_NR_clock_getres
7240
    case TARGET_NR_clock_getres:
7241
    {
7242
        struct timespec ts;
7243
        ret = get_errno(clock_getres(arg1, &ts));
7244
        if (!is_error(ret)) {
7245
            host_to_target_timespec(arg2, &ts);
7246
        }
7247
        break;
7248
    }
7249
#endif
7250
#ifdef TARGET_NR_clock_nanosleep
7251
    case TARGET_NR_clock_nanosleep:
7252
    {
7253
        struct timespec ts;
7254
        target_to_host_timespec(&ts, arg3);
7255
        ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
7256
        if (arg4)
7257
            host_to_target_timespec(arg4, &ts);
7258
        break;
7259
    }
7260
#endif
7261

    
7262
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
7263
    case TARGET_NR_set_tid_address:
7264
        ret = get_errno(set_tid_address((int *)g2h(arg1)));
7265
        break;
7266
#endif
7267

    
7268
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
7269
    case TARGET_NR_tkill:
7270
        ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
7271
        break;
7272
#endif
7273

    
7274
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
7275
    case TARGET_NR_tgkill:
7276
        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
7277
                        target_to_host_signal(arg3)));
7278
        break;
7279
#endif
7280

    
7281
#ifdef TARGET_NR_set_robust_list
7282
    case TARGET_NR_set_robust_list:
7283
        goto unimplemented_nowarn;
7284
#endif
7285

    
7286
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
7287
    case TARGET_NR_utimensat:
7288
        {
7289
            struct timespec *tsp, ts[2];
7290
            if (!arg3) {
7291
                tsp = NULL;
7292
            } else {
7293
                target_to_host_timespec(ts, arg3);
7294
                target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
7295
                tsp = ts;
7296
            }
7297
            if (!arg2)
7298
                ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4));
7299
            else {
7300
                if (!(p = lock_user_string(arg2))) {
7301
                    ret = -TARGET_EFAULT;
7302
                    goto fail;
7303
                }
7304
                ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4));
7305
                unlock_user(p, arg2, 0);
7306
            }
7307
        }
7308
        break;
7309
#endif
7310
#if defined(CONFIG_USE_NPTL)
7311
    case TARGET_NR_futex:
7312
        ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
7313
        break;
7314
#endif
7315
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
7316
    case TARGET_NR_inotify_init:
7317
        ret = get_errno(sys_inotify_init());
7318
        break;
7319
#endif
7320
#ifdef CONFIG_INOTIFY1
7321
#if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
7322
    case TARGET_NR_inotify_init1:
7323
        ret = get_errno(sys_inotify_init1(arg1));
7324
        break;
7325
#endif
7326
#endif
7327
#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
7328
    case TARGET_NR_inotify_add_watch:
7329
        p = lock_user_string(arg2);
7330
        ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
7331
        unlock_user(p, arg2, 0);
7332
        break;
7333
#endif
7334
#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
7335
    case TARGET_NR_inotify_rm_watch:
7336
        ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
7337
        break;
7338
#endif
7339

    
7340
#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
7341
    case TARGET_NR_mq_open:
7342
        {
7343
            struct mq_attr posix_mq_attr;
7344

    
7345
            p = lock_user_string(arg1 - 1);
7346
            if (arg4 != 0)
7347
                copy_from_user_mq_attr (&posix_mq_attr, arg4);
7348
            ret = get_errno(mq_open(p, arg2, arg3, &posix_mq_attr));
7349
            unlock_user (p, arg1, 0);
7350
        }
7351
        break;
7352

    
7353
    case TARGET_NR_mq_unlink:
7354
        p = lock_user_string(arg1 - 1);
7355
        ret = get_errno(mq_unlink(p));
7356
        unlock_user (p, arg1, 0);
7357
        break;
7358

    
7359
    case TARGET_NR_mq_timedsend:
7360
        {
7361
            struct timespec ts;
7362

    
7363
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
7364
            if (arg5 != 0) {
7365
                target_to_host_timespec(&ts, arg5);
7366
                ret = get_errno(mq_timedsend(arg1, p, arg3, arg4, &ts));
7367
                host_to_target_timespec(arg5, &ts);
7368
            }
7369
            else
7370
                ret = get_errno(mq_send(arg1, p, arg3, arg4));
7371
            unlock_user (p, arg2, arg3);
7372
        }
7373
        break;
7374

    
7375
    case TARGET_NR_mq_timedreceive:
7376
        {
7377
            struct timespec ts;
7378
            unsigned int prio;
7379

    
7380
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
7381
            if (arg5 != 0) {
7382
                target_to_host_timespec(&ts, arg5);
7383
                ret = get_errno(mq_timedreceive(arg1, p, arg3, &prio, &ts));
7384
                host_to_target_timespec(arg5, &ts);
7385
            }
7386
            else
7387
                ret = get_errno(mq_receive(arg1, p, arg3, &prio));
7388
            unlock_user (p, arg2, arg3);
7389
            if (arg4 != 0)
7390
                put_user_u32(prio, arg4);
7391
        }
7392
        break;
7393

    
7394
    /* Not implemented for now... */
7395
/*     case TARGET_NR_mq_notify: */
7396
/*         break; */
7397

    
7398
    case TARGET_NR_mq_getsetattr:
7399
        {
7400
            struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
7401
            ret = 0;
7402
            if (arg3 != 0) {
7403
                ret = mq_getattr(arg1, &posix_mq_attr_out);
7404
                copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
7405
            }
7406
            if (arg2 != 0) {
7407
                copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
7408
                ret |= mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_attr_out);
7409
            }
7410

    
7411
        }
7412
        break;
7413
#endif
7414

    
7415
#ifdef CONFIG_SPLICE
7416
#ifdef TARGET_NR_tee
7417
    case TARGET_NR_tee:
7418
        {
7419
            ret = get_errno(tee(arg1,arg2,arg3,arg4));
7420
        }
7421
        break;
7422
#endif
7423
#ifdef TARGET_NR_splice
7424
    case TARGET_NR_splice:
7425
        {
7426
            loff_t loff_in, loff_out;
7427
            loff_t *ploff_in = NULL, *ploff_out = NULL;
7428
            if(arg2) {
7429
                get_user_u64(loff_in, arg2);
7430
                ploff_in = &loff_in;
7431
            }
7432
            if(arg4) {
7433
                get_user_u64(loff_out, arg2);
7434
                ploff_out = &loff_out;
7435
            }
7436
            ret = get_errno(splice(arg1, ploff_in, arg3, ploff_out, arg5, arg6));
7437
        }
7438
        break;
7439
#endif
7440
#ifdef TARGET_NR_vmsplice
7441
        case TARGET_NR_vmsplice:
7442
        {
7443
            int count = arg3;
7444
            struct iovec *vec;
7445

    
7446
            vec = alloca(count * sizeof(struct iovec));
7447
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
7448
                goto efault;
7449
            ret = get_errno(vmsplice(arg1, vec, count, arg4));
7450
            unlock_iovec(vec, arg2, count, 0);
7451
        }
7452
        break;
7453
#endif
7454
#endif /* CONFIG_SPLICE */
7455
#ifdef CONFIG_EVENTFD
7456
#if defined(TARGET_NR_eventfd)
7457
    case TARGET_NR_eventfd:
7458
        ret = get_errno(eventfd(arg1, 0));
7459
        break;
7460
#endif
7461
#if defined(TARGET_NR_eventfd2)
7462
    case TARGET_NR_eventfd2:
7463
        ret = get_errno(eventfd(arg1, arg2));
7464
        break;
7465
#endif
7466
#endif /* CONFIG_EVENTFD  */
7467
#if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate)
7468
    case TARGET_NR_fallocate:
7469
        ret = get_errno(fallocate(arg1, arg2, arg3, arg4));
7470
        break;
7471
#endif
7472
#if defined(CONFIG_SYNC_FILE_RANGE)
7473
#if defined(TARGET_NR_sync_file_range)
7474
    case TARGET_NR_sync_file_range:
7475
#if TARGET_ABI_BITS == 32
7476
        ret = get_errno(sync_file_range(arg1, target_offset64(arg2, arg3),
7477
                                        target_offset64(arg4, arg5), arg6));
7478
#else
7479
        ret = get_errno(sync_file_range(arg1, arg2, arg3, arg4));
7480
#endif
7481
        break;
7482
#endif
7483
#if defined(TARGET_NR_sync_file_range2)
7484
    case TARGET_NR_sync_file_range2:
7485
        /* This is like sync_file_range but the arguments are reordered */
7486
#if TARGET_ABI_BITS == 32
7487
        ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
7488
                                        target_offset64(arg5, arg6), arg2));
7489
#else
7490
        ret = get_errno(sync_file_range(arg1, arg3, arg4, arg2));
7491
#endif
7492
        break;
7493
#endif
7494
#endif
7495
    default:
7496
    unimplemented:
7497
        gemu_log("qemu: Unsupported syscall: %d\n", num);
7498
#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
7499
    unimplemented_nowarn:
7500
#endif
7501
        ret = -TARGET_ENOSYS;
7502
        break;
7503
    }
7504
fail:
7505
#ifdef DEBUG
7506
    gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
7507
#endif
7508
    if(do_strace)
7509
        print_syscall_ret(num, ret);
7510
    return ret;
7511
efault:
7512
    ret = -TARGET_EFAULT;
7513
    goto fail;
7514
}