Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ 0b959cf5

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

    
85
#define termios host_termios
86
#define winsize host_winsize
87
#define termio host_termio
88
#define sgttyb host_sgttyb /* same as target */
89
#define tchars host_tchars /* same as target */
90
#define ltchars host_ltchars /* same as target */
91

    
92
#include <linux/termios.h>
93
#include <linux/unistd.h>
94
#include <linux/utsname.h>
95
#include <linux/cdrom.h>
96
#include <linux/hdreg.h>
97
#include <linux/soundcard.h>
98
#include <linux/kd.h>
99
#include <linux/mtio.h>
100
#include <linux/fs.h>
101
#if defined(CONFIG_FIEMAP)
102
#include <linux/fiemap.h>
103
#endif
104
#include <linux/fb.h>
105
#include <linux/vt.h>
106
#include <linux/dm-ioctl.h>
107
#include <linux/reboot.h>
108
#include <linux/route.h>
109
#include <linux/filter.h>
110
#include "linux_loop.h"
111
#include "cpu-uname.h"
112

    
113
#include "qemu.h"
114

    
115
#define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
116
    CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
117

    
118
//#define DEBUG
119

    
120
//#include <linux/msdos_fs.h>
121
#define        VFAT_IOCTL_READDIR_BOTH                _IOR('r', 1, struct linux_dirent [2])
122
#define        VFAT_IOCTL_READDIR_SHORT        _IOR('r', 2, struct linux_dirent [2])
123

    
124

    
125
#undef _syscall0
126
#undef _syscall1
127
#undef _syscall2
128
#undef _syscall3
129
#undef _syscall4
130
#undef _syscall5
131
#undef _syscall6
132

    
133
#define _syscall0(type,name)                \
134
static type name (void)                        \
135
{                                        \
136
        return syscall(__NR_##name);        \
137
}
138

    
139
#define _syscall1(type,name,type1,arg1)                \
140
static type name (type1 arg1)                        \
141
{                                                \
142
        return syscall(__NR_##name, arg1);        \
143
}
144

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

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

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

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

    
170

    
171
#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,        \
172
                  type5,arg5,type6,arg6)                                        \
173
static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,        \
174
                  type6 arg6)                                                        \
175
{                                                                                \
176
        return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6);        \
177
}
178

    
179

    
180
#define __NR_sys_uname __NR_uname
181
#define __NR_sys_getcwd1 __NR_getcwd
182
#define __NR_sys_getdents __NR_getdents
183
#define __NR_sys_getdents64 __NR_getdents64
184
#define __NR_sys_getpriority __NR_getpriority
185
#define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
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_futex __NR_futex
190
#define __NR_sys_inotify_init __NR_inotify_init
191
#define __NR_sys_inotify_add_watch __NR_inotify_add_watch
192
#define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
193

    
194
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) || \
195
    defined(__s390x__)
196
#define __NR__llseek __NR_lseek
197
#endif
198

    
199
#ifdef __NR_gettid
200
_syscall0(int, gettid)
201
#else
202
/* This is a replacement for the host gettid() and must return a host
203
   errno. */
204
static int gettid(void) {
205
    return -ENOSYS;
206
}
207
#endif
208
#ifdef __NR_getdents
209
_syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
210
#endif
211
#if !defined(__NR_getdents) || \
212
    (defined(TARGET_NR_getdents64) && defined(__NR_getdents64))
213
_syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
214
#endif
215
#if defined(TARGET_NR__llseek) && defined(__NR_llseek)
216
_syscall5(int, _llseek,  uint,  fd, ulong, hi, ulong, lo,
217
          loff_t *, res, uint, wh);
218
#endif
219
_syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
220
_syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
221
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
222
_syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
223
#endif
224
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
225
_syscall2(int,sys_tkill,int,tid,int,sig)
226
#endif
227
#ifdef __NR_exit_group
228
_syscall1(int,exit_group,int,error_code)
229
#endif
230
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
231
_syscall1(int,set_tid_address,int *,tidptr)
232
#endif
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
#define __NR_sys_sched_getaffinity __NR_sched_getaffinity
238
_syscall3(int, sys_sched_getaffinity, pid_t, pid, unsigned int, len,
239
          unsigned long *, user_mask_ptr);
240
#define __NR_sys_sched_setaffinity __NR_sched_setaffinity
241
_syscall3(int, sys_sched_setaffinity, pid_t, pid, unsigned int, len,
242
          unsigned long *, user_mask_ptr);
243
_syscall4(int, reboot, int, magic1, int, magic2, unsigned int, cmd,
244
          void *, arg);
245

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

    
279
#define COPY_UTSNAME_FIELD(dest, src) \
280
  do { \
281
      /* __NEW_UTS_LEN doesn't include terminating null */ \
282
      (void) strncpy((dest), (src), __NEW_UTS_LEN); \
283
      (dest)[__NEW_UTS_LEN] = '\0'; \
284
  } while (0)
285

    
286
static int sys_uname(struct new_utsname *buf)
287
{
288
  struct utsname uts_buf;
289

    
290
  if (uname(&uts_buf) < 0)
291
      return (-1);
292

    
293
  /*
294
   * Just in case these have some differences, we
295
   * translate utsname to new_utsname (which is the
296
   * struct linux kernel uses).
297
   */
298

    
299
  memset(buf, 0, sizeof(*buf));
300
  COPY_UTSNAME_FIELD(buf->sysname, uts_buf.sysname);
301
  COPY_UTSNAME_FIELD(buf->nodename, uts_buf.nodename);
302
  COPY_UTSNAME_FIELD(buf->release, uts_buf.release);
303
  COPY_UTSNAME_FIELD(buf->version, uts_buf.version);
304
  COPY_UTSNAME_FIELD(buf->machine, uts_buf.machine);
305
#ifdef _GNU_SOURCE
306
  COPY_UTSNAME_FIELD(buf->domainname, uts_buf.domainname);
307
#endif
308
  return (0);
309

    
310
#undef COPY_UTSNAME_FIELD
311
}
312

    
313
static int sys_getcwd1(char *buf, size_t size)
314
{
315
  if (getcwd(buf, size) == NULL) {
316
      /* getcwd() sets errno */
317
      return (-1);
318
  }
319
  return strlen(buf)+1;
320
}
321

    
322
#ifdef TARGET_NR_openat
323
static int sys_openat(int dirfd, const char *pathname, int flags, mode_t mode)
324
{
325
  /*
326
   * open(2) has extra parameter 'mode' when called with
327
   * flag O_CREAT.
328
   */
329
  if ((flags & O_CREAT) != 0) {
330
      return (openat(dirfd, pathname, flags, mode));
331
  }
332
  return (openat(dirfd, pathname, flags));
333
}
334
#endif
335

    
336
#ifdef TARGET_NR_utimensat
337
#ifdef CONFIG_UTIMENSAT
338
static int sys_utimensat(int dirfd, const char *pathname,
339
    const struct timespec times[2], int flags)
340
{
341
    if (pathname == NULL)
342
        return futimens(dirfd, times);
343
    else
344
        return utimensat(dirfd, pathname, times, flags);
345
}
346
#elif defined(__NR_utimensat)
347
#define __NR_sys_utimensat __NR_utimensat
348
_syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
349
          const struct timespec *,tsp,int,flags)
350
#else
351
static int sys_utimensat(int dirfd, const char *pathname,
352
                         const struct timespec times[2], int flags)
353
{
354
    errno = ENOSYS;
355
    return -1;
356
}
357
#endif
358
#endif /* TARGET_NR_utimensat */
359

    
360
#ifdef CONFIG_INOTIFY
361
#include <sys/inotify.h>
362

    
363
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
364
static int sys_inotify_init(void)
365
{
366
  return (inotify_init());
367
}
368
#endif
369
#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
370
static int sys_inotify_add_watch(int fd,const char *pathname, int32_t mask)
371
{
372
  return (inotify_add_watch(fd, pathname, mask));
373
}
374
#endif
375
#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
376
static int sys_inotify_rm_watch(int fd, int32_t wd)
377
{
378
  return (inotify_rm_watch(fd, wd));
379
}
380
#endif
381
#ifdef CONFIG_INOTIFY1
382
#if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
383
static int sys_inotify_init1(int flags)
384
{
385
  return (inotify_init1(flags));
386
}
387
#endif
388
#endif
389
#else
390
/* Userspace can usually survive runtime without inotify */
391
#undef TARGET_NR_inotify_init
392
#undef TARGET_NR_inotify_init1
393
#undef TARGET_NR_inotify_add_watch
394
#undef TARGET_NR_inotify_rm_watch
395
#endif /* CONFIG_INOTIFY  */
396

    
397
#if defined(TARGET_NR_ppoll)
398
#ifndef __NR_ppoll
399
# define __NR_ppoll -1
400
#endif
401
#define __NR_sys_ppoll __NR_ppoll
402
_syscall5(int, sys_ppoll, struct pollfd *, fds, nfds_t, nfds,
403
          struct timespec *, timeout, const __sigset_t *, sigmask,
404
          size_t, sigsetsize)
405
#endif
406

    
407
#if defined(TARGET_NR_pselect6)
408
#ifndef __NR_pselect6
409
# define __NR_pselect6 -1
410
#endif
411
#define __NR_sys_pselect6 __NR_pselect6
412
_syscall6(int, sys_pselect6, int, nfds, fd_set *, readfds, fd_set *, writefds,
413
          fd_set *, exceptfds, struct timespec *, timeout, void *, sig);
414
#endif
415

    
416
#if defined(TARGET_NR_prlimit64)
417
#ifndef __NR_prlimit64
418
# define __NR_prlimit64 -1
419
#endif
420
#define __NR_sys_prlimit64 __NR_prlimit64
421
/* The glibc rlimit structure may not be that used by the underlying syscall */
422
struct host_rlimit64 {
423
    uint64_t rlim_cur;
424
    uint64_t rlim_max;
425
};
426
_syscall4(int, sys_prlimit64, pid_t, pid, int, resource,
427
          const struct host_rlimit64 *, new_limit,
428
          struct host_rlimit64 *, old_limit)
429
#endif
430

    
431
/* ARM EABI and MIPS expect 64bit types aligned even on pairs or registers */
432
#ifdef TARGET_ARM
433
static inline int regpairs_aligned(void *cpu_env) {
434
    return ((((CPUARMState *)cpu_env)->eabi) == 1) ;
435
}
436
#elif defined(TARGET_MIPS)
437
static inline int regpairs_aligned(void *cpu_env) { return 1; }
438
#elif defined(TARGET_PPC) && !defined(TARGET_PPC64)
439
/* SysV AVI for PPC32 expects 64bit parameters to be passed on odd/even pairs
440
 * of registers which translates to the same as ARM/MIPS, because we start with
441
 * r3 as arg1 */
442
static inline int regpairs_aligned(void *cpu_env) { return 1; }
443
#else
444
static inline int regpairs_aligned(void *cpu_env) { return 0; }
445
#endif
446

    
447
#define ERRNO_TABLE_SIZE 1200
448

    
449
/* target_to_host_errno_table[] is initialized from
450
 * host_to_target_errno_table[] in syscall_init(). */
451
static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
452
};
453

    
454
/*
455
 * This list is the union of errno values overridden in asm-<arch>/errno.h
456
 * minus the errnos that are not actually generic to all archs.
457
 */
458
static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
459
    [EIDRM]                = TARGET_EIDRM,
460
    [ECHRNG]                = TARGET_ECHRNG,
461
    [EL2NSYNC]                = TARGET_EL2NSYNC,
462
    [EL3HLT]                = TARGET_EL3HLT,
463
    [EL3RST]                = TARGET_EL3RST,
464
    [ELNRNG]                = TARGET_ELNRNG,
465
    [EUNATCH]                = TARGET_EUNATCH,
466
    [ENOCSI]                = TARGET_ENOCSI,
467
    [EL2HLT]                = TARGET_EL2HLT,
468
    [EDEADLK]                = TARGET_EDEADLK,
469
    [ENOLCK]                = TARGET_ENOLCK,
470
    [EBADE]                = TARGET_EBADE,
471
    [EBADR]                = TARGET_EBADR,
472
    [EXFULL]                = TARGET_EXFULL,
473
    [ENOANO]                = TARGET_ENOANO,
474
    [EBADRQC]                = TARGET_EBADRQC,
475
    [EBADSLT]                = TARGET_EBADSLT,
476
    [EBFONT]                = TARGET_EBFONT,
477
    [ENOSTR]                = TARGET_ENOSTR,
478
    [ENODATA]                = TARGET_ENODATA,
479
    [ETIME]                = TARGET_ETIME,
480
    [ENOSR]                = TARGET_ENOSR,
481
    [ENONET]                = TARGET_ENONET,
482
    [ENOPKG]                = TARGET_ENOPKG,
483
    [EREMOTE]                = TARGET_EREMOTE,
484
    [ENOLINK]                = TARGET_ENOLINK,
485
    [EADV]                = TARGET_EADV,
486
    [ESRMNT]                = TARGET_ESRMNT,
487
    [ECOMM]                = TARGET_ECOMM,
488
    [EPROTO]                = TARGET_EPROTO,
489
    [EDOTDOT]                = TARGET_EDOTDOT,
490
    [EMULTIHOP]                = TARGET_EMULTIHOP,
491
    [EBADMSG]                = TARGET_EBADMSG,
492
    [ENAMETOOLONG]        = TARGET_ENAMETOOLONG,
493
    [EOVERFLOW]                = TARGET_EOVERFLOW,
494
    [ENOTUNIQ]                = TARGET_ENOTUNIQ,
495
    [EBADFD]                = TARGET_EBADFD,
496
    [EREMCHG]                = TARGET_EREMCHG,
497
    [ELIBACC]                = TARGET_ELIBACC,
498
    [ELIBBAD]                = TARGET_ELIBBAD,
499
    [ELIBSCN]                = TARGET_ELIBSCN,
500
    [ELIBMAX]                = TARGET_ELIBMAX,
501
    [ELIBEXEC]                = TARGET_ELIBEXEC,
502
    [EILSEQ]                = TARGET_EILSEQ,
503
    [ENOSYS]                = TARGET_ENOSYS,
504
    [ELOOP]                = TARGET_ELOOP,
505
    [ERESTART]                = TARGET_ERESTART,
506
    [ESTRPIPE]                = TARGET_ESTRPIPE,
507
    [ENOTEMPTY]                = TARGET_ENOTEMPTY,
508
    [EUSERS]                = TARGET_EUSERS,
509
    [ENOTSOCK]                = TARGET_ENOTSOCK,
510
    [EDESTADDRREQ]        = TARGET_EDESTADDRREQ,
511
    [EMSGSIZE]                = TARGET_EMSGSIZE,
512
    [EPROTOTYPE]        = TARGET_EPROTOTYPE,
513
    [ENOPROTOOPT]        = TARGET_ENOPROTOOPT,
514
    [EPROTONOSUPPORT]        = TARGET_EPROTONOSUPPORT,
515
    [ESOCKTNOSUPPORT]        = TARGET_ESOCKTNOSUPPORT,
516
    [EOPNOTSUPP]        = TARGET_EOPNOTSUPP,
517
    [EPFNOSUPPORT]        = TARGET_EPFNOSUPPORT,
518
    [EAFNOSUPPORT]        = TARGET_EAFNOSUPPORT,
519
    [EADDRINUSE]        = TARGET_EADDRINUSE,
520
    [EADDRNOTAVAIL]        = TARGET_EADDRNOTAVAIL,
521
    [ENETDOWN]                = TARGET_ENETDOWN,
522
    [ENETUNREACH]        = TARGET_ENETUNREACH,
523
    [ENETRESET]                = TARGET_ENETRESET,
524
    [ECONNABORTED]        = TARGET_ECONNABORTED,
525
    [ECONNRESET]        = TARGET_ECONNRESET,
526
    [ENOBUFS]                = TARGET_ENOBUFS,
527
    [EISCONN]                = TARGET_EISCONN,
528
    [ENOTCONN]                = TARGET_ENOTCONN,
529
    [EUCLEAN]                = TARGET_EUCLEAN,
530
    [ENOTNAM]                = TARGET_ENOTNAM,
531
    [ENAVAIL]                = TARGET_ENAVAIL,
532
    [EISNAM]                = TARGET_EISNAM,
533
    [EREMOTEIO]                = TARGET_EREMOTEIO,
534
    [ESHUTDOWN]                = TARGET_ESHUTDOWN,
535
    [ETOOMANYREFS]        = TARGET_ETOOMANYREFS,
536
    [ETIMEDOUT]                = TARGET_ETIMEDOUT,
537
    [ECONNREFUSED]        = TARGET_ECONNREFUSED,
538
    [EHOSTDOWN]                = TARGET_EHOSTDOWN,
539
    [EHOSTUNREACH]        = TARGET_EHOSTUNREACH,
540
    [EALREADY]                = TARGET_EALREADY,
541
    [EINPROGRESS]        = TARGET_EINPROGRESS,
542
    [ESTALE]                = TARGET_ESTALE,
543
    [ECANCELED]                = TARGET_ECANCELED,
544
    [ENOMEDIUM]                = TARGET_ENOMEDIUM,
545
    [EMEDIUMTYPE]        = TARGET_EMEDIUMTYPE,
546
#ifdef ENOKEY
547
    [ENOKEY]                = TARGET_ENOKEY,
548
#endif
549
#ifdef EKEYEXPIRED
550
    [EKEYEXPIRED]        = TARGET_EKEYEXPIRED,
551
#endif
552
#ifdef EKEYREVOKED
553
    [EKEYREVOKED]        = TARGET_EKEYREVOKED,
554
#endif
555
#ifdef EKEYREJECTED
556
    [EKEYREJECTED]        = TARGET_EKEYREJECTED,
557
#endif
558
#ifdef EOWNERDEAD
559
    [EOWNERDEAD]        = TARGET_EOWNERDEAD,
560
#endif
561
#ifdef ENOTRECOVERABLE
562
    [ENOTRECOVERABLE]        = TARGET_ENOTRECOVERABLE,
563
#endif
564
};
565

    
566
static inline int host_to_target_errno(int err)
567
{
568
    if(host_to_target_errno_table[err])
569
        return host_to_target_errno_table[err];
570
    return err;
571
}
572

    
573
static inline int target_to_host_errno(int err)
574
{
575
    if (target_to_host_errno_table[err])
576
        return target_to_host_errno_table[err];
577
    return err;
578
}
579

    
580
static inline abi_long get_errno(abi_long ret)
581
{
582
    if (ret == -1)
583
        return -host_to_target_errno(errno);
584
    else
585
        return ret;
586
}
587

    
588
static inline int is_error(abi_long ret)
589
{
590
    return (abi_ulong)ret >= (abi_ulong)(-4096);
591
}
592

    
593
char *target_strerror(int err)
594
{
595
    if ((err >= ERRNO_TABLE_SIZE) || (err < 0)) {
596
        return NULL;
597
    }
598
    return strerror(target_to_host_errno(err));
599
}
600

    
601
static abi_ulong target_brk;
602
static abi_ulong target_original_brk;
603
static abi_ulong brk_page;
604

    
605
void target_set_brk(abi_ulong new_brk)
606
{
607
    target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
608
    brk_page = HOST_PAGE_ALIGN(target_brk);
609
}
610

    
611
//#define DEBUGF_BRK(message, args...) do { fprintf(stderr, (message), ## args); } while (0)
612
#define DEBUGF_BRK(message, args...)
613

    
614
/* do_brk() must return target values and target errnos. */
615
abi_long do_brk(abi_ulong new_brk)
616
{
617
    abi_long mapped_addr;
618
    int        new_alloc_size;
619

    
620
    DEBUGF_BRK("do_brk(" TARGET_ABI_FMT_lx ") -> ", new_brk);
621

    
622
    if (!new_brk) {
623
        DEBUGF_BRK(TARGET_ABI_FMT_lx " (!new_brk)\n", target_brk);
624
        return target_brk;
625
    }
626
    if (new_brk < target_original_brk) {
627
        DEBUGF_BRK(TARGET_ABI_FMT_lx " (new_brk < target_original_brk)\n",
628
                   target_brk);
629
        return target_brk;
630
    }
631

    
632
    /* If the new brk is less than the highest page reserved to the
633
     * target heap allocation, set it and we're almost done...  */
634
    if (new_brk <= brk_page) {
635
        /* Heap contents are initialized to zero, as for anonymous
636
         * mapped pages.  */
637
        if (new_brk > target_brk) {
638
            memset(g2h(target_brk), 0, new_brk - target_brk);
639
        }
640
        target_brk = new_brk;
641
        DEBUGF_BRK(TARGET_ABI_FMT_lx " (new_brk <= brk_page)\n", target_brk);
642
            return target_brk;
643
    }
644

    
645
    /* We need to allocate more memory after the brk... Note that
646
     * we don't use MAP_FIXED because that will map over the top of
647
     * any existing mapping (like the one with the host libc or qemu
648
     * itself); instead we treat "mapped but at wrong address" as
649
     * a failure and unmap again.
650
     */
651
    new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page);
652
    mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
653
                                        PROT_READ|PROT_WRITE,
654
                                        MAP_ANON|MAP_PRIVATE, 0, 0));
655

    
656
    if (mapped_addr == brk_page) {
657
        /* Heap contents are initialized to zero, as for anonymous
658
         * mapped pages.  Technically the new pages are already
659
         * initialized to zero since they *are* anonymous mapped
660
         * pages, however we have to take care with the contents that
661
         * come from the remaining part of the previous page: it may
662
         * contains garbage data due to a previous heap usage (grown
663
         * then shrunken).  */
664
        memset(g2h(target_brk), 0, brk_page - target_brk);
665

    
666
        target_brk = new_brk;
667
        brk_page = HOST_PAGE_ALIGN(target_brk);
668
        DEBUGF_BRK(TARGET_ABI_FMT_lx " (mapped_addr == brk_page)\n",
669
            target_brk);
670
        return target_brk;
671
    } else if (mapped_addr != -1) {
672
        /* Mapped but at wrong address, meaning there wasn't actually
673
         * enough space for this brk.
674
         */
675
        target_munmap(mapped_addr, new_alloc_size);
676
        mapped_addr = -1;
677
        DEBUGF_BRK(TARGET_ABI_FMT_lx " (mapped_addr != -1)\n", target_brk);
678
    }
679
    else {
680
        DEBUGF_BRK(TARGET_ABI_FMT_lx " (otherwise)\n", target_brk);
681
    }
682

    
683
#if defined(TARGET_ALPHA)
684
    /* We (partially) emulate OSF/1 on Alpha, which requires we
685
       return a proper errno, not an unchanged brk value.  */
686
    return -TARGET_ENOMEM;
687
#endif
688
    /* For everything else, return the previous break. */
689
    return target_brk;
690
}
691

    
692
static inline abi_long copy_from_user_fdset(fd_set *fds,
693
                                            abi_ulong target_fds_addr,
694
                                            int n)
695
{
696
    int i, nw, j, k;
697
    abi_ulong b, *target_fds;
698

    
699
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
700
    if (!(target_fds = lock_user(VERIFY_READ,
701
                                 target_fds_addr,
702
                                 sizeof(abi_ulong) * nw,
703
                                 1)))
704
        return -TARGET_EFAULT;
705

    
706
    FD_ZERO(fds);
707
    k = 0;
708
    for (i = 0; i < nw; i++) {
709
        /* grab the abi_ulong */
710
        __get_user(b, &target_fds[i]);
711
        for (j = 0; j < TARGET_ABI_BITS; j++) {
712
            /* check the bit inside the abi_ulong */
713
            if ((b >> j) & 1)
714
                FD_SET(k, fds);
715
            k++;
716
        }
717
    }
718

    
719
    unlock_user(target_fds, target_fds_addr, 0);
720

    
721
    return 0;
722
}
723

    
724
static inline abi_ulong copy_from_user_fdset_ptr(fd_set *fds, fd_set **fds_ptr,
725
                                                 abi_ulong target_fds_addr,
726
                                                 int n)
727
{
728
    if (target_fds_addr) {
729
        if (copy_from_user_fdset(fds, target_fds_addr, n))
730
            return -TARGET_EFAULT;
731
        *fds_ptr = fds;
732
    } else {
733
        *fds_ptr = NULL;
734
    }
735
    return 0;
736
}
737

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

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

    
753
    k = 0;
754
    for (i = 0; i < nw; i++) {
755
        v = 0;
756
        for (j = 0; j < TARGET_ABI_BITS; j++) {
757
            v |= ((abi_ulong)(FD_ISSET(k, fds) != 0) << j);
758
            k++;
759
        }
760
        __put_user(v, &target_fds[i]);
761
    }
762

    
763
    unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
764

    
765
    return 0;
766
}
767

    
768
#if defined(__alpha__)
769
#define HOST_HZ 1024
770
#else
771
#define HOST_HZ 100
772
#endif
773

    
774
static inline abi_long host_to_target_clock_t(long ticks)
775
{
776
#if HOST_HZ == TARGET_HZ
777
    return ticks;
778
#else
779
    return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
780
#endif
781
}
782

    
783
static inline abi_long host_to_target_rusage(abi_ulong target_addr,
784
                                             const struct rusage *rusage)
785
{
786
    struct target_rusage *target_rusage;
787

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

    
810
    return 0;
811
}
812

    
813
static inline rlim_t target_to_host_rlim(abi_ulong target_rlim)
814
{
815
    abi_ulong target_rlim_swap;
816
    rlim_t result;
817
    
818
    target_rlim_swap = tswapal(target_rlim);
819
    if (target_rlim_swap == TARGET_RLIM_INFINITY)
820
        return RLIM_INFINITY;
821

    
822
    result = target_rlim_swap;
823
    if (target_rlim_swap != (rlim_t)result)
824
        return RLIM_INFINITY;
825
    
826
    return result;
827
}
828

    
829
static inline abi_ulong host_to_target_rlim(rlim_t rlim)
830
{
831
    abi_ulong target_rlim_swap;
832
    abi_ulong result;
833
    
834
    if (rlim == RLIM_INFINITY || rlim != (abi_long)rlim)
835
        target_rlim_swap = TARGET_RLIM_INFINITY;
836
    else
837
        target_rlim_swap = rlim;
838
    result = tswapal(target_rlim_swap);
839
    
840
    return result;
841
}
842

    
843
static inline int target_to_host_resource(int code)
844
{
845
    switch (code) {
846
    case TARGET_RLIMIT_AS:
847
        return RLIMIT_AS;
848
    case TARGET_RLIMIT_CORE:
849
        return RLIMIT_CORE;
850
    case TARGET_RLIMIT_CPU:
851
        return RLIMIT_CPU;
852
    case TARGET_RLIMIT_DATA:
853
        return RLIMIT_DATA;
854
    case TARGET_RLIMIT_FSIZE:
855
        return RLIMIT_FSIZE;
856
    case TARGET_RLIMIT_LOCKS:
857
        return RLIMIT_LOCKS;
858
    case TARGET_RLIMIT_MEMLOCK:
859
        return RLIMIT_MEMLOCK;
860
    case TARGET_RLIMIT_MSGQUEUE:
861
        return RLIMIT_MSGQUEUE;
862
    case TARGET_RLIMIT_NICE:
863
        return RLIMIT_NICE;
864
    case TARGET_RLIMIT_NOFILE:
865
        return RLIMIT_NOFILE;
866
    case TARGET_RLIMIT_NPROC:
867
        return RLIMIT_NPROC;
868
    case TARGET_RLIMIT_RSS:
869
        return RLIMIT_RSS;
870
    case TARGET_RLIMIT_RTPRIO:
871
        return RLIMIT_RTPRIO;
872
    case TARGET_RLIMIT_SIGPENDING:
873
        return RLIMIT_SIGPENDING;
874
    case TARGET_RLIMIT_STACK:
875
        return RLIMIT_STACK;
876
    default:
877
        return code;
878
    }
879
}
880

    
881
static inline abi_long copy_from_user_timeval(struct timeval *tv,
882
                                              abi_ulong target_tv_addr)
883
{
884
    struct target_timeval *target_tv;
885

    
886
    if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
887
        return -TARGET_EFAULT;
888

    
889
    __get_user(tv->tv_sec, &target_tv->tv_sec);
890
    __get_user(tv->tv_usec, &target_tv->tv_usec);
891

    
892
    unlock_user_struct(target_tv, target_tv_addr, 0);
893

    
894
    return 0;
895
}
896

    
897
static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
898
                                            const struct timeval *tv)
899
{
900
    struct target_timeval *target_tv;
901

    
902
    if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
903
        return -TARGET_EFAULT;
904

    
905
    __put_user(tv->tv_sec, &target_tv->tv_sec);
906
    __put_user(tv->tv_usec, &target_tv->tv_usec);
907

    
908
    unlock_user_struct(target_tv, target_tv_addr, 1);
909

    
910
    return 0;
911
}
912

    
913
#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
914
#include <mqueue.h>
915

    
916
static inline abi_long copy_from_user_mq_attr(struct mq_attr *attr,
917
                                              abi_ulong target_mq_attr_addr)
918
{
919
    struct target_mq_attr *target_mq_attr;
920

    
921
    if (!lock_user_struct(VERIFY_READ, target_mq_attr,
922
                          target_mq_attr_addr, 1))
923
        return -TARGET_EFAULT;
924

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

    
930
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0);
931

    
932
    return 0;
933
}
934

    
935
static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr,
936
                                            const struct mq_attr *attr)
937
{
938
    struct target_mq_attr *target_mq_attr;
939

    
940
    if (!lock_user_struct(VERIFY_WRITE, target_mq_attr,
941
                          target_mq_attr_addr, 0))
942
        return -TARGET_EFAULT;
943

    
944
    __put_user(attr->mq_flags, &target_mq_attr->mq_flags);
945
    __put_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
946
    __put_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
947
    __put_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
948

    
949
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1);
950

    
951
    return 0;
952
}
953
#endif
954

    
955
#if defined(TARGET_NR_select) || defined(TARGET_NR__newselect)
956
/* do_select() must return target values and target errnos. */
957
static abi_long do_select(int n,
958
                          abi_ulong rfd_addr, abi_ulong wfd_addr,
959
                          abi_ulong efd_addr, abi_ulong target_tv_addr)
960
{
961
    fd_set rfds, wfds, efds;
962
    fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
963
    struct timeval tv, *tv_ptr;
964
    abi_long ret;
965

    
966
    ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
967
    if (ret) {
968
        return ret;
969
    }
970
    ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
971
    if (ret) {
972
        return ret;
973
    }
974
    ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
975
    if (ret) {
976
        return ret;
977
    }
978

    
979
    if (target_tv_addr) {
980
        if (copy_from_user_timeval(&tv, target_tv_addr))
981
            return -TARGET_EFAULT;
982
        tv_ptr = &tv;
983
    } else {
984
        tv_ptr = NULL;
985
    }
986

    
987
    ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
988

    
989
    if (!is_error(ret)) {
990
        if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
991
            return -TARGET_EFAULT;
992
        if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
993
            return -TARGET_EFAULT;
994
        if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
995
            return -TARGET_EFAULT;
996

    
997
        if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
998
            return -TARGET_EFAULT;
999
    }
1000

    
1001
    return ret;
1002
}
1003
#endif
1004

    
1005
static abi_long do_pipe2(int host_pipe[], int flags)
1006
{
1007
#ifdef CONFIG_PIPE2
1008
    return pipe2(host_pipe, flags);
1009
#else
1010
    return -ENOSYS;
1011
#endif
1012
}
1013

    
1014
static abi_long do_pipe(void *cpu_env, abi_ulong pipedes,
1015
                        int flags, int is_pipe2)
1016
{
1017
    int host_pipe[2];
1018
    abi_long ret;
1019
    ret = flags ? do_pipe2(host_pipe, flags) : pipe(host_pipe);
1020

    
1021
    if (is_error(ret))
1022
        return get_errno(ret);
1023

    
1024
    /* Several targets have special calling conventions for the original
1025
       pipe syscall, but didn't replicate this into the pipe2 syscall.  */
1026
    if (!is_pipe2) {
1027
#if defined(TARGET_ALPHA)
1028
        ((CPUAlphaState *)cpu_env)->ir[IR_A4] = host_pipe[1];
1029
        return host_pipe[0];
1030
#elif defined(TARGET_MIPS)
1031
        ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1];
1032
        return host_pipe[0];
1033
#elif defined(TARGET_SH4)
1034
        ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
1035
        return host_pipe[0];
1036
#elif defined(TARGET_SPARC)
1037
        ((CPUSPARCState*)cpu_env)->regwptr[1] = host_pipe[1];
1038
        return host_pipe[0];
1039
#endif
1040
    }
1041

    
1042
    if (put_user_s32(host_pipe[0], pipedes)
1043
        || put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0])))
1044
        return -TARGET_EFAULT;
1045
    return get_errno(ret);
1046
}
1047

    
1048
static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn,
1049
                                              abi_ulong target_addr,
1050
                                              socklen_t len)
1051
{
1052
    struct target_ip_mreqn *target_smreqn;
1053

    
1054
    target_smreqn = lock_user(VERIFY_READ, target_addr, len, 1);
1055
    if (!target_smreqn)
1056
        return -TARGET_EFAULT;
1057
    mreqn->imr_multiaddr.s_addr = target_smreqn->imr_multiaddr.s_addr;
1058
    mreqn->imr_address.s_addr = target_smreqn->imr_address.s_addr;
1059
    if (len == sizeof(struct target_ip_mreqn))
1060
        mreqn->imr_ifindex = tswapal(target_smreqn->imr_ifindex);
1061
    unlock_user(target_smreqn, target_addr, 0);
1062

    
1063
    return 0;
1064
}
1065

    
1066
static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
1067
                                               abi_ulong target_addr,
1068
                                               socklen_t len)
1069
{
1070
    const socklen_t unix_maxlen = sizeof (struct sockaddr_un);
1071
    sa_family_t sa_family;
1072
    struct target_sockaddr *target_saddr;
1073

    
1074
    target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
1075
    if (!target_saddr)
1076
        return -TARGET_EFAULT;
1077

    
1078
    sa_family = tswap16(target_saddr->sa_family);
1079

    
1080
    /* Oops. The caller might send a incomplete sun_path; sun_path
1081
     * must be terminated by \0 (see the manual page), but
1082
     * unfortunately it is quite common to specify sockaddr_un
1083
     * length as "strlen(x->sun_path)" while it should be
1084
     * "strlen(...) + 1". We'll fix that here if needed.
1085
     * Linux kernel has a similar feature.
1086
     */
1087

    
1088
    if (sa_family == AF_UNIX) {
1089
        if (len < unix_maxlen && len > 0) {
1090
            char *cp = (char*)target_saddr;
1091

    
1092
            if ( cp[len-1] && !cp[len] )
1093
                len++;
1094
        }
1095
        if (len > unix_maxlen)
1096
            len = unix_maxlen;
1097
    }
1098

    
1099
    memcpy(addr, target_saddr, len);
1100
    addr->sa_family = sa_family;
1101
    unlock_user(target_saddr, target_addr, 0);
1102

    
1103
    return 0;
1104
}
1105

    
1106
static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
1107
                                               struct sockaddr *addr,
1108
                                               socklen_t len)
1109
{
1110
    struct target_sockaddr *target_saddr;
1111

    
1112
    target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
1113
    if (!target_saddr)
1114
        return -TARGET_EFAULT;
1115
    memcpy(target_saddr, addr, len);
1116
    target_saddr->sa_family = tswap16(addr->sa_family);
1117
    unlock_user(target_saddr, target_addr, len);
1118

    
1119
    return 0;
1120
}
1121

    
1122
static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
1123
                                           struct target_msghdr *target_msgh)
1124
{
1125
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1126
    abi_long msg_controllen;
1127
    abi_ulong target_cmsg_addr;
1128
    struct target_cmsghdr *target_cmsg;
1129
    socklen_t space = 0;
1130
    
1131
    msg_controllen = tswapal(target_msgh->msg_controllen);
1132
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1133
        goto the_end;
1134
    target_cmsg_addr = tswapal(target_msgh->msg_control);
1135
    target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
1136
    if (!target_cmsg)
1137
        return -TARGET_EFAULT;
1138

    
1139
    while (cmsg && target_cmsg) {
1140
        void *data = CMSG_DATA(cmsg);
1141
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
1142

    
1143
        int len = tswapal(target_cmsg->cmsg_len)
1144
                  - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
1145

    
1146
        space += CMSG_SPACE(len);
1147
        if (space > msgh->msg_controllen) {
1148
            space -= CMSG_SPACE(len);
1149
            gemu_log("Host cmsg overflow\n");
1150
            break;
1151
        }
1152

    
1153
        if (tswap32(target_cmsg->cmsg_level) == TARGET_SOL_SOCKET) {
1154
            cmsg->cmsg_level = SOL_SOCKET;
1155
        } else {
1156
            cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
1157
        }
1158
        cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
1159
        cmsg->cmsg_len = CMSG_LEN(len);
1160

    
1161
        if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1162
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1163
            memcpy(data, target_data, len);
1164
        } else {
1165
            int *fd = (int *)data;
1166
            int *target_fd = (int *)target_data;
1167
            int i, numfds = len / sizeof(int);
1168

    
1169
            for (i = 0; i < numfds; i++)
1170
                fd[i] = tswap32(target_fd[i]);
1171
        }
1172

    
1173
        cmsg = CMSG_NXTHDR(msgh, cmsg);
1174
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1175
    }
1176
    unlock_user(target_cmsg, target_cmsg_addr, 0);
1177
 the_end:
1178
    msgh->msg_controllen = space;
1179
    return 0;
1180
}
1181

    
1182
static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
1183
                                           struct msghdr *msgh)
1184
{
1185
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1186
    abi_long msg_controllen;
1187
    abi_ulong target_cmsg_addr;
1188
    struct target_cmsghdr *target_cmsg;
1189
    socklen_t space = 0;
1190

    
1191
    msg_controllen = tswapal(target_msgh->msg_controllen);
1192
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1193
        goto the_end;
1194
    target_cmsg_addr = tswapal(target_msgh->msg_control);
1195
    target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
1196
    if (!target_cmsg)
1197
        return -TARGET_EFAULT;
1198

    
1199
    while (cmsg && target_cmsg) {
1200
        void *data = CMSG_DATA(cmsg);
1201
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
1202

    
1203
        int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
1204

    
1205
        space += TARGET_CMSG_SPACE(len);
1206
        if (space > msg_controllen) {
1207
            space -= TARGET_CMSG_SPACE(len);
1208
            gemu_log("Target cmsg overflow\n");
1209
            break;
1210
        }
1211

    
1212
        if (cmsg->cmsg_level == SOL_SOCKET) {
1213
            target_cmsg->cmsg_level = tswap32(TARGET_SOL_SOCKET);
1214
        } else {
1215
            target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
1216
        }
1217
        target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
1218
        target_cmsg->cmsg_len = tswapal(TARGET_CMSG_LEN(len));
1219

    
1220
        if ((cmsg->cmsg_level == SOL_SOCKET) &&
1221
                                (cmsg->cmsg_type == SCM_RIGHTS)) {
1222
            int *fd = (int *)data;
1223
            int *target_fd = (int *)target_data;
1224
            int i, numfds = len / sizeof(int);
1225

    
1226
            for (i = 0; i < numfds; i++)
1227
                target_fd[i] = tswap32(fd[i]);
1228
        } else if ((cmsg->cmsg_level == SOL_SOCKET) &&
1229
                                (cmsg->cmsg_type == SO_TIMESTAMP) &&
1230
                                (len == sizeof(struct timeval))) {
1231
            /* copy struct timeval to target */
1232
            struct timeval *tv = (struct timeval *)data;
1233
            struct target_timeval *target_tv =
1234
                                        (struct target_timeval *)target_data;
1235

    
1236
            target_tv->tv_sec = tswapal(tv->tv_sec);
1237
            target_tv->tv_usec = tswapal(tv->tv_usec);
1238
        } else {
1239
            gemu_log("Unsupported ancillary data: %d/%d\n",
1240
                                        cmsg->cmsg_level, cmsg->cmsg_type);
1241
            memcpy(target_data, data, len);
1242
        }
1243

    
1244
        cmsg = CMSG_NXTHDR(msgh, cmsg);
1245
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1246
    }
1247
    unlock_user(target_cmsg, target_cmsg_addr, space);
1248
 the_end:
1249
    target_msgh->msg_controllen = tswapal(space);
1250
    return 0;
1251
}
1252

    
1253
/* do_setsockopt() Must return target values and target errnos. */
1254
static abi_long do_setsockopt(int sockfd, int level, int optname,
1255
                              abi_ulong optval_addr, socklen_t optlen)
1256
{
1257
    abi_long ret;
1258
    int val;
1259
    struct ip_mreqn *ip_mreq;
1260
    struct ip_mreq_source *ip_mreq_source;
1261

    
1262
    switch(level) {
1263
    case SOL_TCP:
1264
        /* TCP options all take an 'int' value.  */
1265
        if (optlen < sizeof(uint32_t))
1266
            return -TARGET_EINVAL;
1267

    
1268
        if (get_user_u32(val, optval_addr))
1269
            return -TARGET_EFAULT;
1270
        ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1271
        break;
1272
    case SOL_IP:
1273
        switch(optname) {
1274
        case IP_TOS:
1275
        case IP_TTL:
1276
        case IP_HDRINCL:
1277
        case IP_ROUTER_ALERT:
1278
        case IP_RECVOPTS:
1279
        case IP_RETOPTS:
1280
        case IP_PKTINFO:
1281
        case IP_MTU_DISCOVER:
1282
        case IP_RECVERR:
1283
        case IP_RECVTOS:
1284
#ifdef IP_FREEBIND
1285
        case IP_FREEBIND:
1286
#endif
1287
        case IP_MULTICAST_TTL:
1288
        case IP_MULTICAST_LOOP:
1289
            val = 0;
1290
            if (optlen >= sizeof(uint32_t)) {
1291
                if (get_user_u32(val, optval_addr))
1292
                    return -TARGET_EFAULT;
1293
            } else if (optlen >= 1) {
1294
                if (get_user_u8(val, optval_addr))
1295
                    return -TARGET_EFAULT;
1296
            }
1297
            ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1298
            break;
1299
        case IP_ADD_MEMBERSHIP:
1300
        case IP_DROP_MEMBERSHIP:
1301
            if (optlen < sizeof (struct target_ip_mreq) ||
1302
                optlen > sizeof (struct target_ip_mreqn))
1303
                return -TARGET_EINVAL;
1304

    
1305
            ip_mreq = (struct ip_mreqn *) alloca(optlen);
1306
            target_to_host_ip_mreq(ip_mreq, optval_addr, optlen);
1307
            ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq, optlen));
1308
            break;
1309

    
1310
        case IP_BLOCK_SOURCE:
1311
        case IP_UNBLOCK_SOURCE:
1312
        case IP_ADD_SOURCE_MEMBERSHIP:
1313
        case IP_DROP_SOURCE_MEMBERSHIP:
1314
            if (optlen != sizeof (struct target_ip_mreq_source))
1315
                return -TARGET_EINVAL;
1316

    
1317
            ip_mreq_source = lock_user(VERIFY_READ, optval_addr, optlen, 1);
1318
            ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq_source, optlen));
1319
            unlock_user (ip_mreq_source, optval_addr, 0);
1320
            break;
1321

    
1322
        default:
1323
            goto unimplemented;
1324
        }
1325
        break;
1326
    case SOL_IPV6:
1327
        switch (optname) {
1328
        case IPV6_MTU_DISCOVER:
1329
        case IPV6_MTU:
1330
        case IPV6_V6ONLY:
1331
        case IPV6_RECVPKTINFO:
1332
            val = 0;
1333
            if (optlen < sizeof(uint32_t)) {
1334
                return -TARGET_EINVAL;
1335
            }
1336
            if (get_user_u32(val, optval_addr)) {
1337
                return -TARGET_EFAULT;
1338
            }
1339
            ret = get_errno(setsockopt(sockfd, level, optname,
1340
                                       &val, sizeof(val)));
1341
            break;
1342
        default:
1343
            goto unimplemented;
1344
        }
1345
        break;
1346
    case SOL_RAW:
1347
        switch (optname) {
1348
        case ICMP_FILTER:
1349
            /* struct icmp_filter takes an u32 value */
1350
            if (optlen < sizeof(uint32_t)) {
1351
                return -TARGET_EINVAL;
1352
            }
1353

    
1354
            if (get_user_u32(val, optval_addr)) {
1355
                return -TARGET_EFAULT;
1356
            }
1357
            ret = get_errno(setsockopt(sockfd, level, optname,
1358
                                       &val, sizeof(val)));
1359
            break;
1360

    
1361
        default:
1362
            goto unimplemented;
1363
        }
1364
        break;
1365
    case TARGET_SOL_SOCKET:
1366
        switch (optname) {
1367
        case TARGET_SO_RCVTIMEO:
1368
        {
1369
                struct timeval tv;
1370

    
1371
                optname = SO_RCVTIMEO;
1372

    
1373
set_timeout:
1374
                if (optlen != sizeof(struct target_timeval)) {
1375
                    return -TARGET_EINVAL;
1376
                }
1377

    
1378
                if (copy_from_user_timeval(&tv, optval_addr)) {
1379
                    return -TARGET_EFAULT;
1380
                }
1381

    
1382
                ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname,
1383
                                &tv, sizeof(tv)));
1384
                return ret;
1385
        }
1386
        case TARGET_SO_SNDTIMEO:
1387
                optname = SO_SNDTIMEO;
1388
                goto set_timeout;
1389
        case TARGET_SO_ATTACH_FILTER:
1390
        {
1391
                struct target_sock_fprog *tfprog;
1392
                struct target_sock_filter *tfilter;
1393
                struct sock_fprog fprog;
1394
                struct sock_filter *filter;
1395
                int i;
1396

    
1397
                if (optlen != sizeof(*tfprog)) {
1398
                    return -TARGET_EINVAL;
1399
                }
1400
                if (!lock_user_struct(VERIFY_READ, tfprog, optval_addr, 0)) {
1401
                    return -TARGET_EFAULT;
1402
                }
1403
                if (!lock_user_struct(VERIFY_READ, tfilter,
1404
                                      tswapal(tfprog->filter), 0)) {
1405
                    unlock_user_struct(tfprog, optval_addr, 1);
1406
                    return -TARGET_EFAULT;
1407
                }
1408

    
1409
                fprog.len = tswap16(tfprog->len);
1410
                filter = malloc(fprog.len * sizeof(*filter));
1411
                if (filter == NULL) {
1412
                    unlock_user_struct(tfilter, tfprog->filter, 1);
1413
                    unlock_user_struct(tfprog, optval_addr, 1);
1414
                    return -TARGET_ENOMEM;
1415
                }
1416
                for (i = 0; i < fprog.len; i++) {
1417
                    filter[i].code = tswap16(tfilter[i].code);
1418
                    filter[i].jt = tfilter[i].jt;
1419
                    filter[i].jf = tfilter[i].jf;
1420
                    filter[i].k = tswap32(tfilter[i].k);
1421
                }
1422
                fprog.filter = filter;
1423

    
1424
                ret = get_errno(setsockopt(sockfd, SOL_SOCKET,
1425
                                SO_ATTACH_FILTER, &fprog, sizeof(fprog)));
1426
                free(filter);
1427

    
1428
                unlock_user_struct(tfilter, tfprog->filter, 1);
1429
                unlock_user_struct(tfprog, optval_addr, 1);
1430
                return ret;
1431
        }
1432
            /* Options with 'int' argument.  */
1433
        case TARGET_SO_DEBUG:
1434
                optname = SO_DEBUG;
1435
                break;
1436
        case TARGET_SO_REUSEADDR:
1437
                optname = SO_REUSEADDR;
1438
                break;
1439
        case TARGET_SO_TYPE:
1440
                optname = SO_TYPE;
1441
                break;
1442
        case TARGET_SO_ERROR:
1443
                optname = SO_ERROR;
1444
                break;
1445
        case TARGET_SO_DONTROUTE:
1446
                optname = SO_DONTROUTE;
1447
                break;
1448
        case TARGET_SO_BROADCAST:
1449
                optname = SO_BROADCAST;
1450
                break;
1451
        case TARGET_SO_SNDBUF:
1452
                optname = SO_SNDBUF;
1453
                break;
1454
        case TARGET_SO_RCVBUF:
1455
                optname = SO_RCVBUF;
1456
                break;
1457
        case TARGET_SO_KEEPALIVE:
1458
                optname = SO_KEEPALIVE;
1459
                break;
1460
        case TARGET_SO_OOBINLINE:
1461
                optname = SO_OOBINLINE;
1462
                break;
1463
        case TARGET_SO_NO_CHECK:
1464
                optname = SO_NO_CHECK;
1465
                break;
1466
        case TARGET_SO_PRIORITY:
1467
                optname = SO_PRIORITY;
1468
                break;
1469
#ifdef SO_BSDCOMPAT
1470
        case TARGET_SO_BSDCOMPAT:
1471
                optname = SO_BSDCOMPAT;
1472
                break;
1473
#endif
1474
        case TARGET_SO_PASSCRED:
1475
                optname = SO_PASSCRED;
1476
                break;
1477
        case TARGET_SO_TIMESTAMP:
1478
                optname = SO_TIMESTAMP;
1479
                break;
1480
        case TARGET_SO_RCVLOWAT:
1481
                optname = SO_RCVLOWAT;
1482
                break;
1483
            break;
1484
        default:
1485
            goto unimplemented;
1486
        }
1487
        if (optlen < sizeof(uint32_t))
1488
            return -TARGET_EINVAL;
1489

    
1490
        if (get_user_u32(val, optval_addr))
1491
            return -TARGET_EFAULT;
1492
        ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
1493
        break;
1494
    default:
1495
    unimplemented:
1496
        gemu_log("Unsupported setsockopt level=%d optname=%d\n", level, optname);
1497
        ret = -TARGET_ENOPROTOOPT;
1498
    }
1499
    return ret;
1500
}
1501

    
1502
/* do_getsockopt() Must return target values and target errnos. */
1503
static abi_long do_getsockopt(int sockfd, int level, int optname,
1504
                              abi_ulong optval_addr, abi_ulong optlen)
1505
{
1506
    abi_long ret;
1507
    int len, val;
1508
    socklen_t lv;
1509

    
1510
    switch(level) {
1511
    case TARGET_SOL_SOCKET:
1512
        level = SOL_SOCKET;
1513
        switch (optname) {
1514
        /* These don't just return a single integer */
1515
        case TARGET_SO_LINGER:
1516
        case TARGET_SO_RCVTIMEO:
1517
        case TARGET_SO_SNDTIMEO:
1518
        case TARGET_SO_PEERNAME:
1519
            goto unimplemented;
1520
        case TARGET_SO_PEERCRED: {
1521
            struct ucred cr;
1522
            socklen_t crlen;
1523
            struct target_ucred *tcr;
1524

    
1525
            if (get_user_u32(len, optlen)) {
1526
                return -TARGET_EFAULT;
1527
            }
1528
            if (len < 0) {
1529
                return -TARGET_EINVAL;
1530
            }
1531

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

    
1684
static struct iovec *lock_iovec(int type, abi_ulong target_addr,
1685
                                int count, int copy)
1686
{
1687
    struct target_iovec *target_vec;
1688
    struct iovec *vec;
1689
    abi_ulong total_len, max_len;
1690
    int i;
1691

    
1692
    if (count == 0) {
1693
        errno = 0;
1694
        return NULL;
1695
    }
1696
    if (count < 0 || count > IOV_MAX) {
1697
        errno = EINVAL;
1698
        return NULL;
1699
    }
1700

    
1701
    vec = calloc(count, sizeof(struct iovec));
1702
    if (vec == NULL) {
1703
        errno = ENOMEM;
1704
        return NULL;
1705
    }
1706

    
1707
    target_vec = lock_user(VERIFY_READ, target_addr,
1708
                           count * sizeof(struct target_iovec), 1);
1709
    if (target_vec == NULL) {
1710
        errno = EFAULT;
1711
        goto fail2;
1712
    }
1713

    
1714
    /* ??? If host page size > target page size, this will result in a
1715
       value larger than what we can actually support.  */
1716
    max_len = 0x7fffffff & TARGET_PAGE_MASK;
1717
    total_len = 0;
1718

    
1719
    for (i = 0; i < count; i++) {
1720
        abi_ulong base = tswapal(target_vec[i].iov_base);
1721
        abi_long len = tswapal(target_vec[i].iov_len);
1722

    
1723
        if (len < 0) {
1724
            errno = EINVAL;
1725
            goto fail;
1726
        } else if (len == 0) {
1727
            /* Zero length pointer is ignored.  */
1728
            vec[i].iov_base = 0;
1729
        } else {
1730
            vec[i].iov_base = lock_user(type, base, len, copy);
1731
            if (!vec[i].iov_base) {
1732
                errno = EFAULT;
1733
                goto fail;
1734
            }
1735
            if (len > max_len - total_len) {
1736
                len = max_len - total_len;
1737
            }
1738
        }
1739
        vec[i].iov_len = len;
1740
        total_len += len;
1741
    }
1742

    
1743
    unlock_user(target_vec, target_addr, 0);
1744
    return vec;
1745

    
1746
 fail:
1747
    free(vec);
1748
 fail2:
1749
    unlock_user(target_vec, target_addr, 0);
1750
    return NULL;
1751
}
1752

    
1753
static void unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1754
                         int count, int copy)
1755
{
1756
    struct target_iovec *target_vec;
1757
    int i;
1758

    
1759
    target_vec = lock_user(VERIFY_READ, target_addr,
1760
                           count * sizeof(struct target_iovec), 1);
1761
    if (target_vec) {
1762
        for (i = 0; i < count; i++) {
1763
            abi_ulong base = tswapal(target_vec[i].iov_base);
1764
            abi_long len = tswapal(target_vec[i].iov_base);
1765
            if (len < 0) {
1766
                break;
1767
            }
1768
            unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1769
        }
1770
        unlock_user(target_vec, target_addr, 0);
1771
    }
1772

    
1773
    free(vec);
1774
}
1775

    
1776
static inline int target_to_host_sock_type(int *type)
1777
{
1778
    int host_type = 0;
1779
    int target_type = *type;
1780

    
1781
    switch (target_type & TARGET_SOCK_TYPE_MASK) {
1782
    case TARGET_SOCK_DGRAM:
1783
        host_type = SOCK_DGRAM;
1784
        break;
1785
    case TARGET_SOCK_STREAM:
1786
        host_type = SOCK_STREAM;
1787
        break;
1788
    default:
1789
        host_type = target_type & TARGET_SOCK_TYPE_MASK;
1790
        break;
1791
    }
1792
    if (target_type & TARGET_SOCK_CLOEXEC) {
1793
#if defined(SOCK_CLOEXEC)
1794
        host_type |= SOCK_CLOEXEC;
1795
#else
1796
        return -TARGET_EINVAL;
1797
#endif
1798
    }
1799
    if (target_type & TARGET_SOCK_NONBLOCK) {
1800
#if defined(SOCK_NONBLOCK)
1801
        host_type |= SOCK_NONBLOCK;
1802
#elif !defined(O_NONBLOCK)
1803
        return -TARGET_EINVAL;
1804
#endif
1805
    }
1806
    *type = host_type;
1807
    return 0;
1808
}
1809

    
1810
/* Try to emulate socket type flags after socket creation.  */
1811
static int sock_flags_fixup(int fd, int target_type)
1812
{
1813
#if !defined(SOCK_NONBLOCK) && defined(O_NONBLOCK)
1814
    if (target_type & TARGET_SOCK_NONBLOCK) {
1815
        int flags = fcntl(fd, F_GETFL);
1816
        if (fcntl(fd, F_SETFL, O_NONBLOCK | flags) == -1) {
1817
            close(fd);
1818
            return -TARGET_EINVAL;
1819
        }
1820
    }
1821
#endif
1822
    return fd;
1823
}
1824

    
1825
/* do_socket() Must return target values and target errnos. */
1826
static abi_long do_socket(int domain, int type, int protocol)
1827
{
1828
    int target_type = type;
1829
    int ret;
1830

    
1831
    ret = target_to_host_sock_type(&type);
1832
    if (ret) {
1833
        return ret;
1834
    }
1835

    
1836
    if (domain == PF_NETLINK)
1837
        return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1838
    ret = get_errno(socket(domain, type, protocol));
1839
    if (ret >= 0) {
1840
        ret = sock_flags_fixup(ret, target_type);
1841
    }
1842
    return ret;
1843
}
1844

    
1845
/* do_bind() Must return target values and target errnos. */
1846
static abi_long do_bind(int sockfd, abi_ulong target_addr,
1847
                        socklen_t addrlen)
1848
{
1849
    void *addr;
1850
    abi_long ret;
1851

    
1852
    if ((int)addrlen < 0) {
1853
        return -TARGET_EINVAL;
1854
    }
1855

    
1856
    addr = alloca(addrlen+1);
1857

    
1858
    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1859
    if (ret)
1860
        return ret;
1861

    
1862
    return get_errno(bind(sockfd, addr, addrlen));
1863
}
1864

    
1865
/* do_connect() Must return target values and target errnos. */
1866
static abi_long do_connect(int sockfd, abi_ulong target_addr,
1867
                           socklen_t addrlen)
1868
{
1869
    void *addr;
1870
    abi_long ret;
1871

    
1872
    if ((int)addrlen < 0) {
1873
        return -TARGET_EINVAL;
1874
    }
1875

    
1876
    addr = alloca(addrlen);
1877

    
1878
    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1879
    if (ret)
1880
        return ret;
1881

    
1882
    return get_errno(connect(sockfd, addr, addrlen));
1883
}
1884

    
1885
/* do_sendrecvmsg() Must return target values and target errnos. */
1886
static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1887
                               int flags, int send)
1888
{
1889
    abi_long ret, len;
1890
    struct target_msghdr *msgp;
1891
    struct msghdr msg;
1892
    int count;
1893
    struct iovec *vec;
1894
    abi_ulong target_vec;
1895

    
1896
    /* FIXME */
1897
    if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1898
                          msgp,
1899
                          target_msg,
1900
                          send ? 1 : 0))
1901
        return -TARGET_EFAULT;
1902
    if (msgp->msg_name) {
1903
        msg.msg_namelen = tswap32(msgp->msg_namelen);
1904
        msg.msg_name = alloca(msg.msg_namelen);
1905
        ret = target_to_host_sockaddr(msg.msg_name, tswapal(msgp->msg_name),
1906
                                msg.msg_namelen);
1907
        if (ret) {
1908
            goto out2;
1909
        }
1910
    } else {
1911
        msg.msg_name = NULL;
1912
        msg.msg_namelen = 0;
1913
    }
1914
    msg.msg_controllen = 2 * tswapal(msgp->msg_controllen);
1915
    msg.msg_control = alloca(msg.msg_controllen);
1916
    msg.msg_flags = tswap32(msgp->msg_flags);
1917

    
1918
    count = tswapal(msgp->msg_iovlen);
1919
    target_vec = tswapal(msgp->msg_iov);
1920
    vec = lock_iovec(send ? VERIFY_READ : VERIFY_WRITE,
1921
                     target_vec, count, send);
1922
    if (vec == NULL) {
1923
        ret = -host_to_target_errno(errno);
1924
        goto out2;
1925
    }
1926
    msg.msg_iovlen = count;
1927
    msg.msg_iov = vec;
1928

    
1929
    if (send) {
1930
        ret = target_to_host_cmsg(&msg, msgp);
1931
        if (ret == 0)
1932
            ret = get_errno(sendmsg(fd, &msg, flags));
1933
    } else {
1934
        ret = get_errno(recvmsg(fd, &msg, flags));
1935
        if (!is_error(ret)) {
1936
            len = ret;
1937
            ret = host_to_target_cmsg(msgp, &msg);
1938
            if (!is_error(ret)) {
1939
                msgp->msg_namelen = tswap32(msg.msg_namelen);
1940
                if (msg.msg_name != NULL) {
1941
                    ret = host_to_target_sockaddr(tswapal(msgp->msg_name),
1942
                                    msg.msg_name, msg.msg_namelen);
1943
                    if (ret) {
1944
                        goto out;
1945
                    }
1946
                }
1947

    
1948
                ret = len;
1949
            }
1950
        }
1951
    }
1952

    
1953
out:
1954
    unlock_iovec(vec, target_vec, count, !send);
1955
out2:
1956
    unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1957
    return ret;
1958
}
1959

    
1960
/* If we don't have a system accept4() then just call accept.
1961
 * The callsites to do_accept4() will ensure that they don't
1962
 * pass a non-zero flags argument in this config.
1963
 */
1964
#ifndef CONFIG_ACCEPT4
1965
static inline int accept4(int sockfd, struct sockaddr *addr,
1966
                          socklen_t *addrlen, int flags)
1967
{
1968
    assert(flags == 0);
1969
    return accept(sockfd, addr, addrlen);
1970
}
1971
#endif
1972

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

    
1981
    if (target_addr == 0) {
1982
        return get_errno(accept4(fd, NULL, NULL, flags));
1983
    }
1984

    
1985
    /* linux returns EINVAL if addrlen pointer is invalid */
1986
    if (get_user_u32(addrlen, target_addrlen_addr))
1987
        return -TARGET_EINVAL;
1988

    
1989
    if ((int)addrlen < 0) {
1990
        return -TARGET_EINVAL;
1991
    }
1992

    
1993
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1994
        return -TARGET_EINVAL;
1995

    
1996
    addr = alloca(addrlen);
1997

    
1998
    ret = get_errno(accept4(fd, addr, &addrlen, flags));
1999
    if (!is_error(ret)) {
2000
        host_to_target_sockaddr(target_addr, addr, addrlen);
2001
        if (put_user_u32(addrlen, target_addrlen_addr))
2002
            ret = -TARGET_EFAULT;
2003
    }
2004
    return ret;
2005
}
2006

    
2007
/* do_getpeername() Must return target values and target errnos. */
2008
static abi_long do_getpeername(int fd, abi_ulong target_addr,
2009
                               abi_ulong target_addrlen_addr)
2010
{
2011
    socklen_t addrlen;
2012
    void *addr;
2013
    abi_long ret;
2014

    
2015
    if (get_user_u32(addrlen, target_addrlen_addr))
2016
        return -TARGET_EFAULT;
2017

    
2018
    if ((int)addrlen < 0) {
2019
        return -TARGET_EINVAL;
2020
    }
2021

    
2022
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
2023
        return -TARGET_EFAULT;
2024

    
2025
    addr = alloca(addrlen);
2026

    
2027
    ret = get_errno(getpeername(fd, addr, &addrlen));
2028
    if (!is_error(ret)) {
2029
        host_to_target_sockaddr(target_addr, addr, addrlen);
2030
        if (put_user_u32(addrlen, target_addrlen_addr))
2031
            ret = -TARGET_EFAULT;
2032
    }
2033
    return ret;
2034
}
2035

    
2036
/* do_getsockname() Must return target values and target errnos. */
2037
static abi_long do_getsockname(int fd, abi_ulong target_addr,
2038
                               abi_ulong target_addrlen_addr)
2039
{
2040
    socklen_t addrlen;
2041
    void *addr;
2042
    abi_long ret;
2043

    
2044
    if (get_user_u32(addrlen, target_addrlen_addr))
2045
        return -TARGET_EFAULT;
2046

    
2047
    if ((int)addrlen < 0) {
2048
        return -TARGET_EINVAL;
2049
    }
2050

    
2051
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
2052
        return -TARGET_EFAULT;
2053

    
2054
    addr = alloca(addrlen);
2055

    
2056
    ret = get_errno(getsockname(fd, addr, &addrlen));
2057
    if (!is_error(ret)) {
2058
        host_to_target_sockaddr(target_addr, addr, addrlen);
2059
        if (put_user_u32(addrlen, target_addrlen_addr))
2060
            ret = -TARGET_EFAULT;
2061
    }
2062
    return ret;
2063
}
2064

    
2065
/* do_socketpair() Must return target values and target errnos. */
2066
static abi_long do_socketpair(int domain, int type, int protocol,
2067
                              abi_ulong target_tab_addr)
2068
{
2069
    int tab[2];
2070
    abi_long ret;
2071

    
2072
    target_to_host_sock_type(&type);
2073

    
2074
    ret = get_errno(socketpair(domain, type, protocol, tab));
2075
    if (!is_error(ret)) {
2076
        if (put_user_s32(tab[0], target_tab_addr)
2077
            || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
2078
            ret = -TARGET_EFAULT;
2079
    }
2080
    return ret;
2081
}
2082

    
2083
/* do_sendto() Must return target values and target errnos. */
2084
static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
2085
                          abi_ulong target_addr, socklen_t addrlen)
2086
{
2087
    void *addr;
2088
    void *host_msg;
2089
    abi_long ret;
2090

    
2091
    if ((int)addrlen < 0) {
2092
        return -TARGET_EINVAL;
2093
    }
2094

    
2095
    host_msg = lock_user(VERIFY_READ, msg, len, 1);
2096
    if (!host_msg)
2097
        return -TARGET_EFAULT;
2098
    if (target_addr) {
2099
        addr = alloca(addrlen);
2100
        ret = target_to_host_sockaddr(addr, target_addr, addrlen);
2101
        if (ret) {
2102
            unlock_user(host_msg, msg, 0);
2103
            return ret;
2104
        }
2105
        ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
2106
    } else {
2107
        ret = get_errno(send(fd, host_msg, len, flags));
2108
    }
2109
    unlock_user(host_msg, msg, 0);
2110
    return ret;
2111
}
2112

    
2113
/* do_recvfrom() Must return target values and target errnos. */
2114
static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
2115
                            abi_ulong target_addr,
2116
                            abi_ulong target_addrlen)
2117
{
2118
    socklen_t addrlen;
2119
    void *addr;
2120
    void *host_msg;
2121
    abi_long ret;
2122

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

    
2157
#ifdef TARGET_NR_socketcall
2158
/* do_socketcall() Must return target values and target errnos. */
2159
static abi_long do_socketcall(int num, abi_ulong vptr)
2160
{
2161
    abi_long ret;
2162
    const int n = sizeof(abi_ulong);
2163

    
2164
    switch(num) {
2165
    case SOCKOP_socket:
2166
        {
2167
            abi_ulong domain, type, protocol;
2168

    
2169
            if (get_user_ual(domain, vptr)
2170
                || get_user_ual(type, vptr + n)
2171
                || get_user_ual(protocol, vptr + 2 * n))
2172
                return -TARGET_EFAULT;
2173

    
2174
            ret = do_socket(domain, type, protocol);
2175
        }
2176
        break;
2177
    case SOCKOP_bind:
2178
        {
2179
            abi_ulong sockfd;
2180
            abi_ulong target_addr;
2181
            socklen_t addrlen;
2182

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

    
2188
            ret = do_bind(sockfd, target_addr, addrlen);
2189
        }
2190
        break;
2191
    case SOCKOP_connect:
2192
        {
2193
            abi_ulong sockfd;
2194
            abi_ulong target_addr;
2195
            socklen_t addrlen;
2196

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

    
2202
            ret = do_connect(sockfd, target_addr, addrlen);
2203
        }
2204
        break;
2205
    case SOCKOP_listen:
2206
        {
2207
            abi_ulong sockfd, backlog;
2208

    
2209
            if (get_user_ual(sockfd, vptr)
2210
                || get_user_ual(backlog, vptr + n))
2211
                return -TARGET_EFAULT;
2212

    
2213
            ret = get_errno(listen(sockfd, backlog));
2214
        }
2215
        break;
2216
    case SOCKOP_accept:
2217
        {
2218
            abi_ulong sockfd;
2219
            abi_ulong target_addr, target_addrlen;
2220

    
2221
            if (get_user_ual(sockfd, vptr)
2222
                || get_user_ual(target_addr, vptr + n)
2223
                || get_user_ual(target_addrlen, vptr + 2 * n))
2224
                return -TARGET_EFAULT;
2225

    
2226
            ret = do_accept4(sockfd, target_addr, target_addrlen, 0);
2227
        }
2228
        break;
2229
    case SOCKOP_getsockname:
2230
        {
2231
            abi_ulong sockfd;
2232
            abi_ulong target_addr, target_addrlen;
2233

    
2234
            if (get_user_ual(sockfd, vptr)
2235
                || get_user_ual(target_addr, vptr + n)
2236
                || get_user_ual(target_addrlen, vptr + 2 * n))
2237
                return -TARGET_EFAULT;
2238

    
2239
            ret = do_getsockname(sockfd, target_addr, target_addrlen);
2240
        }
2241
        break;
2242
    case SOCKOP_getpeername:
2243
        {
2244
            abi_ulong sockfd;
2245
            abi_ulong target_addr, target_addrlen;
2246

    
2247
            if (get_user_ual(sockfd, vptr)
2248
                || get_user_ual(target_addr, vptr + n)
2249
                || get_user_ual(target_addrlen, vptr + 2 * n))
2250
                return -TARGET_EFAULT;
2251

    
2252
            ret = do_getpeername(sockfd, target_addr, target_addrlen);
2253
        }
2254
        break;
2255
    case SOCKOP_socketpair:
2256
        {
2257
            abi_ulong domain, type, protocol;
2258
            abi_ulong tab;
2259

    
2260
            if (get_user_ual(domain, vptr)
2261
                || get_user_ual(type, vptr + n)
2262
                || get_user_ual(protocol, vptr + 2 * n)
2263
                || get_user_ual(tab, vptr + 3 * n))
2264
                return -TARGET_EFAULT;
2265

    
2266
            ret = do_socketpair(domain, type, protocol, tab);
2267
        }
2268
        break;
2269
    case SOCKOP_send:
2270
        {
2271
            abi_ulong sockfd;
2272
            abi_ulong msg;
2273
            size_t len;
2274
            abi_ulong flags;
2275

    
2276
            if (get_user_ual(sockfd, vptr)
2277
                || get_user_ual(msg, vptr + n)
2278
                || get_user_ual(len, vptr + 2 * n)
2279
                || get_user_ual(flags, vptr + 3 * n))
2280
                return -TARGET_EFAULT;
2281

    
2282
            ret = do_sendto(sockfd, msg, len, flags, 0, 0);
2283
        }
2284
        break;
2285
    case SOCKOP_recv:
2286
        {
2287
            abi_ulong sockfd;
2288
            abi_ulong msg;
2289
            size_t len;
2290
            abi_ulong flags;
2291

    
2292
            if (get_user_ual(sockfd, vptr)
2293
                || get_user_ual(msg, vptr + n)
2294
                || get_user_ual(len, vptr + 2 * n)
2295
                || get_user_ual(flags, vptr + 3 * n))
2296
                return -TARGET_EFAULT;
2297

    
2298
            ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
2299
        }
2300
        break;
2301
    case SOCKOP_sendto:
2302
        {
2303
            abi_ulong sockfd;
2304
            abi_ulong msg;
2305
            size_t len;
2306
            abi_ulong flags;
2307
            abi_ulong addr;
2308
            socklen_t addrlen;
2309

    
2310
            if (get_user_ual(sockfd, vptr)
2311
                || get_user_ual(msg, vptr + n)
2312
                || get_user_ual(len, vptr + 2 * n)
2313
                || get_user_ual(flags, vptr + 3 * n)
2314
                || get_user_ual(addr, vptr + 4 * n)
2315
                || get_user_ual(addrlen, vptr + 5 * n))
2316
                return -TARGET_EFAULT;
2317

    
2318
            ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
2319
        }
2320
        break;
2321
    case SOCKOP_recvfrom:
2322
        {
2323
            abi_ulong sockfd;
2324
            abi_ulong msg;
2325
            size_t len;
2326
            abi_ulong flags;
2327
            abi_ulong addr;
2328
            socklen_t addrlen;
2329

    
2330
            if (get_user_ual(sockfd, vptr)
2331
                || get_user_ual(msg, vptr + n)
2332
                || get_user_ual(len, vptr + 2 * n)
2333
                || get_user_ual(flags, vptr + 3 * n)
2334
                || get_user_ual(addr, vptr + 4 * n)
2335
                || get_user_ual(addrlen, vptr + 5 * n))
2336
                return -TARGET_EFAULT;
2337

    
2338
            ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
2339
        }
2340
        break;
2341
    case SOCKOP_shutdown:
2342
        {
2343
            abi_ulong sockfd, how;
2344

    
2345
            if (get_user_ual(sockfd, vptr)
2346
                || get_user_ual(how, vptr + n))
2347
                return -TARGET_EFAULT;
2348

    
2349
            ret = get_errno(shutdown(sockfd, how));
2350
        }
2351
        break;
2352
    case SOCKOP_sendmsg:
2353
    case SOCKOP_recvmsg:
2354
        {
2355
            abi_ulong fd;
2356
            abi_ulong target_msg;
2357
            abi_ulong flags;
2358

    
2359
            if (get_user_ual(fd, vptr)
2360
                || get_user_ual(target_msg, vptr + n)
2361
                || get_user_ual(flags, vptr + 2 * n))
2362
                return -TARGET_EFAULT;
2363

    
2364
            ret = do_sendrecvmsg(fd, target_msg, flags,
2365
                                 (num == SOCKOP_sendmsg));
2366
        }
2367
        break;
2368
    case SOCKOP_setsockopt:
2369
        {
2370
            abi_ulong sockfd;
2371
            abi_ulong level;
2372
            abi_ulong optname;
2373
            abi_ulong optval;
2374
            socklen_t optlen;
2375

    
2376
            if (get_user_ual(sockfd, vptr)
2377
                || get_user_ual(level, vptr + n)
2378
                || get_user_ual(optname, vptr + 2 * n)
2379
                || get_user_ual(optval, vptr + 3 * n)
2380
                || get_user_ual(optlen, vptr + 4 * n))
2381
                return -TARGET_EFAULT;
2382

    
2383
            ret = do_setsockopt(sockfd, level, optname, optval, optlen);
2384
        }
2385
        break;
2386
    case SOCKOP_getsockopt:
2387
        {
2388
            abi_ulong sockfd;
2389
            abi_ulong level;
2390
            abi_ulong optname;
2391
            abi_ulong optval;
2392
            socklen_t optlen;
2393

    
2394
            if (get_user_ual(sockfd, vptr)
2395
                || get_user_ual(level, vptr + n)
2396
                || get_user_ual(optname, vptr + 2 * n)
2397
                || get_user_ual(optval, vptr + 3 * n)
2398
                || get_user_ual(optlen, vptr + 4 * n))
2399
                return -TARGET_EFAULT;
2400

    
2401
            ret = do_getsockopt(sockfd, level, optname, optval, optlen);
2402
        }
2403
        break;
2404
    default:
2405
        gemu_log("Unsupported socketcall: %d\n", num);
2406
        ret = -TARGET_ENOSYS;
2407
        break;
2408
    }
2409
    return ret;
2410
}
2411
#endif
2412

    
2413
#define N_SHM_REGIONS        32
2414

    
2415
static struct shm_region {
2416
    abi_ulong        start;
2417
    abi_ulong        size;
2418
} shm_regions[N_SHM_REGIONS];
2419

    
2420
struct target_ipc_perm
2421
{
2422
    abi_long __key;
2423
    abi_ulong uid;
2424
    abi_ulong gid;
2425
    abi_ulong cuid;
2426
    abi_ulong cgid;
2427
    unsigned short int mode;
2428
    unsigned short int __pad1;
2429
    unsigned short int __seq;
2430
    unsigned short int __pad2;
2431
    abi_ulong __unused1;
2432
    abi_ulong __unused2;
2433
};
2434

    
2435
struct target_semid_ds
2436
{
2437
  struct target_ipc_perm sem_perm;
2438
  abi_ulong sem_otime;
2439
  abi_ulong __unused1;
2440
  abi_ulong sem_ctime;
2441
  abi_ulong __unused2;
2442
  abi_ulong sem_nsems;
2443
  abi_ulong __unused3;
2444
  abi_ulong __unused4;
2445
};
2446

    
2447
static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
2448
                                               abi_ulong target_addr)
2449
{
2450
    struct target_ipc_perm *target_ip;
2451
    struct target_semid_ds *target_sd;
2452

    
2453
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2454
        return -TARGET_EFAULT;
2455
    target_ip = &(target_sd->sem_perm);
2456
    host_ip->__key = tswapal(target_ip->__key);
2457
    host_ip->uid = tswapal(target_ip->uid);
2458
    host_ip->gid = tswapal(target_ip->gid);
2459
    host_ip->cuid = tswapal(target_ip->cuid);
2460
    host_ip->cgid = tswapal(target_ip->cgid);
2461
    host_ip->mode = tswap16(target_ip->mode);
2462
    unlock_user_struct(target_sd, target_addr, 0);
2463
    return 0;
2464
}
2465

    
2466
static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
2467
                                               struct ipc_perm *host_ip)
2468
{
2469
    struct target_ipc_perm *target_ip;
2470
    struct target_semid_ds *target_sd;
2471

    
2472
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2473
        return -TARGET_EFAULT;
2474
    target_ip = &(target_sd->sem_perm);
2475
    target_ip->__key = tswapal(host_ip->__key);
2476
    target_ip->uid = tswapal(host_ip->uid);
2477
    target_ip->gid = tswapal(host_ip->gid);
2478
    target_ip->cuid = tswapal(host_ip->cuid);
2479
    target_ip->cgid = tswapal(host_ip->cgid);
2480
    target_ip->mode = tswap16(host_ip->mode);
2481
    unlock_user_struct(target_sd, target_addr, 1);
2482
    return 0;
2483
}
2484

    
2485
static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
2486
                                               abi_ulong target_addr)
2487
{
2488
    struct target_semid_ds *target_sd;
2489

    
2490
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2491
        return -TARGET_EFAULT;
2492
    if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr))
2493
        return -TARGET_EFAULT;
2494
    host_sd->sem_nsems = tswapal(target_sd->sem_nsems);
2495
    host_sd->sem_otime = tswapal(target_sd->sem_otime);
2496
    host_sd->sem_ctime = tswapal(target_sd->sem_ctime);
2497
    unlock_user_struct(target_sd, target_addr, 0);
2498
    return 0;
2499
}
2500

    
2501
static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
2502
                                               struct semid_ds *host_sd)
2503
{
2504
    struct target_semid_ds *target_sd;
2505

    
2506
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2507
        return -TARGET_EFAULT;
2508
    if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
2509
        return -TARGET_EFAULT;
2510
    target_sd->sem_nsems = tswapal(host_sd->sem_nsems);
2511
    target_sd->sem_otime = tswapal(host_sd->sem_otime);
2512
    target_sd->sem_ctime = tswapal(host_sd->sem_ctime);
2513
    unlock_user_struct(target_sd, target_addr, 1);
2514
    return 0;
2515
}
2516

    
2517
struct target_seminfo {
2518
    int semmap;
2519
    int semmni;
2520
    int semmns;
2521
    int semmnu;
2522
    int semmsl;
2523
    int semopm;
2524
    int semume;
2525
    int semusz;
2526
    int semvmx;
2527
    int semaem;
2528
};
2529

    
2530
static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
2531
                                              struct seminfo *host_seminfo)
2532
{
2533
    struct target_seminfo *target_seminfo;
2534
    if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
2535
        return -TARGET_EFAULT;
2536
    __put_user(host_seminfo->semmap, &target_seminfo->semmap);
2537
    __put_user(host_seminfo->semmni, &target_seminfo->semmni);
2538
    __put_user(host_seminfo->semmns, &target_seminfo->semmns);
2539
    __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
2540
    __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
2541
    __put_user(host_seminfo->semopm, &target_seminfo->semopm);
2542
    __put_user(host_seminfo->semume, &target_seminfo->semume);
2543
    __put_user(host_seminfo->semusz, &target_seminfo->semusz);
2544
    __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
2545
    __put_user(host_seminfo->semaem, &target_seminfo->semaem);
2546
    unlock_user_struct(target_seminfo, target_addr, 1);
2547
    return 0;
2548
}
2549

    
2550
union semun {
2551
        int val;
2552
        struct semid_ds *buf;
2553
        unsigned short *array;
2554
        struct seminfo *__buf;
2555
};
2556

    
2557
union target_semun {
2558
        int val;
2559
        abi_ulong buf;
2560
        abi_ulong array;
2561
        abi_ulong __buf;
2562
};
2563

    
2564
static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
2565
                                               abi_ulong target_addr)
2566
{
2567
    int nsems;
2568
    unsigned short *array;
2569
    union semun semun;
2570
    struct semid_ds semid_ds;
2571
    int i, ret;
2572

    
2573
    semun.buf = &semid_ds;
2574

    
2575
    ret = semctl(semid, 0, IPC_STAT, semun);
2576
    if (ret == -1)
2577
        return get_errno(ret);
2578

    
2579
    nsems = semid_ds.sem_nsems;
2580

    
2581
    *host_array = malloc(nsems*sizeof(unsigned short));
2582
    array = lock_user(VERIFY_READ, target_addr,
2583
                      nsems*sizeof(unsigned short), 1);
2584
    if (!array)
2585
        return -TARGET_EFAULT;
2586

    
2587
    for(i=0; i<nsems; i++) {
2588
        __get_user((*host_array)[i], &array[i]);
2589
    }
2590
    unlock_user(array, target_addr, 0);
2591

    
2592
    return 0;
2593
}
2594

    
2595
static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
2596
                                               unsigned short **host_array)
2597
{
2598
    int nsems;
2599
    unsigned short *array;
2600
    union semun semun;
2601
    struct semid_ds semid_ds;
2602
    int i, ret;
2603

    
2604
    semun.buf = &semid_ds;
2605

    
2606
    ret = semctl(semid, 0, IPC_STAT, semun);
2607
    if (ret == -1)
2608
        return get_errno(ret);
2609

    
2610
    nsems = semid_ds.sem_nsems;
2611

    
2612
    array = lock_user(VERIFY_WRITE, target_addr,
2613
                      nsems*sizeof(unsigned short), 0);
2614
    if (!array)
2615
        return -TARGET_EFAULT;
2616

    
2617
    for(i=0; i<nsems; i++) {
2618
        __put_user((*host_array)[i], &array[i]);
2619
    }
2620
    free(*host_array);
2621
    unlock_user(array, target_addr, 1);
2622

    
2623
    return 0;
2624
}
2625

    
2626
static inline abi_long do_semctl(int semid, int semnum, int cmd,
2627
                                 union target_semun target_su)
2628
{
2629
    union semun arg;
2630
    struct semid_ds dsarg;
2631
    unsigned short *array = NULL;
2632
    struct seminfo seminfo;
2633
    abi_long ret = -TARGET_EINVAL;
2634
    abi_long err;
2635
    cmd &= 0xff;
2636

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

    
2683
    return ret;
2684
}
2685

    
2686
struct target_sembuf {
2687
    unsigned short sem_num;
2688
    short sem_op;
2689
    short sem_flg;
2690
};
2691

    
2692
static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
2693
                                             abi_ulong target_addr,
2694
                                             unsigned nsops)
2695
{
2696
    struct target_sembuf *target_sembuf;
2697
    int i;
2698

    
2699
    target_sembuf = lock_user(VERIFY_READ, target_addr,
2700
                              nsops*sizeof(struct target_sembuf), 1);
2701
    if (!target_sembuf)
2702
        return -TARGET_EFAULT;
2703

    
2704
    for(i=0; i<nsops; i++) {
2705
        __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
2706
        __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
2707
        __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
2708
    }
2709

    
2710
    unlock_user(target_sembuf, target_addr, 0);
2711

    
2712
    return 0;
2713
}
2714

    
2715
static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
2716
{
2717
    struct sembuf sops[nsops];
2718

    
2719
    if (target_to_host_sembuf(sops, ptr, nsops))
2720
        return -TARGET_EFAULT;
2721

    
2722
    return get_errno(semop(semid, sops, nsops));
2723
}
2724

    
2725
struct target_msqid_ds
2726
{
2727
    struct target_ipc_perm msg_perm;
2728
    abi_ulong msg_stime;
2729
#if TARGET_ABI_BITS == 32
2730
    abi_ulong __unused1;
2731
#endif
2732
    abi_ulong msg_rtime;
2733
#if TARGET_ABI_BITS == 32
2734
    abi_ulong __unused2;
2735
#endif
2736
    abi_ulong msg_ctime;
2737
#if TARGET_ABI_BITS == 32
2738
    abi_ulong __unused3;
2739
#endif
2740
    abi_ulong __msg_cbytes;
2741
    abi_ulong msg_qnum;
2742
    abi_ulong msg_qbytes;
2743
    abi_ulong msg_lspid;
2744
    abi_ulong msg_lrpid;
2745
    abi_ulong __unused4;
2746
    abi_ulong __unused5;
2747
};
2748

    
2749
static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
2750
                                               abi_ulong target_addr)
2751
{
2752
    struct target_msqid_ds *target_md;
2753

    
2754
    if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
2755
        return -TARGET_EFAULT;
2756
    if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
2757
        return -TARGET_EFAULT;
2758
    host_md->msg_stime = tswapal(target_md->msg_stime);
2759
    host_md->msg_rtime = tswapal(target_md->msg_rtime);
2760
    host_md->msg_ctime = tswapal(target_md->msg_ctime);
2761
    host_md->__msg_cbytes = tswapal(target_md->__msg_cbytes);
2762
    host_md->msg_qnum = tswapal(target_md->msg_qnum);
2763
    host_md->msg_qbytes = tswapal(target_md->msg_qbytes);
2764
    host_md->msg_lspid = tswapal(target_md->msg_lspid);
2765
    host_md->msg_lrpid = tswapal(target_md->msg_lrpid);
2766
    unlock_user_struct(target_md, target_addr, 0);
2767
    return 0;
2768
}
2769

    
2770
static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
2771
                                               struct msqid_ds *host_md)
2772
{
2773
    struct target_msqid_ds *target_md;
2774

    
2775
    if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
2776
        return -TARGET_EFAULT;
2777
    if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
2778
        return -TARGET_EFAULT;
2779
    target_md->msg_stime = tswapal(host_md->msg_stime);
2780
    target_md->msg_rtime = tswapal(host_md->msg_rtime);
2781
    target_md->msg_ctime = tswapal(host_md->msg_ctime);
2782
    target_md->__msg_cbytes = tswapal(host_md->__msg_cbytes);
2783
    target_md->msg_qnum = tswapal(host_md->msg_qnum);
2784
    target_md->msg_qbytes = tswapal(host_md->msg_qbytes);
2785
    target_md->msg_lspid = tswapal(host_md->msg_lspid);
2786
    target_md->msg_lrpid = tswapal(host_md->msg_lrpid);
2787
    unlock_user_struct(target_md, target_addr, 1);
2788
    return 0;
2789
}
2790

    
2791
struct target_msginfo {
2792
    int msgpool;
2793
    int msgmap;
2794
    int msgmax;
2795
    int msgmnb;
2796
    int msgmni;
2797
    int msgssz;
2798
    int msgtql;
2799
    unsigned short int msgseg;
2800
};
2801

    
2802
static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
2803
                                              struct msginfo *host_msginfo)
2804
{
2805
    struct target_msginfo *target_msginfo;
2806
    if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
2807
        return -TARGET_EFAULT;
2808
    __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
2809
    __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
2810
    __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
2811
    __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
2812
    __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
2813
    __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
2814
    __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
2815
    __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
2816
    unlock_user_struct(target_msginfo, target_addr, 1);
2817
    return 0;
2818
}
2819

    
2820
static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
2821
{
2822
    struct msqid_ds dsarg;
2823
    struct msginfo msginfo;
2824
    abi_long ret = -TARGET_EINVAL;
2825

    
2826
    cmd &= 0xff;
2827

    
2828
    switch (cmd) {
2829
    case IPC_STAT:
2830
    case IPC_SET:
2831
    case MSG_STAT:
2832
        if (target_to_host_msqid_ds(&dsarg,ptr))
2833
            return -TARGET_EFAULT;
2834
        ret = get_errno(msgctl(msgid, cmd, &dsarg));
2835
        if (host_to_target_msqid_ds(ptr,&dsarg))
2836
            return -TARGET_EFAULT;
2837
        break;
2838
    case IPC_RMID:
2839
        ret = get_errno(msgctl(msgid, cmd, NULL));
2840
        break;
2841
    case IPC_INFO:
2842
    case MSG_INFO:
2843
        ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
2844
        if (host_to_target_msginfo(ptr, &msginfo))
2845
            return -TARGET_EFAULT;
2846
        break;
2847
    }
2848

    
2849
    return ret;
2850
}
2851

    
2852
struct target_msgbuf {
2853
    abi_long mtype;
2854
    char        mtext[1];
2855
};
2856

    
2857
static inline abi_long do_msgsnd(int msqid, abi_long msgp,
2858
                                 unsigned int msgsz, int msgflg)
2859
{
2860
    struct target_msgbuf *target_mb;
2861
    struct msgbuf *host_mb;
2862
    abi_long ret = 0;
2863

    
2864
    if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
2865
        return -TARGET_EFAULT;
2866
    host_mb = malloc(msgsz+sizeof(long));
2867
    host_mb->mtype = (abi_long) tswapal(target_mb->mtype);
2868
    memcpy(host_mb->mtext, target_mb->mtext, msgsz);
2869
    ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
2870
    free(host_mb);
2871
    unlock_user_struct(target_mb, msgp, 0);
2872

    
2873
    return ret;
2874
}
2875

    
2876
static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2877
                                 unsigned int msgsz, abi_long msgtyp,
2878
                                 int msgflg)
2879
{
2880
    struct target_msgbuf *target_mb;
2881
    char *target_mtext;
2882
    struct msgbuf *host_mb;
2883
    abi_long ret = 0;
2884

    
2885
    if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2886
        return -TARGET_EFAULT;
2887

    
2888
    host_mb = g_malloc(msgsz+sizeof(long));
2889
    ret = get_errno(msgrcv(msqid, host_mb, msgsz, msgtyp, msgflg));
2890

    
2891
    if (ret > 0) {
2892
        abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2893
        target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2894
        if (!target_mtext) {
2895
            ret = -TARGET_EFAULT;
2896
            goto end;
2897
        }
2898
        memcpy(target_mb->mtext, host_mb->mtext, ret);
2899
        unlock_user(target_mtext, target_mtext_addr, ret);
2900
    }
2901

    
2902
    target_mb->mtype = tswapal(host_mb->mtype);
2903

    
2904
end:
2905
    if (target_mb)
2906
        unlock_user_struct(target_mb, msgp, 1);
2907
    g_free(host_mb);
2908
    return ret;
2909
}
2910

    
2911
struct target_shmid_ds
2912
{
2913
    struct target_ipc_perm shm_perm;
2914
    abi_ulong shm_segsz;
2915
    abi_ulong shm_atime;
2916
#if TARGET_ABI_BITS == 32
2917
    abi_ulong __unused1;
2918
#endif
2919
    abi_ulong shm_dtime;
2920
#if TARGET_ABI_BITS == 32
2921
    abi_ulong __unused2;
2922
#endif
2923
    abi_ulong shm_ctime;
2924
#if TARGET_ABI_BITS == 32
2925
    abi_ulong __unused3;
2926
#endif
2927
    int shm_cpid;
2928
    int shm_lpid;
2929
    abi_ulong shm_nattch;
2930
    unsigned long int __unused4;
2931
    unsigned long int __unused5;
2932
};
2933

    
2934
static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
2935
                                               abi_ulong target_addr)
2936
{
2937
    struct target_shmid_ds *target_sd;
2938

    
2939
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2940
        return -TARGET_EFAULT;
2941
    if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr))
2942
        return -TARGET_EFAULT;
2943
    __get_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2944
    __get_user(host_sd->shm_atime, &target_sd->shm_atime);
2945
    __get_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2946
    __get_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2947
    __get_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2948
    __get_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2949
    __get_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2950
    unlock_user_struct(target_sd, target_addr, 0);
2951
    return 0;
2952
}
2953

    
2954
static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
2955
                                               struct shmid_ds *host_sd)
2956
{
2957
    struct target_shmid_ds *target_sd;
2958

    
2959
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2960
        return -TARGET_EFAULT;
2961
    if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm)))
2962
        return -TARGET_EFAULT;
2963
    __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2964
    __put_user(host_sd->shm_atime, &target_sd->shm_atime);
2965
    __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2966
    __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2967
    __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2968
    __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2969
    __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2970
    unlock_user_struct(target_sd, target_addr, 1);
2971
    return 0;
2972
}
2973

    
2974
struct  target_shminfo {
2975
    abi_ulong shmmax;
2976
    abi_ulong shmmin;
2977
    abi_ulong shmmni;
2978
    abi_ulong shmseg;
2979
    abi_ulong shmall;
2980
};
2981

    
2982
static inline abi_long host_to_target_shminfo(abi_ulong target_addr,
2983
                                              struct shminfo *host_shminfo)
2984
{
2985
    struct target_shminfo *target_shminfo;
2986
    if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0))
2987
        return -TARGET_EFAULT;
2988
    __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
2989
    __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
2990
    __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
2991
    __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
2992
    __put_user(host_shminfo->shmall, &target_shminfo->shmall);
2993
    unlock_user_struct(target_shminfo, target_addr, 1);
2994
    return 0;
2995
}
2996

    
2997
struct target_shm_info {
2998
    int used_ids;
2999
    abi_ulong shm_tot;
3000
    abi_ulong shm_rss;
3001
    abi_ulong shm_swp;
3002
    abi_ulong swap_attempts;
3003
    abi_ulong swap_successes;
3004
};
3005

    
3006
static inline abi_long host_to_target_shm_info(abi_ulong target_addr,
3007
                                               struct shm_info *host_shm_info)
3008
{
3009
    struct target_shm_info *target_shm_info;
3010
    if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0))
3011
        return -TARGET_EFAULT;
3012
    __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
3013
    __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
3014
    __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
3015
    __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
3016
    __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts);
3017
    __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes);
3018
    unlock_user_struct(target_shm_info, target_addr, 1);
3019
    return 0;
3020
}
3021

    
3022
static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
3023
{
3024
    struct shmid_ds dsarg;
3025
    struct shminfo shminfo;
3026
    struct shm_info shm_info;
3027
    abi_long ret = -TARGET_EINVAL;
3028

    
3029
    cmd &= 0xff;
3030

    
3031
    switch(cmd) {
3032
    case IPC_STAT:
3033
    case IPC_SET:
3034
    case SHM_STAT:
3035
        if (target_to_host_shmid_ds(&dsarg, buf))
3036
            return -TARGET_EFAULT;
3037
        ret = get_errno(shmctl(shmid, cmd, &dsarg));
3038
        if (host_to_target_shmid_ds(buf, &dsarg))
3039
            return -TARGET_EFAULT;
3040
        break;
3041
    case IPC_INFO:
3042
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
3043
        if (host_to_target_shminfo(buf, &shminfo))
3044
            return -TARGET_EFAULT;
3045
        break;
3046
    case SHM_INFO:
3047
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
3048
        if (host_to_target_shm_info(buf, &shm_info))
3049
            return -TARGET_EFAULT;
3050
        break;
3051
    case IPC_RMID:
3052
    case SHM_LOCK:
3053
    case SHM_UNLOCK:
3054
        ret = get_errno(shmctl(shmid, cmd, NULL));
3055
        break;
3056
    }
3057

    
3058
    return ret;
3059
}
3060

    
3061
static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
3062
{
3063
    abi_long raddr;
3064
    void *host_raddr;
3065
    struct shmid_ds shm_info;
3066
    int i,ret;
3067

    
3068
    /* find out the length of the shared memory segment */
3069
    ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
3070
    if (is_error(ret)) {
3071
        /* can't get length, bail out */
3072
        return ret;
3073
    }
3074

    
3075
    mmap_lock();
3076

    
3077
    if (shmaddr)
3078
        host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
3079
    else {
3080
        abi_ulong mmap_start;
3081

    
3082
        mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
3083

    
3084
        if (mmap_start == -1) {
3085
            errno = ENOMEM;
3086
            host_raddr = (void *)-1;
3087
        } else
3088
            host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);
3089
    }
3090

    
3091
    if (host_raddr == (void *)-1) {
3092
        mmap_unlock();
3093
        return get_errno((long)host_raddr);
3094
    }
3095
    raddr=h2g((unsigned long)host_raddr);
3096

    
3097
    page_set_flags(raddr, raddr + shm_info.shm_segsz,
3098
                   PAGE_VALID | PAGE_READ |
3099
                   ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
3100

    
3101
    for (i = 0; i < N_SHM_REGIONS; i++) {
3102
        if (shm_regions[i].start == 0) {
3103
            shm_regions[i].start = raddr;
3104
            shm_regions[i].size = shm_info.shm_segsz;
3105
            break;
3106
        }
3107
    }
3108

    
3109
    mmap_unlock();
3110
    return raddr;
3111

    
3112
}
3113

    
3114
static inline abi_long do_shmdt(abi_ulong shmaddr)
3115
{
3116
    int i;
3117

    
3118
    for (i = 0; i < N_SHM_REGIONS; ++i) {
3119
        if (shm_regions[i].start == shmaddr) {
3120
            shm_regions[i].start = 0;
3121
            page_set_flags(shmaddr, shmaddr + shm_regions[i].size, 0);
3122
            break;
3123
        }
3124
    }
3125

    
3126
    return get_errno(shmdt(g2h(shmaddr)));
3127
}
3128

    
3129
#ifdef TARGET_NR_ipc
3130
/* ??? This only works with linear mappings.  */
3131
/* do_ipc() must return target values and target errnos. */
3132
static abi_long do_ipc(unsigned int call, int first,
3133
                       int second, int third,
3134
                       abi_long ptr, abi_long fifth)
3135
{
3136
    int version;
3137
    abi_long ret = 0;
3138

    
3139
    version = call >> 16;
3140
    call &= 0xffff;
3141

    
3142
    switch (call) {
3143
    case IPCOP_semop:
3144
        ret = do_semop(first, ptr, second);
3145
        break;
3146

    
3147
    case IPCOP_semget:
3148
        ret = get_errno(semget(first, second, third));
3149
        break;
3150

    
3151
    case IPCOP_semctl:
3152
        ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr);
3153
        break;
3154

    
3155
    case IPCOP_msgget:
3156
        ret = get_errno(msgget(first, second));
3157
        break;
3158

    
3159
    case IPCOP_msgsnd:
3160
        ret = do_msgsnd(first, ptr, second, third);
3161
        break;
3162

    
3163
    case IPCOP_msgctl:
3164
        ret = do_msgctl(first, second, ptr);
3165
        break;
3166

    
3167
    case IPCOP_msgrcv:
3168
        switch (version) {
3169
        case 0:
3170
            {
3171
                struct target_ipc_kludge {
3172
                    abi_long msgp;
3173
                    abi_long msgtyp;
3174
                } *tmp;
3175

    
3176
                if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
3177
                    ret = -TARGET_EFAULT;
3178
                    break;
3179
                }
3180

    
3181
                ret = do_msgrcv(first, tswapal(tmp->msgp), second, tswapal(tmp->msgtyp), third);
3182

    
3183
                unlock_user_struct(tmp, ptr, 0);
3184
                break;
3185
            }
3186
        default:
3187
            ret = do_msgrcv(first, ptr, second, fifth, third);
3188
        }
3189
        break;
3190

    
3191
    case IPCOP_shmat:
3192
        switch (version) {
3193
        default:
3194
        {
3195
            abi_ulong raddr;
3196
            raddr = do_shmat(first, ptr, second);
3197
            if (is_error(raddr))
3198
                return get_errno(raddr);
3199
            if (put_user_ual(raddr, third))
3200
                return -TARGET_EFAULT;
3201
            break;
3202
        }
3203
        case 1:
3204
            ret = -TARGET_EINVAL;
3205
            break;
3206
        }
3207
        break;
3208
    case IPCOP_shmdt:
3209
        ret = do_shmdt(ptr);
3210
        break;
3211

    
3212
    case IPCOP_shmget:
3213
        /* IPC_* flag values are the same on all linux platforms */
3214
        ret = get_errno(shmget(first, second, third));
3215
        break;
3216

    
3217
        /* IPC_* and SHM_* command values are the same on all linux platforms */
3218
    case IPCOP_shmctl:
3219
        ret = do_shmctl(first, second, third);
3220
        break;
3221
    default:
3222
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
3223
        ret = -TARGET_ENOSYS;
3224
        break;
3225
    }
3226
    return ret;
3227
}
3228
#endif
3229

    
3230
/* kernel structure types definitions */
3231

    
3232
#define STRUCT(name, ...) STRUCT_ ## name,
3233
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
3234
enum {
3235
#include "syscall_types.h"
3236
};
3237
#undef STRUCT
3238
#undef STRUCT_SPECIAL
3239

    
3240
#define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = {  __VA_ARGS__, TYPE_NULL };
3241
#define STRUCT_SPECIAL(name)
3242
#include "syscall_types.h"
3243
#undef STRUCT
3244
#undef STRUCT_SPECIAL
3245

    
3246
typedef struct IOCTLEntry IOCTLEntry;
3247

    
3248
typedef abi_long do_ioctl_fn(const IOCTLEntry *ie, uint8_t *buf_temp,
3249
                             int fd, abi_long cmd, abi_long arg);
3250

    
3251
struct IOCTLEntry {
3252
    unsigned int target_cmd;
3253
    unsigned int host_cmd;
3254
    const char *name;
3255
    int access;
3256
    do_ioctl_fn *do_ioctl;
3257
    const argtype arg_type[5];
3258
};
3259

    
3260
#define IOC_R 0x0001
3261
#define IOC_W 0x0002
3262
#define IOC_RW (IOC_R | IOC_W)
3263

    
3264
#define MAX_STRUCT_SIZE 4096
3265

    
3266
#ifdef CONFIG_FIEMAP
3267
/* So fiemap access checks don't overflow on 32 bit systems.
3268
 * This is very slightly smaller than the limit imposed by
3269
 * the underlying kernel.
3270
 */
3271
#define FIEMAP_MAX_EXTENTS ((UINT_MAX - sizeof(struct fiemap))  \
3272
                            / sizeof(struct fiemap_extent))
3273

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

    
3292
    assert(arg_type[0] == TYPE_PTR);
3293
    assert(ie->access == IOC_RW);
3294
    arg_type++;
3295
    target_size_in = thunk_type_size(arg_type, 0);
3296
    argptr = lock_user(VERIFY_READ, arg, target_size_in, 1);
3297
    if (!argptr) {
3298
        return -TARGET_EFAULT;
3299
    }
3300
    thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3301
    unlock_user(argptr, arg, 0);
3302
    fm = (struct fiemap *)buf_temp;
3303
    if (fm->fm_extent_count > FIEMAP_MAX_EXTENTS) {
3304
        return -TARGET_EINVAL;
3305
    }
3306

    
3307
    outbufsz = sizeof (*fm) +
3308
        (sizeof(struct fiemap_extent) * fm->fm_extent_count);
3309

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

    
3355
static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp,
3356
                                int fd, abi_long cmd, abi_long arg)
3357
{
3358
    const argtype *arg_type = ie->arg_type;
3359
    int target_size;
3360
    void *argptr;
3361
    int ret;
3362
    struct ifconf *host_ifconf;
3363
    uint32_t outbufsz;
3364
    const argtype ifreq_arg_type[] = { MK_STRUCT(STRUCT_sockaddr_ifreq) };
3365
    int target_ifreq_size;
3366
    int nb_ifreq;
3367
    int free_buf = 0;
3368
    int i;
3369
    int target_ifc_len;
3370
    abi_long target_ifc_buf;
3371
    int host_ifc_len;
3372
    char *host_ifc_buf;
3373

    
3374
    assert(arg_type[0] == TYPE_PTR);
3375
    assert(ie->access == IOC_RW);
3376

    
3377
    arg_type++;
3378
    target_size = thunk_type_size(arg_type, 0);
3379

    
3380
    argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3381
    if (!argptr)
3382
        return -TARGET_EFAULT;
3383
    thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3384
    unlock_user(argptr, arg, 0);
3385

    
3386
    host_ifconf = (struct ifconf *)(unsigned long)buf_temp;
3387
    target_ifc_len = host_ifconf->ifc_len;
3388
    target_ifc_buf = (abi_long)(unsigned long)host_ifconf->ifc_buf;
3389

    
3390
    target_ifreq_size = thunk_type_size(ifreq_arg_type, 0);
3391
    nb_ifreq = target_ifc_len / target_ifreq_size;
3392
    host_ifc_len = nb_ifreq * sizeof(struct ifreq);
3393

    
3394
    outbufsz = sizeof(*host_ifconf) + host_ifc_len;
3395
    if (outbufsz > MAX_STRUCT_SIZE) {
3396
        /* We can't fit all the extents into the fixed size buffer.
3397
         * Allocate one that is large enough and use it instead.
3398
         */
3399
        host_ifconf = malloc(outbufsz);
3400
        if (!host_ifconf) {
3401
            return -TARGET_ENOMEM;
3402
        }
3403
        memcpy(host_ifconf, buf_temp, sizeof(*host_ifconf));
3404
        free_buf = 1;
3405
    }
3406
    host_ifc_buf = (char*)host_ifconf + sizeof(*host_ifconf);
3407

    
3408
    host_ifconf->ifc_len = host_ifc_len;
3409
    host_ifconf->ifc_buf = host_ifc_buf;
3410

    
3411
    ret = get_errno(ioctl(fd, ie->host_cmd, host_ifconf));
3412
    if (!is_error(ret)) {
3413
        /* convert host ifc_len to target ifc_len */
3414

    
3415
        nb_ifreq = host_ifconf->ifc_len / sizeof(struct ifreq);
3416
        target_ifc_len = nb_ifreq * target_ifreq_size;
3417
        host_ifconf->ifc_len = target_ifc_len;
3418

    
3419
        /* restore target ifc_buf */
3420

    
3421
        host_ifconf->ifc_buf = (char *)(unsigned long)target_ifc_buf;
3422

    
3423
        /* copy struct ifconf to target user */
3424

    
3425
        argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3426
        if (!argptr)
3427
            return -TARGET_EFAULT;
3428
        thunk_convert(argptr, host_ifconf, arg_type, THUNK_TARGET);
3429
        unlock_user(argptr, arg, target_size);
3430

    
3431
        /* copy ifreq[] to target user */
3432

    
3433
        argptr = lock_user(VERIFY_WRITE, target_ifc_buf, target_ifc_len, 0);
3434
        for (i = 0; i < nb_ifreq ; i++) {
3435
            thunk_convert(argptr + i * target_ifreq_size,
3436
                          host_ifc_buf + i * sizeof(struct ifreq),
3437
                          ifreq_arg_type, THUNK_TARGET);
3438
        }
3439
        unlock_user(argptr, target_ifc_buf, target_ifc_len);
3440
    }
3441

    
3442
    if (free_buf) {
3443
        free(host_ifconf);
3444
    }
3445

    
3446
    return ret;
3447
}
3448

    
3449
static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
3450
                            abi_long cmd, abi_long arg)
3451
{
3452
    void *argptr;
3453
    struct dm_ioctl *host_dm;
3454
    abi_long guest_data;
3455
    uint32_t guest_data_size;
3456
    int target_size;
3457
    const argtype *arg_type = ie->arg_type;
3458
    abi_long ret;
3459
    void *big_buf = NULL;
3460
    char *host_data;
3461

    
3462
    arg_type++;
3463
    target_size = thunk_type_size(arg_type, 0);
3464
    argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3465
    if (!argptr) {
3466
        ret = -TARGET_EFAULT;
3467
        goto out;
3468
    }
3469
    thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3470
    unlock_user(argptr, arg, 0);
3471

    
3472
    /* buf_temp is too small, so fetch things into a bigger buffer */
3473
    big_buf = g_malloc0(((struct dm_ioctl*)buf_temp)->data_size * 2);
3474
    memcpy(big_buf, buf_temp, target_size);
3475
    buf_temp = big_buf;
3476
    host_dm = big_buf;
3477

    
3478
    guest_data = arg + host_dm->data_start;
3479
    if ((guest_data - arg) < 0) {
3480
        ret = -EINVAL;
3481
        goto out;
3482
    }
3483
    guest_data_size = host_dm->data_size - host_dm->data_start;
3484
    host_data = (char*)host_dm + host_dm->data_start;
3485

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

    
3518
        for (i = 0; i < host_dm->target_count; i++) {
3519
            struct dm_target_spec *spec = cur_data;
3520
            uint32_t next;
3521
            int slen;
3522

    
3523
            thunk_convert(spec, gspec, arg_type, THUNK_HOST);
3524
            slen = strlen((char*)gspec + spec_size) + 1;
3525
            next = spec->next;
3526
            spec->next = sizeof(*spec) + slen;
3527
            strcpy((char*)&spec[1], gspec + spec_size);
3528
            gspec += next;
3529
            cur_data += spec->next;
3530
        }
3531
        break;
3532
    }
3533
    default:
3534
        ret = -TARGET_EINVAL;
3535
        goto out;
3536
    }
3537
    unlock_user(argptr, guest_data, 0);
3538

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

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

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

    
3617
            *(uint32_t*)argptr = tswap32(count);
3618
            for (i = 0; i < count; i++) {
3619
                *gdev = tswap64(*hdev);
3620
                gdev++;
3621
                hdev++;
3622
            }
3623
            break;
3624
        }
3625
        case DM_LIST_VERSIONS:
3626
        {
3627
            struct dm_target_versions *vers = (void*)host_dm + host_dm->data_start;
3628
            uint32_t remaining_data = guest_data_size;
3629
            void *cur_data = argptr;
3630
            const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_versions) };
3631
            int vers_size = thunk_type_size(arg_type, 0);
3632

    
3633
            while (1) {
3634
                uint32_t next = vers->next;
3635
                if (next) {
3636
                    vers->next = vers_size + (strlen(vers->name) + 1);
3637
                }
3638
                if (remaining_data < vers->next) {
3639
                    host_dm->flags |= DM_BUFFER_FULL_FLAG;
3640
                    break;
3641
                }
3642
                thunk_convert(cur_data, vers, arg_type, THUNK_TARGET);
3643
                strcpy(cur_data + vers_size, vers->name);
3644
                cur_data += vers->next;
3645
                remaining_data -= vers->next;
3646
                if (!next) {
3647
                    break;
3648
                }
3649
                vers = (void*)vers + next;
3650
            }
3651
            break;
3652
        }
3653
        default:
3654
            ret = -TARGET_EINVAL;
3655
            goto out;
3656
        }
3657
        unlock_user(argptr, guest_data, guest_data_size);
3658

    
3659
        argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3660
        if (!argptr) {
3661
            ret = -TARGET_EFAULT;
3662
            goto out;
3663
        }
3664
        thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
3665
        unlock_user(argptr, arg, target_size);
3666
    }
3667
out:
3668
    g_free(big_buf);
3669
    return ret;
3670
}
3671

    
3672
static abi_long do_ioctl_rt(const IOCTLEntry *ie, uint8_t *buf_temp,
3673
                                int fd, abi_long cmd, abi_long arg)
3674
{
3675
    const argtype *arg_type = ie->arg_type;
3676
    const StructEntry *se;
3677
    const argtype *field_types;
3678
    const int *dst_offsets, *src_offsets;
3679
    int target_size;
3680
    void *argptr;
3681
    abi_ulong *target_rt_dev_ptr;
3682
    unsigned long *host_rt_dev_ptr;
3683
    abi_long ret;
3684
    int i;
3685

    
3686
    assert(ie->access == IOC_W);
3687
    assert(*arg_type == TYPE_PTR);
3688
    arg_type++;
3689
    assert(*arg_type == TYPE_STRUCT);
3690
    target_size = thunk_type_size(arg_type, 0);
3691
    argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3692
    if (!argptr) {
3693
        return -TARGET_EFAULT;
3694
    }
3695
    arg_type++;
3696
    assert(*arg_type == (int)STRUCT_rtentry);
3697
    se = struct_entries + *arg_type++;
3698
    assert(se->convert[0] == NULL);
3699
    /* convert struct here to be able to catch rt_dev string */
3700
    field_types = se->field_types;
3701
    dst_offsets = se->field_offsets[THUNK_HOST];
3702
    src_offsets = se->field_offsets[THUNK_TARGET];
3703
    for (i = 0; i < se->nb_fields; i++) {
3704
        if (dst_offsets[i] == offsetof(struct rtentry, rt_dev)) {
3705
            assert(*field_types == TYPE_PTRVOID);
3706
            target_rt_dev_ptr = (abi_ulong *)(argptr + src_offsets[i]);
3707
            host_rt_dev_ptr = (unsigned long *)(buf_temp + dst_offsets[i]);
3708
            if (*target_rt_dev_ptr != 0) {
3709
                *host_rt_dev_ptr = (unsigned long)lock_user_string(
3710
                                                  tswapal(*target_rt_dev_ptr));
3711
                if (!*host_rt_dev_ptr) {
3712
                    unlock_user(argptr, arg, 0);
3713
                    return -TARGET_EFAULT;
3714
                }
3715
            } else {
3716
                *host_rt_dev_ptr = 0;
3717
            }
3718
            field_types++;
3719
            continue;
3720
        }
3721
        field_types = thunk_convert(buf_temp + dst_offsets[i],
3722
                                    argptr + src_offsets[i],
3723
                                    field_types, THUNK_HOST);
3724
    }
3725
    unlock_user(argptr, arg, 0);
3726

    
3727
    ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3728
    if (*host_rt_dev_ptr != 0) {
3729
        unlock_user((void *)*host_rt_dev_ptr,
3730
                    *target_rt_dev_ptr, 0);
3731
    }
3732
    return ret;
3733
}
3734

    
3735
static IOCTLEntry ioctl_entries[] = {
3736
#define IOCTL(cmd, access, ...) \
3737
    { TARGET_ ## cmd, cmd, #cmd, access, 0, {  __VA_ARGS__ } },
3738
#define IOCTL_SPECIAL(cmd, access, dofn, ...)                      \
3739
    { TARGET_ ## cmd, cmd, #cmd, access, dofn, {  __VA_ARGS__ } },
3740
#include "ioctls.h"
3741
    { 0, 0, },
3742
};
3743

    
3744
/* ??? Implement proper locking for ioctls.  */
3745
/* do_ioctl() Must return target values and target errnos. */
3746
static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
3747
{
3748
    const IOCTLEntry *ie;
3749
    const argtype *arg_type;
3750
    abi_long ret;
3751
    uint8_t buf_temp[MAX_STRUCT_SIZE];
3752
    int target_size;
3753
    void *argptr;
3754

    
3755
    ie = ioctl_entries;
3756
    for(;;) {
3757
        if (ie->target_cmd == 0) {
3758
            gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
3759
            return -TARGET_ENOSYS;
3760
        }
3761
        if (ie->target_cmd == cmd)
3762
            break;
3763
        ie++;
3764
    }
3765
    arg_type = ie->arg_type;
3766
#if defined(DEBUG)
3767
    gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
3768
#endif
3769
    if (ie->do_ioctl) {
3770
        return ie->do_ioctl(ie, buf_temp, fd, cmd, arg);
3771
    }
3772

    
3773
    switch(arg_type[0]) {
3774
    case TYPE_NULL:
3775
        /* no argument */
3776
        ret = get_errno(ioctl(fd, ie->host_cmd));
3777
        break;
3778
    case TYPE_PTRVOID:
3779
    case TYPE_INT:
3780
        /* int argment */
3781
        ret = get_errno(ioctl(fd, ie->host_cmd, arg));
3782
        break;
3783
    case TYPE_PTR:
3784
        arg_type++;
3785
        target_size = thunk_type_size(arg_type, 0);
3786
        switch(ie->access) {
3787
        case IOC_R:
3788
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3789
            if (!is_error(ret)) {
3790
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3791
                if (!argptr)
3792
                    return -TARGET_EFAULT;
3793
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
3794
                unlock_user(argptr, arg, target_size);
3795
            }
3796
            break;
3797
        case IOC_W:
3798
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3799
            if (!argptr)
3800
                return -TARGET_EFAULT;
3801
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3802
            unlock_user(argptr, arg, 0);
3803
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3804
            break;
3805
        default:
3806
        case IOC_RW:
3807
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3808
            if (!argptr)
3809
                return -TARGET_EFAULT;
3810
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3811
            unlock_user(argptr, arg, 0);
3812
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3813
            if (!is_error(ret)) {
3814
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3815
                if (!argptr)
3816
                    return -TARGET_EFAULT;
3817
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
3818
                unlock_user(argptr, arg, target_size);
3819
            }
3820
            break;
3821
        }
3822
        break;
3823
    default:
3824
        gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
3825
                 (long)cmd, arg_type[0]);
3826
        ret = -TARGET_ENOSYS;
3827
        break;
3828
    }
3829
    return ret;
3830
}
3831

    
3832
static const bitmask_transtbl iflag_tbl[] = {
3833
        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
3834
        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
3835
        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
3836
        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
3837
        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
3838
        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
3839
        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
3840
        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
3841
        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
3842
        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
3843
        { TARGET_IXON, TARGET_IXON, IXON, IXON },
3844
        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
3845
        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
3846
        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
3847
        { 0, 0, 0, 0 }
3848
};
3849

    
3850
static const bitmask_transtbl oflag_tbl[] = {
3851
        { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
3852
        { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
3853
        { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
3854
        { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
3855
        { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
3856
        { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
3857
        { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
3858
        { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
3859
        { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
3860
        { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
3861
        { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
3862
        { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
3863
        { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
3864
        { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
3865
        { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
3866
        { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
3867
        { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
3868
        { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
3869
        { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
3870
        { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
3871
        { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
3872
        { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
3873
        { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
3874
        { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
3875
        { 0, 0, 0, 0 }
3876
};
3877

    
3878
static const bitmask_transtbl cflag_tbl[] = {
3879
        { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
3880
        { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
3881
        { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
3882
        { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
3883
        { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
3884
        { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
3885
        { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
3886
        { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
3887
        { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
3888
        { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
3889
        { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
3890
        { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
3891
        { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
3892
        { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
3893
        { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
3894
        { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
3895
        { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
3896
        { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
3897
        { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
3898
        { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
3899
        { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
3900
        { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
3901
        { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
3902
        { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
3903
        { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
3904
        { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
3905
        { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
3906
        { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
3907
        { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
3908
        { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
3909
        { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
3910
        { 0, 0, 0, 0 }
3911
};
3912

    
3913
static const bitmask_transtbl lflag_tbl[] = {
3914
        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
3915
        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
3916
        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
3917
        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
3918
        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
3919
        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
3920
        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
3921
        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
3922
        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
3923
        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
3924
        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
3925
        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
3926
        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
3927
        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
3928
        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
3929
        { 0, 0, 0, 0 }
3930
};
3931

    
3932
static void target_to_host_termios (void *dst, const void *src)
3933
{
3934
    struct host_termios *host = dst;
3935
    const struct target_termios *target = src;
3936

    
3937
    host->c_iflag =
3938
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
3939
    host->c_oflag =
3940
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
3941
    host->c_cflag =
3942
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
3943
    host->c_lflag =
3944
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
3945
    host->c_line = target->c_line;
3946

    
3947
    memset(host->c_cc, 0, sizeof(host->c_cc));
3948
    host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
3949
    host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
3950
    host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
3951
    host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
3952
    host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
3953
    host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
3954
    host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
3955
    host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
3956
    host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
3957
    host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
3958
    host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
3959
    host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
3960
    host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
3961
    host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
3962
    host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
3963
    host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
3964
    host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
3965
}
3966

    
3967
static void host_to_target_termios (void *dst, const void *src)
3968
{
3969
    struct target_termios *target = dst;
3970
    const struct host_termios *host = src;
3971

    
3972
    target->c_iflag =
3973
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
3974
    target->c_oflag =
3975
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
3976
    target->c_cflag =
3977
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
3978
    target->c_lflag =
3979
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
3980
    target->c_line = host->c_line;
3981

    
3982
    memset(target->c_cc, 0, sizeof(target->c_cc));
3983
    target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
3984
    target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
3985
    target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
3986
    target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
3987
    target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
3988
    target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
3989
    target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
3990
    target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
3991
    target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
3992
    target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
3993
    target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
3994
    target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
3995
    target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
3996
    target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
3997
    target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
3998
    target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
3999
    target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
4000
}
4001

    
4002
static const StructEntry struct_termios_def = {
4003
    .convert = { host_to_target_termios, target_to_host_termios },
4004
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
4005
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
4006
};
4007

    
4008
static bitmask_transtbl mmap_flags_tbl[] = {
4009
        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
4010
        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
4011
        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
4012
        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
4013
        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
4014
        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
4015
        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
4016
        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
4017
        { 0, 0, 0, 0 }
4018
};
4019

    
4020
#if defined(TARGET_I386)
4021

    
4022
/* NOTE: there is really one LDT for all the threads */
4023
static uint8_t *ldt_table;
4024

    
4025
static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
4026
{
4027
    int size;
4028
    void *p;
4029

    
4030
    if (!ldt_table)
4031
        return 0;
4032
    size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
4033
    if (size > bytecount)
4034
        size = bytecount;
4035
    p = lock_user(VERIFY_WRITE, ptr, size, 0);
4036
    if (!p)
4037
        return -TARGET_EFAULT;
4038
    /* ??? Should this by byteswapped?  */
4039
    memcpy(p, ldt_table, size);
4040
    unlock_user(p, ptr, size);
4041
    return size;
4042
}
4043

    
4044
/* XXX: add locking support */
4045
static abi_long write_ldt(CPUX86State *env,
4046
                          abi_ulong ptr, unsigned long bytecount, int oldmode)
4047
{
4048
    struct target_modify_ldt_ldt_s ldt_info;
4049
    struct target_modify_ldt_ldt_s *target_ldt_info;
4050
    int seg_32bit, contents, read_exec_only, limit_in_pages;
4051
    int seg_not_present, useable, lm;
4052
    uint32_t *lp, entry_1, entry_2;
4053

    
4054
    if (bytecount != sizeof(ldt_info))
4055
        return -TARGET_EINVAL;
4056
    if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
4057
        return -TARGET_EFAULT;
4058
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
4059
    ldt_info.base_addr = tswapal(target_ldt_info->base_addr);
4060
    ldt_info.limit = tswap32(target_ldt_info->limit);
4061
    ldt_info.flags = tswap32(target_ldt_info->flags);
4062
    unlock_user_struct(target_ldt_info, ptr, 0);
4063

    
4064
    if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
4065
        return -TARGET_EINVAL;
4066
    seg_32bit = ldt_info.flags & 1;
4067
    contents = (ldt_info.flags >> 1) & 3;
4068
    read_exec_only = (ldt_info.flags >> 3) & 1;
4069
    limit_in_pages = (ldt_info.flags >> 4) & 1;
4070
    seg_not_present = (ldt_info.flags >> 5) & 1;
4071
    useable = (ldt_info.flags >> 6) & 1;
4072
#ifdef TARGET_ABI32
4073
    lm = 0;
4074
#else
4075
    lm = (ldt_info.flags >> 7) & 1;
4076
#endif
4077
    if (contents == 3) {
4078
        if (oldmode)
4079
            return -TARGET_EINVAL;
4080
        if (seg_not_present == 0)
4081
            return -TARGET_EINVAL;
4082
    }
4083
    /* allocate the LDT */
4084
    if (!ldt_table) {
4085
        env->ldt.base = target_mmap(0,
4086
                                    TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
4087
                                    PROT_READ|PROT_WRITE,
4088
                                    MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
4089
        if (env->ldt.base == -1)
4090
            return -TARGET_ENOMEM;
4091
        memset(g2h(env->ldt.base), 0,
4092
               TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
4093
        env->ldt.limit = 0xffff;
4094
        ldt_table = g2h(env->ldt.base);
4095
    }
4096

    
4097
    /* NOTE: same code as Linux kernel */
4098
    /* Allow LDTs to be cleared by the user. */
4099
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
4100
        if (oldmode ||
4101
            (contents == 0                &&
4102
             read_exec_only == 1        &&
4103
             seg_32bit == 0                &&
4104
             limit_in_pages == 0        &&
4105
             seg_not_present == 1        &&
4106
             useable == 0 )) {
4107
            entry_1 = 0;
4108
            entry_2 = 0;
4109
            goto install;
4110
        }
4111
    }
4112

    
4113
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
4114
        (ldt_info.limit & 0x0ffff);
4115
    entry_2 = (ldt_info.base_addr & 0xff000000) |
4116
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
4117
        (ldt_info.limit & 0xf0000) |
4118
        ((read_exec_only ^ 1) << 9) |
4119
        (contents << 10) |
4120
        ((seg_not_present ^ 1) << 15) |
4121
        (seg_32bit << 22) |
4122
        (limit_in_pages << 23) |
4123
        (lm << 21) |
4124
        0x7000;
4125
    if (!oldmode)
4126
        entry_2 |= (useable << 20);
4127

    
4128
    /* Install the new entry ...  */
4129
install:
4130
    lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
4131
    lp[0] = tswap32(entry_1);
4132
    lp[1] = tswap32(entry_2);
4133
    return 0;
4134
}
4135

    
4136
/* specific and weird i386 syscalls */
4137
static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
4138
                              unsigned long bytecount)
4139
{
4140
    abi_long ret;
4141

    
4142
    switch (func) {
4143
    case 0:
4144
        ret = read_ldt(ptr, bytecount);
4145
        break;
4146
    case 1:
4147
        ret = write_ldt(env, ptr, bytecount, 1);
4148
        break;
4149
    case 0x11:
4150
        ret = write_ldt(env, ptr, bytecount, 0);
4151
        break;
4152
    default:
4153
        ret = -TARGET_ENOSYS;
4154
        break;
4155
    }
4156
    return ret;
4157
}
4158

    
4159
#if defined(TARGET_I386) && defined(TARGET_ABI32)
4160
abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
4161
{
4162
    uint64_t *gdt_table = g2h(env->gdt.base);
4163
    struct target_modify_ldt_ldt_s ldt_info;
4164
    struct target_modify_ldt_ldt_s *target_ldt_info;
4165
    int seg_32bit, contents, read_exec_only, limit_in_pages;
4166
    int seg_not_present, useable, lm;
4167
    uint32_t *lp, entry_1, entry_2;
4168
    int i;
4169

    
4170
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
4171
    if (!target_ldt_info)
4172
        return -TARGET_EFAULT;
4173
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
4174
    ldt_info.base_addr = tswapal(target_ldt_info->base_addr);
4175
    ldt_info.limit = tswap32(target_ldt_info->limit);
4176
    ldt_info.flags = tswap32(target_ldt_info->flags);
4177
    if (ldt_info.entry_number == -1) {
4178
        for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
4179
            if (gdt_table[i] == 0) {
4180
                ldt_info.entry_number = i;
4181
                target_ldt_info->entry_number = tswap32(i);
4182
                break;
4183
            }
4184
        }
4185
    }
4186
    unlock_user_struct(target_ldt_info, ptr, 1);
4187

    
4188
    if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || 
4189
        ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
4190
           return -TARGET_EINVAL;
4191
    seg_32bit = ldt_info.flags & 1;
4192
    contents = (ldt_info.flags >> 1) & 3;
4193
    read_exec_only = (ldt_info.flags >> 3) & 1;
4194
    limit_in_pages = (ldt_info.flags >> 4) & 1;
4195
    seg_not_present = (ldt_info.flags >> 5) & 1;
4196
    useable = (ldt_info.flags >> 6) & 1;
4197
#ifdef TARGET_ABI32
4198
    lm = 0;
4199
#else
4200
    lm = (ldt_info.flags >> 7) & 1;
4201
#endif
4202

    
4203
    if (contents == 3) {
4204
        if (seg_not_present == 0)
4205
            return -TARGET_EINVAL;
4206
    }
4207

    
4208
    /* NOTE: same code as Linux kernel */
4209
    /* Allow LDTs to be cleared by the user. */
4210
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
4211
        if ((contents == 0             &&
4212
             read_exec_only == 1       &&
4213
             seg_32bit == 0            &&
4214
             limit_in_pages == 0       &&
4215
             seg_not_present == 1      &&
4216
             useable == 0 )) {
4217
            entry_1 = 0;
4218
            entry_2 = 0;
4219
            goto install;
4220
        }
4221
    }
4222

    
4223
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
4224
        (ldt_info.limit & 0x0ffff);
4225
    entry_2 = (ldt_info.base_addr & 0xff000000) |
4226
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
4227
        (ldt_info.limit & 0xf0000) |
4228
        ((read_exec_only ^ 1) << 9) |
4229
        (contents << 10) |
4230
        ((seg_not_present ^ 1) << 15) |
4231
        (seg_32bit << 22) |
4232
        (limit_in_pages << 23) |
4233
        (useable << 20) |
4234
        (lm << 21) |
4235
        0x7000;
4236

    
4237
    /* Install the new entry ...  */
4238
install:
4239
    lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
4240
    lp[0] = tswap32(entry_1);
4241
    lp[1] = tswap32(entry_2);
4242
    return 0;
4243
}
4244

    
4245
static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
4246
{
4247
    struct target_modify_ldt_ldt_s *target_ldt_info;
4248
    uint64_t *gdt_table = g2h(env->gdt.base);
4249
    uint32_t base_addr, limit, flags;
4250
    int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
4251
    int seg_not_present, useable, lm;
4252
    uint32_t *lp, entry_1, entry_2;
4253

    
4254
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
4255
    if (!target_ldt_info)
4256
        return -TARGET_EFAULT;
4257
    idx = tswap32(target_ldt_info->entry_number);
4258
    if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
4259
        idx > TARGET_GDT_ENTRY_TLS_MAX) {
4260
        unlock_user_struct(target_ldt_info, ptr, 1);
4261
        return -TARGET_EINVAL;
4262
    }
4263
    lp = (uint32_t *)(gdt_table + idx);
4264
    entry_1 = tswap32(lp[0]);
4265
    entry_2 = tswap32(lp[1]);
4266
    
4267
    read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
4268
    contents = (entry_2 >> 10) & 3;
4269
    seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
4270
    seg_32bit = (entry_2 >> 22) & 1;
4271
    limit_in_pages = (entry_2 >> 23) & 1;
4272
    useable = (entry_2 >> 20) & 1;
4273
#ifdef TARGET_ABI32
4274
    lm = 0;
4275
#else
4276
    lm = (entry_2 >> 21) & 1;
4277
#endif
4278
    flags = (seg_32bit << 0) | (contents << 1) |
4279
        (read_exec_only << 3) | (limit_in_pages << 4) |
4280
        (seg_not_present << 5) | (useable << 6) | (lm << 7);
4281
    limit = (entry_1 & 0xffff) | (entry_2  & 0xf0000);
4282
    base_addr = (entry_1 >> 16) | 
4283
        (entry_2 & 0xff000000) | 
4284
        ((entry_2 & 0xff) << 16);
4285
    target_ldt_info->base_addr = tswapal(base_addr);
4286
    target_ldt_info->limit = tswap32(limit);
4287
    target_ldt_info->flags = tswap32(flags);
4288
    unlock_user_struct(target_ldt_info, ptr, 1);
4289
    return 0;
4290
}
4291
#endif /* TARGET_I386 && TARGET_ABI32 */
4292

    
4293
#ifndef TARGET_ABI32
4294
abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
4295
{
4296
    abi_long ret = 0;
4297
    abi_ulong val;
4298
    int idx;
4299

    
4300
    switch(code) {
4301
    case TARGET_ARCH_SET_GS:
4302
    case TARGET_ARCH_SET_FS:
4303
        if (code == TARGET_ARCH_SET_GS)
4304
            idx = R_GS;
4305
        else
4306
            idx = R_FS;
4307
        cpu_x86_load_seg(env, idx, 0);
4308
        env->segs[idx].base = addr;
4309
        break;
4310
    case TARGET_ARCH_GET_GS:
4311
    case TARGET_ARCH_GET_FS:
4312
        if (code == TARGET_ARCH_GET_GS)
4313
            idx = R_GS;
4314
        else
4315
            idx = R_FS;
4316
        val = env->segs[idx].base;
4317
        if (put_user(val, addr, abi_ulong))
4318
            ret = -TARGET_EFAULT;
4319
        break;
4320
    default:
4321
        ret = -TARGET_EINVAL;
4322
        break;
4323
    }
4324
    return ret;
4325
}
4326
#endif
4327

    
4328
#endif /* defined(TARGET_I386) */
4329

    
4330
#define NEW_STACK_SIZE 0x40000
4331

    
4332

    
4333
static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
4334
typedef struct {
4335
    CPUArchState *env;
4336
    pthread_mutex_t mutex;
4337
    pthread_cond_t cond;
4338
    pthread_t thread;
4339
    uint32_t tid;
4340
    abi_ulong child_tidptr;
4341
    abi_ulong parent_tidptr;
4342
    sigset_t sigmask;
4343
} new_thread_info;
4344

    
4345
static void *clone_func(void *arg)
4346
{
4347
    new_thread_info *info = arg;
4348
    CPUArchState *env;
4349
    CPUState *cpu;
4350
    TaskState *ts;
4351

    
4352
    env = info->env;
4353
    cpu = ENV_GET_CPU(env);
4354
    thread_cpu = cpu;
4355
    ts = (TaskState *)env->opaque;
4356
    info->tid = gettid();
4357
    cpu->host_tid = info->tid;
4358
    task_settid(ts);
4359
    if (info->child_tidptr)
4360
        put_user_u32(info->tid, info->child_tidptr);
4361
    if (info->parent_tidptr)
4362
        put_user_u32(info->tid, info->parent_tidptr);
4363
    /* Enable signals.  */
4364
    sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
4365
    /* Signal to the parent that we're ready.  */
4366
    pthread_mutex_lock(&info->mutex);
4367
    pthread_cond_broadcast(&info->cond);
4368
    pthread_mutex_unlock(&info->mutex);
4369
    /* Wait until the parent has finshed initializing the tls state.  */
4370
    pthread_mutex_lock(&clone_lock);
4371
    pthread_mutex_unlock(&clone_lock);
4372
    cpu_loop(env);
4373
    /* never exits */
4374
    return NULL;
4375
}
4376

    
4377
/* do_fork() Must return host values and target errnos (unlike most
4378
   do_*() functions). */
4379
static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
4380
                   abi_ulong parent_tidptr, target_ulong newtls,
4381
                   abi_ulong child_tidptr)
4382
{
4383
    int ret;
4384
    TaskState *ts;
4385
    CPUArchState *new_env;
4386
    unsigned int nptl_flags;
4387
    sigset_t sigmask;
4388

    
4389
    /* Emulate vfork() with fork() */
4390
    if (flags & CLONE_VFORK)
4391
        flags &= ~(CLONE_VFORK | CLONE_VM);
4392

    
4393
    if (flags & CLONE_VM) {
4394
        TaskState *parent_ts = (TaskState *)env->opaque;
4395
        new_thread_info info;
4396
        pthread_attr_t attr;
4397

    
4398
        ts = g_malloc0(sizeof(TaskState));
4399
        init_task_state(ts);
4400
        /* we create a new CPU instance. */
4401
        new_env = cpu_copy(env);
4402
        /* Init regs that differ from the parent.  */
4403
        cpu_clone_regs(new_env, newsp);
4404
        new_env->opaque = ts;
4405
        ts->bprm = parent_ts->bprm;
4406
        ts->info = parent_ts->info;
4407
        nptl_flags = flags;
4408
        flags &= ~CLONE_NPTL_FLAGS2;
4409

    
4410
        if (nptl_flags & CLONE_CHILD_CLEARTID) {
4411
            ts->child_tidptr = child_tidptr;
4412
        }
4413

    
4414
        if (nptl_flags & CLONE_SETTLS)
4415
            cpu_set_tls (new_env, newtls);
4416

    
4417
        /* Grab a mutex so that thread setup appears atomic.  */
4418
        pthread_mutex_lock(&clone_lock);
4419

    
4420
        memset(&info, 0, sizeof(info));
4421
        pthread_mutex_init(&info.mutex, NULL);
4422
        pthread_mutex_lock(&info.mutex);
4423
        pthread_cond_init(&info.cond, NULL);
4424
        info.env = new_env;
4425
        if (nptl_flags & CLONE_CHILD_SETTID)
4426
            info.child_tidptr = child_tidptr;
4427
        if (nptl_flags & CLONE_PARENT_SETTID)
4428
            info.parent_tidptr = parent_tidptr;
4429

    
4430
        ret = pthread_attr_init(&attr);
4431
        ret = pthread_attr_setstacksize(&attr, NEW_STACK_SIZE);
4432
        ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
4433
        /* It is not safe to deliver signals until the child has finished
4434
           initializing, so temporarily block all signals.  */
4435
        sigfillset(&sigmask);
4436
        sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
4437

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

    
4441
        sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
4442
        pthread_attr_destroy(&attr);
4443
        if (ret == 0) {
4444
            /* Wait for the child to initialize.  */
4445
            pthread_cond_wait(&info.cond, &info.mutex);
4446
            ret = info.tid;
4447
            if (flags & CLONE_PARENT_SETTID)
4448
                put_user_u32(ret, parent_tidptr);
4449
        } else {
4450
            ret = -1;
4451
        }
4452
        pthread_mutex_unlock(&info.mutex);
4453
        pthread_cond_destroy(&info.cond);
4454
        pthread_mutex_destroy(&info.mutex);
4455
        pthread_mutex_unlock(&clone_lock);
4456
    } else {
4457
        /* if no CLONE_VM, we consider it is a fork */
4458
        if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
4459
            return -EINVAL;
4460
        fork_start();
4461
        ret = fork();
4462
        if (ret == 0) {
4463
            /* Child Process.  */
4464
            cpu_clone_regs(env, newsp);
4465
            fork_end(1);
4466
            /* There is a race condition here.  The parent process could
4467
               theoretically read the TID in the child process before the child
4468
               tid is set.  This would require using either ptrace
4469
               (not implemented) or having *_tidptr to point at a shared memory
4470
               mapping.  We can't repeat the spinlock hack used above because
4471
               the child process gets its own copy of the lock.  */
4472
            if (flags & CLONE_CHILD_SETTID)
4473
                put_user_u32(gettid(), child_tidptr);
4474
            if (flags & CLONE_PARENT_SETTID)
4475
                put_user_u32(gettid(), parent_tidptr);
4476
            ts = (TaskState *)env->opaque;
4477
            if (flags & CLONE_SETTLS)
4478
                cpu_set_tls (env, newtls);
4479
            if (flags & CLONE_CHILD_CLEARTID)
4480
                ts->child_tidptr = child_tidptr;
4481
        } else {
4482
            fork_end(0);
4483
        }
4484
    }
4485
    return ret;
4486
}
4487

    
4488
/* warning : doesn't handle linux specific flags... */
4489
static int target_to_host_fcntl_cmd(int cmd)
4490
{
4491
    switch(cmd) {
4492
        case TARGET_F_DUPFD:
4493
        case TARGET_F_GETFD:
4494
        case TARGET_F_SETFD:
4495
        case TARGET_F_GETFL:
4496
        case TARGET_F_SETFL:
4497
            return cmd;
4498
        case TARGET_F_GETLK:
4499
            return F_GETLK;
4500
        case TARGET_F_SETLK:
4501
            return F_SETLK;
4502
        case TARGET_F_SETLKW:
4503
            return F_SETLKW;
4504
        case TARGET_F_GETOWN:
4505
            return F_GETOWN;
4506
        case TARGET_F_SETOWN:
4507
            return F_SETOWN;
4508
        case TARGET_F_GETSIG:
4509
            return F_GETSIG;
4510
        case TARGET_F_SETSIG:
4511
            return F_SETSIG;
4512
#if TARGET_ABI_BITS == 32
4513
        case TARGET_F_GETLK64:
4514
            return F_GETLK64;
4515
        case TARGET_F_SETLK64:
4516
            return F_SETLK64;
4517
        case TARGET_F_SETLKW64:
4518
            return F_SETLKW64;
4519
#endif
4520
        case TARGET_F_SETLEASE:
4521
            return F_SETLEASE;
4522
        case TARGET_F_GETLEASE:
4523
            return F_GETLEASE;
4524
#ifdef F_DUPFD_CLOEXEC
4525
        case TARGET_F_DUPFD_CLOEXEC:
4526
            return F_DUPFD_CLOEXEC;
4527
#endif
4528
        case TARGET_F_NOTIFY:
4529
            return F_NOTIFY;
4530
        default:
4531
            return -TARGET_EINVAL;
4532
    }
4533
    return -TARGET_EINVAL;
4534
}
4535

    
4536
#define TRANSTBL_CONVERT(a) { -1, TARGET_##a, -1, a }
4537
static const bitmask_transtbl flock_tbl[] = {
4538
    TRANSTBL_CONVERT(F_RDLCK),
4539
    TRANSTBL_CONVERT(F_WRLCK),
4540
    TRANSTBL_CONVERT(F_UNLCK),
4541
    TRANSTBL_CONVERT(F_EXLCK),
4542
    TRANSTBL_CONVERT(F_SHLCK),
4543
    { 0, 0, 0, 0 }
4544
};
4545

    
4546
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
4547
{
4548
    struct flock fl;
4549
    struct target_flock *target_fl;
4550
    struct flock64 fl64;
4551
    struct target_flock64 *target_fl64;
4552
    abi_long ret;
4553
    int host_cmd = target_to_host_fcntl_cmd(cmd);
4554

    
4555
    if (host_cmd == -TARGET_EINVAL)
4556
            return host_cmd;
4557

    
4558
    switch(cmd) {
4559
    case TARGET_F_GETLK:
4560
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
4561
            return -TARGET_EFAULT;
4562
        fl.l_type =
4563
                  target_to_host_bitmask(tswap16(target_fl->l_type), flock_tbl);
4564
        fl.l_whence = tswap16(target_fl->l_whence);
4565
        fl.l_start = tswapal(target_fl->l_start);
4566
        fl.l_len = tswapal(target_fl->l_len);
4567
        fl.l_pid = tswap32(target_fl->l_pid);
4568
        unlock_user_struct(target_fl, arg, 0);
4569
        ret = get_errno(fcntl(fd, host_cmd, &fl));
4570
        if (ret == 0) {
4571
            if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
4572
                return -TARGET_EFAULT;
4573
            target_fl->l_type =
4574
                          host_to_target_bitmask(tswap16(fl.l_type), flock_tbl);
4575
            target_fl->l_whence = tswap16(fl.l_whence);
4576
            target_fl->l_start = tswapal(fl.l_start);
4577
            target_fl->l_len = tswapal(fl.l_len);
4578
            target_fl->l_pid = tswap32(fl.l_pid);
4579
            unlock_user_struct(target_fl, arg, 1);
4580
        }
4581
        break;
4582

    
4583
    case TARGET_F_SETLK:
4584
    case TARGET_F_SETLKW:
4585
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
4586
            return -TARGET_EFAULT;
4587
        fl.l_type =
4588
                  target_to_host_bitmask(tswap16(target_fl->l_type), flock_tbl);
4589
        fl.l_whence = tswap16(target_fl->l_whence);
4590
        fl.l_start = tswapal(target_fl->l_start);
4591
        fl.l_len = tswapal(target_fl->l_len);
4592
        fl.l_pid = tswap32(target_fl->l_pid);
4593
        unlock_user_struct(target_fl, arg, 0);
4594
        ret = get_errno(fcntl(fd, host_cmd, &fl));
4595
        break;
4596

    
4597
    case TARGET_F_GETLK64:
4598
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
4599
            return -TARGET_EFAULT;
4600
        fl64.l_type =
4601
           target_to_host_bitmask(tswap16(target_fl64->l_type), flock_tbl) >> 1;
4602
        fl64.l_whence = tswap16(target_fl64->l_whence);
4603
        fl64.l_start = tswap64(target_fl64->l_start);
4604
        fl64.l_len = tswap64(target_fl64->l_len);
4605
        fl64.l_pid = tswap32(target_fl64->l_pid);
4606
        unlock_user_struct(target_fl64, arg, 0);
4607
        ret = get_errno(fcntl(fd, host_cmd, &fl64));
4608
        if (ret == 0) {
4609
            if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
4610
                return -TARGET_EFAULT;
4611
            target_fl64->l_type =
4612
                   host_to_target_bitmask(tswap16(fl64.l_type), flock_tbl) >> 1;
4613
            target_fl64->l_whence = tswap16(fl64.l_whence);
4614
            target_fl64->l_start = tswap64(fl64.l_start);
4615
            target_fl64->l_len = tswap64(fl64.l_len);
4616
            target_fl64->l_pid = tswap32(fl64.l_pid);
4617
            unlock_user_struct(target_fl64, arg, 1);
4618
        }
4619
        break;
4620
    case TARGET_F_SETLK64:
4621
    case TARGET_F_SETLKW64:
4622
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
4623
            return -TARGET_EFAULT;
4624
        fl64.l_type =
4625
           target_to_host_bitmask(tswap16(target_fl64->l_type), flock_tbl) >> 1;
4626
        fl64.l_whence = tswap16(target_fl64->l_whence);
4627
        fl64.l_start = tswap64(target_fl64->l_start);
4628
        fl64.l_len = tswap64(target_fl64->l_len);
4629
        fl64.l_pid = tswap32(target_fl64->l_pid);
4630
        unlock_user_struct(target_fl64, arg, 0);
4631
        ret = get_errno(fcntl(fd, host_cmd, &fl64));
4632
        break;
4633

    
4634
    case TARGET_F_GETFL:
4635
        ret = get_errno(fcntl(fd, host_cmd, arg));
4636
        if (ret >= 0) {
4637
            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
4638
        }
4639
        break;
4640

    
4641
    case TARGET_F_SETFL:
4642
        ret = get_errno(fcntl(fd, host_cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
4643
        break;
4644

    
4645
    case TARGET_F_SETOWN:
4646
    case TARGET_F_GETOWN:
4647
    case TARGET_F_SETSIG:
4648
    case TARGET_F_GETSIG:
4649
    case TARGET_F_SETLEASE:
4650
    case TARGET_F_GETLEASE:
4651
        ret = get_errno(fcntl(fd, host_cmd, arg));
4652
        break;
4653

    
4654
    default:
4655
        ret = get_errno(fcntl(fd, cmd, arg));
4656
        break;
4657
    }
4658
    return ret;
4659
}
4660

    
4661
#ifdef USE_UID16
4662

    
4663
static inline int high2lowuid(int uid)
4664
{
4665
    if (uid > 65535)
4666
        return 65534;
4667
    else
4668
        return uid;
4669
}
4670

    
4671
static inline int high2lowgid(int gid)
4672
{
4673
    if (gid > 65535)
4674
        return 65534;
4675
    else
4676
        return gid;
4677
}
4678

    
4679
static inline int low2highuid(int uid)
4680
{
4681
    if ((int16_t)uid == -1)
4682
        return -1;
4683
    else
4684
        return uid;
4685
}
4686

    
4687
static inline int low2highgid(int gid)
4688
{
4689
    if ((int16_t)gid == -1)
4690
        return -1;
4691
    else
4692
        return gid;
4693
}
4694
static inline int tswapid(int id)
4695
{
4696
    return tswap16(id);
4697
}
4698
#else /* !USE_UID16 */
4699
static inline int high2lowuid(int uid)
4700
{
4701
    return uid;
4702
}
4703
static inline int high2lowgid(int gid)
4704
{
4705
    return gid;
4706
}
4707
static inline int low2highuid(int uid)
4708
{
4709
    return uid;
4710
}
4711
static inline int low2highgid(int gid)
4712
{
4713
    return gid;
4714
}
4715
static inline int tswapid(int id)
4716
{
4717
    return tswap32(id);
4718
}
4719
#endif /* USE_UID16 */
4720

    
4721
void syscall_init(void)
4722
{
4723
    IOCTLEntry *ie;
4724
    const argtype *arg_type;
4725
    int size;
4726
    int i;
4727

    
4728
#define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
4729
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
4730
#include "syscall_types.h"
4731
#undef STRUCT
4732
#undef STRUCT_SPECIAL
4733

    
4734
    /* Build target_to_host_errno_table[] table from
4735
     * host_to_target_errno_table[]. */
4736
    for (i = 0; i < ERRNO_TABLE_SIZE; i++) {
4737
        target_to_host_errno_table[host_to_target_errno_table[i]] = i;
4738
    }
4739

    
4740
    /* we patch the ioctl size if necessary. We rely on the fact that
4741
       no ioctl has all the bits at '1' in the size field */
4742
    ie = ioctl_entries;
4743
    while (ie->target_cmd != 0) {
4744
        if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
4745
            TARGET_IOC_SIZEMASK) {
4746
            arg_type = ie->arg_type;
4747
            if (arg_type[0] != TYPE_PTR) {
4748
                fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
4749
                        ie->target_cmd);
4750
                exit(1);
4751
            }
4752
            arg_type++;
4753
            size = thunk_type_size(arg_type, 0);
4754
            ie->target_cmd = (ie->target_cmd &
4755
                              ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
4756
                (size << TARGET_IOC_SIZESHIFT);
4757
        }
4758

    
4759
        /* automatic consistency check if same arch */
4760
#if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
4761
    (defined(__x86_64__) && defined(TARGET_X86_64))
4762
        if (unlikely(ie->target_cmd != ie->host_cmd)) {
4763
            fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
4764
                    ie->name, ie->target_cmd, ie->host_cmd);
4765
        }
4766
#endif
4767
        ie++;
4768
    }
4769
}
4770

    
4771
#if TARGET_ABI_BITS == 32
4772
static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
4773
{
4774
#ifdef TARGET_WORDS_BIGENDIAN
4775
    return ((uint64_t)word0 << 32) | word1;
4776
#else
4777
    return ((uint64_t)word1 << 32) | word0;
4778
#endif
4779
}
4780
#else /* TARGET_ABI_BITS == 32 */
4781
static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
4782
{
4783
    return word0;
4784
}
4785
#endif /* TARGET_ABI_BITS != 32 */
4786

    
4787
#ifdef TARGET_NR_truncate64
4788
static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
4789
                                         abi_long arg2,
4790
                                         abi_long arg3,
4791
                                         abi_long arg4)
4792
{
4793
    if (regpairs_aligned(cpu_env)) {
4794
        arg2 = arg3;
4795
        arg3 = arg4;
4796
    }
4797
    return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
4798
}
4799
#endif
4800

    
4801
#ifdef TARGET_NR_ftruncate64
4802
static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
4803
                                          abi_long arg2,
4804
                                          abi_long arg3,
4805
                                          abi_long arg4)
4806
{
4807
    if (regpairs_aligned(cpu_env)) {
4808
        arg2 = arg3;
4809
        arg3 = arg4;
4810
    }
4811
    return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
4812
}
4813
#endif
4814

    
4815
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
4816
                                               abi_ulong target_addr)
4817
{
4818
    struct target_timespec *target_ts;
4819

    
4820
    if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
4821
        return -TARGET_EFAULT;
4822
    host_ts->tv_sec = tswapal(target_ts->tv_sec);
4823
    host_ts->tv_nsec = tswapal(target_ts->tv_nsec);
4824
    unlock_user_struct(target_ts, target_addr, 0);
4825
    return 0;
4826
}
4827

    
4828
static inline abi_long host_to_target_timespec(abi_ulong target_addr,
4829
                                               struct timespec *host_ts)
4830
{
4831
    struct target_timespec *target_ts;
4832

    
4833
    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
4834
        return -TARGET_EFAULT;
4835
    target_ts->tv_sec = tswapal(host_ts->tv_sec);
4836
    target_ts->tv_nsec = tswapal(host_ts->tv_nsec);
4837
    unlock_user_struct(target_ts, target_addr, 1);
4838
    return 0;
4839
}
4840

    
4841
#if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
4842
static inline abi_long host_to_target_stat64(void *cpu_env,
4843
                                             abi_ulong target_addr,
4844
                                             struct stat *host_st)
4845
{
4846
#if defined(TARGET_ARM) && defined(TARGET_ABI32)
4847
    if (((CPUARMState *)cpu_env)->eabi) {
4848
        struct target_eabi_stat64 *target_st;
4849

    
4850
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
4851
            return -TARGET_EFAULT;
4852
        memset(target_st, 0, sizeof(struct target_eabi_stat64));
4853
        __put_user(host_st->st_dev, &target_st->st_dev);
4854
        __put_user(host_st->st_ino, &target_st->st_ino);
4855
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4856
        __put_user(host_st->st_ino, &target_st->__st_ino);
4857
#endif
4858
        __put_user(host_st->st_mode, &target_st->st_mode);
4859
        __put_user(host_st->st_nlink, &target_st->st_nlink);
4860
        __put_user(host_st->st_uid, &target_st->st_uid);
4861
        __put_user(host_st->st_gid, &target_st->st_gid);
4862
        __put_user(host_st->st_rdev, &target_st->st_rdev);
4863
        __put_user(host_st->st_size, &target_st->st_size);
4864
        __put_user(host_st->st_blksize, &target_st->st_blksize);
4865
        __put_user(host_st->st_blocks, &target_st->st_blocks);
4866
        __put_user(host_st->st_atime, &target_st->target_st_atime);
4867
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
4868
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
4869
        unlock_user_struct(target_st, target_addr, 1);
4870
    } else
4871
#endif
4872
    {
4873
#if defined(TARGET_HAS_STRUCT_STAT64)
4874
        struct target_stat64 *target_st;
4875
#else
4876
        struct target_stat *target_st;
4877
#endif
4878

    
4879
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
4880
            return -TARGET_EFAULT;
4881
        memset(target_st, 0, sizeof(*target_st));
4882
        __put_user(host_st->st_dev, &target_st->st_dev);
4883
        __put_user(host_st->st_ino, &target_st->st_ino);
4884
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4885
        __put_user(host_st->st_ino, &target_st->__st_ino);
4886
#endif
4887
        __put_user(host_st->st_mode, &target_st->st_mode);
4888
        __put_user(host_st->st_nlink, &target_st->st_nlink);
4889
        __put_user(host_st->st_uid, &target_st->st_uid);
4890
        __put_user(host_st->st_gid, &target_st->st_gid);
4891
        __put_user(host_st->st_rdev, &target_st->st_rdev);
4892
        /* XXX: better use of kernel struct */
4893
        __put_user(host_st->st_size, &target_st->st_size);
4894
        __put_user(host_st->st_blksize, &target_st->st_blksize);
4895
        __put_user(host_st->st_blocks, &target_st->st_blocks);
4896
        __put_user(host_st->st_atime, &target_st->target_st_atime);
4897
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
4898
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
4899
        unlock_user_struct(target_st, target_addr, 1);
4900
    }
4901

    
4902
    return 0;
4903
}
4904
#endif
4905

    
4906
/* ??? Using host futex calls even when target atomic operations
4907
   are not really atomic probably breaks things.  However implementing
4908
   futexes locally would make futexes shared between multiple processes
4909
   tricky.  However they're probably useless because guest atomic
4910
   operations won't work either.  */
4911
static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
4912
                    target_ulong uaddr2, int val3)
4913
{
4914
    struct timespec ts, *pts;
4915
    int base_op;
4916

    
4917
    /* ??? We assume FUTEX_* constants are the same on both host
4918
       and target.  */
4919
#ifdef FUTEX_CMD_MASK
4920
    base_op = op & FUTEX_CMD_MASK;
4921
#else
4922
    base_op = op;
4923
#endif
4924
    switch (base_op) {
4925
    case FUTEX_WAIT:
4926
    case FUTEX_WAIT_BITSET:
4927
        if (timeout) {
4928
            pts = &ts;
4929
            target_to_host_timespec(pts, timeout);
4930
        } else {
4931
            pts = NULL;
4932
        }
4933
        return get_errno(sys_futex(g2h(uaddr), op, tswap32(val),
4934
                         pts, NULL, val3));
4935
    case FUTEX_WAKE:
4936
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4937
    case FUTEX_FD:
4938
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4939
    case FUTEX_REQUEUE:
4940
    case FUTEX_CMP_REQUEUE:
4941
    case FUTEX_WAKE_OP:
4942
        /* For FUTEX_REQUEUE, FUTEX_CMP_REQUEUE, and FUTEX_WAKE_OP, the
4943
           TIMEOUT parameter is interpreted as a uint32_t by the kernel.
4944
           But the prototype takes a `struct timespec *'; insert casts
4945
           to satisfy the compiler.  We do not need to tswap TIMEOUT
4946
           since it's not compared to guest memory.  */
4947
        pts = (struct timespec *)(uintptr_t) timeout;
4948
        return get_errno(sys_futex(g2h(uaddr), op, val, pts,
4949
                                   g2h(uaddr2),
4950
                                   (base_op == FUTEX_CMP_REQUEUE
4951
                                    ? tswap32(val3)
4952
                                    : val3)));
4953
    default:
4954
        return -TARGET_ENOSYS;
4955
    }
4956
}
4957

    
4958
/* Map host to target signal numbers for the wait family of syscalls.
4959
   Assume all other status bits are the same.  */
4960
int host_to_target_waitstatus(int status)
4961
{
4962
    if (WIFSIGNALED(status)) {
4963
        return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f);
4964
    }
4965
    if (WIFSTOPPED(status)) {
4966
        return (host_to_target_signal(WSTOPSIG(status)) << 8)
4967
               | (status & 0xff);
4968
    }
4969
    return status;
4970
}
4971

    
4972
static int relstr_to_int(const char *s)
4973
{
4974
    /* Convert a uname release string like "2.6.18" to an integer
4975
     * of the form 0x020612. (Beware that 0x020612 is *not* 2.6.12.)
4976
     */
4977
    int i, n, tmp;
4978

    
4979
    tmp = 0;
4980
    for (i = 0; i < 3; i++) {
4981
        n = 0;
4982
        while (*s >= '0' && *s <= '9') {
4983
            n *= 10;
4984
            n += *s - '0';
4985
            s++;
4986
        }
4987
        tmp = (tmp << 8) + n;
4988
        if (*s == '.') {
4989
            s++;
4990
        }
4991
    }
4992
    return tmp;
4993
}
4994

    
4995
int get_osversion(void)
4996
{
4997
    static int osversion;
4998
    struct new_utsname buf;
4999
    const char *s;
5000

    
5001
    if (osversion)
5002
        return osversion;
5003
    if (qemu_uname_release && *qemu_uname_release) {
5004
        s = qemu_uname_release;
5005
    } else {
5006
        if (sys_uname(&buf))
5007
            return 0;
5008
        s = buf.release;
5009
    }
5010
    osversion = relstr_to_int(s);
5011
    return osversion;
5012
}
5013

    
5014
void init_qemu_uname_release(void)
5015
{
5016
    /* Initialize qemu_uname_release for later use.
5017
     * If the host kernel is too old and the user hasn't asked for
5018
     * a specific fake version number, we might want to fake a minimum
5019
     * target kernel version.
5020
     */
5021
#ifdef UNAME_MINIMUM_RELEASE
5022
    struct new_utsname buf;
5023

    
5024
    if (qemu_uname_release && *qemu_uname_release) {
5025
        return;
5026
    }
5027

    
5028
    if (sys_uname(&buf)) {
5029
        return;
5030
    }
5031

    
5032
    if (relstr_to_int(buf.release) < relstr_to_int(UNAME_MINIMUM_RELEASE)) {
5033
        qemu_uname_release = UNAME_MINIMUM_RELEASE;
5034
    }
5035
#endif
5036
}
5037

    
5038
static int open_self_maps(void *cpu_env, int fd)
5039
{
5040
#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
5041
    TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
5042
#endif
5043
    FILE *fp;
5044
    char *line = NULL;
5045
    size_t len = 0;
5046
    ssize_t read;
5047

    
5048
    fp = fopen("/proc/self/maps", "r");
5049
    if (fp == NULL) {
5050
        return -EACCES;
5051
    }
5052

    
5053
    while ((read = getline(&line, &len, fp)) != -1) {
5054
        int fields, dev_maj, dev_min, inode;
5055
        uint64_t min, max, offset;
5056
        char flag_r, flag_w, flag_x, flag_p;
5057
        char path[512] = "";
5058
        fields = sscanf(line, "%"PRIx64"-%"PRIx64" %c%c%c%c %"PRIx64" %x:%x %d"
5059
                        " %512s", &min, &max, &flag_r, &flag_w, &flag_x,
5060
                        &flag_p, &offset, &dev_maj, &dev_min, &inode, path);
5061

    
5062
        if ((fields < 10) || (fields > 11)) {
5063
            continue;
5064
        }
5065
        if (!strncmp(path, "[stack]", 7)) {
5066
            continue;
5067
        }
5068
        if (h2g_valid(min) && h2g_valid(max)) {
5069
            dprintf(fd, TARGET_ABI_FMT_lx "-" TARGET_ABI_FMT_lx
5070
                    " %c%c%c%c %08" PRIx64 " %02x:%02x %d %s%s\n",
5071
                    h2g(min), h2g(max), flag_r, flag_w,
5072
                    flag_x, flag_p, offset, dev_maj, dev_min, inode,
5073
                    path[0] ? "         " : "", path);
5074
        }
5075
    }
5076

    
5077
    free(line);
5078
    fclose(fp);
5079

    
5080
#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
5081
    dprintf(fd, "%08llx-%08llx rw-p %08llx 00:00 0          [stack]\n",
5082
                (unsigned long long)ts->info->stack_limit,
5083
                (unsigned long long)(ts->info->start_stack +
5084
                                     (TARGET_PAGE_SIZE - 1)) & TARGET_PAGE_MASK,
5085
                (unsigned long long)0);
5086
#endif
5087

    
5088
    return 0;
5089
}
5090

    
5091
static int open_self_stat(void *cpu_env, int fd)
5092
{
5093
    TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
5094
    abi_ulong start_stack = ts->info->start_stack;
5095
    int i;
5096

    
5097
    for (i = 0; i < 44; i++) {
5098
      char buf[128];
5099
      int len;
5100
      uint64_t val = 0;
5101

    
5102
      if (i == 0) {
5103
        /* pid */
5104
        val = getpid();
5105
        snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
5106
      } else if (i == 1) {
5107
        /* app name */
5108
        snprintf(buf, sizeof(buf), "(%s) ", ts->bprm->argv[0]);
5109
      } else if (i == 27) {
5110
        /* stack bottom */
5111
        val = start_stack;
5112
        snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
5113
      } else {
5114
        /* for the rest, there is MasterCard */
5115
        snprintf(buf, sizeof(buf), "0%c", i == 43 ? '\n' : ' ');
5116
      }
5117

    
5118
      len = strlen(buf);
5119
      if (write(fd, buf, len) != len) {
5120
          return -1;
5121
      }
5122
    }
5123

    
5124
    return 0;
5125
}
5126

    
5127
static int open_self_auxv(void *cpu_env, int fd)
5128
{
5129
    TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
5130
    abi_ulong auxv = ts->info->saved_auxv;
5131
    abi_ulong len = ts->info->auxv_len;
5132
    char *ptr;
5133

    
5134
    /*
5135
     * Auxiliary vector is stored in target process stack.
5136
     * read in whole auxv vector and copy it to file
5137
     */
5138
    ptr = lock_user(VERIFY_READ, auxv, len, 0);
5139
    if (ptr != NULL) {
5140
        while (len > 0) {
5141
            ssize_t r;
5142
            r = write(fd, ptr, len);
5143
            if (r <= 0) {
5144
                break;
5145
            }
5146
            len -= r;
5147
            ptr += r;
5148
        }
5149
        lseek(fd, 0, SEEK_SET);
5150
        unlock_user(ptr, auxv, len);
5151
    }
5152

    
5153
    return 0;
5154
}
5155

    
5156
static int is_proc_myself(const char *filename, const char *entry)
5157
{
5158
    if (!strncmp(filename, "/proc/", strlen("/proc/"))) {
5159
        filename += strlen("/proc/");
5160
        if (!strncmp(filename, "self/", strlen("self/"))) {
5161
            filename += strlen("self/");
5162
        } else if (*filename >= '1' && *filename <= '9') {
5163
            char myself[80];
5164
            snprintf(myself, sizeof(myself), "%d/", getpid());
5165
            if (!strncmp(filename, myself, strlen(myself))) {
5166
                filename += strlen(myself);
5167
            } else {
5168
                return 0;
5169
            }
5170
        } else {
5171
            return 0;
5172
        }
5173
        if (!strcmp(filename, entry)) {
5174
            return 1;
5175
        }
5176
    }
5177
    return 0;
5178
}
5179

    
5180
#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
5181
static int is_proc(const char *filename, const char *entry)
5182
{
5183
    return strcmp(filename, entry) == 0;
5184
}
5185

    
5186
static int open_net_route(void *cpu_env, int fd)
5187
{
5188
    FILE *fp;
5189
    char *line = NULL;
5190
    size_t len = 0;
5191
    ssize_t read;
5192

    
5193
    fp = fopen("/proc/net/route", "r");
5194
    if (fp == NULL) {
5195
        return -EACCES;
5196
    }
5197

    
5198
    /* read header */
5199

    
5200
    read = getline(&line, &len, fp);
5201
    dprintf(fd, "%s", line);
5202

    
5203
    /* read routes */
5204

    
5205
    while ((read = getline(&line, &len, fp)) != -1) {
5206
        char iface[16];
5207
        uint32_t dest, gw, mask;
5208
        unsigned int flags, refcnt, use, metric, mtu, window, irtt;
5209
        sscanf(line, "%s\t%08x\t%08x\t%04x\t%d\t%d\t%d\t%08x\t%d\t%u\t%u\n",
5210
                     iface, &dest, &gw, &flags, &refcnt, &use, &metric,
5211
                     &mask, &mtu, &window, &irtt);
5212
        dprintf(fd, "%s\t%08x\t%08x\t%04x\t%d\t%d\t%d\t%08x\t%d\t%u\t%u\n",
5213
                iface, tswap32(dest), tswap32(gw), flags, refcnt, use,
5214
                metric, tswap32(mask), mtu, window, irtt);
5215
    }
5216

    
5217
    free(line);
5218
    fclose(fp);
5219

    
5220
    return 0;
5221
}
5222
#endif
5223

    
5224
static int do_open(void *cpu_env, const char *pathname, int flags, mode_t mode)
5225
{
5226
    struct fake_open {
5227
        const char *filename;
5228
        int (*fill)(void *cpu_env, int fd);
5229
        int (*cmp)(const char *s1, const char *s2);
5230
    };
5231
    const struct fake_open *fake_open;
5232
    static const struct fake_open fakes[] = {
5233
        { "maps", open_self_maps, is_proc_myself },
5234
        { "stat", open_self_stat, is_proc_myself },
5235
        { "auxv", open_self_auxv, is_proc_myself },
5236
#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
5237
        { "/proc/net/route", open_net_route, is_proc },
5238
#endif
5239
        { NULL, NULL, NULL }
5240
    };
5241

    
5242
    for (fake_open = fakes; fake_open->filename; fake_open++) {
5243
        if (fake_open->cmp(pathname, fake_open->filename)) {
5244
            break;
5245
        }
5246
    }
5247

    
5248
    if (fake_open->filename) {
5249
        const char *tmpdir;
5250
        char filename[PATH_MAX];
5251
        int fd, r;
5252

    
5253
        /* create temporary file to map stat to */
5254
        tmpdir = getenv("TMPDIR");
5255
        if (!tmpdir)
5256
            tmpdir = "/tmp";
5257
        snprintf(filename, sizeof(filename), "%s/qemu-open.XXXXXX", tmpdir);
5258
        fd = mkstemp(filename);
5259
        if (fd < 0) {
5260
            return fd;
5261
        }
5262
        unlink(filename);
5263

    
5264
        if ((r = fake_open->fill(cpu_env, fd))) {
5265
            close(fd);
5266
            return r;
5267
        }
5268
        lseek(fd, 0, SEEK_SET);
5269

    
5270
        return fd;
5271
    }
5272

    
5273
    return get_errno(open(path(pathname), flags, mode));
5274
}
5275

    
5276
/* do_syscall() should always have a single exit point at the end so
5277
   that actions, such as logging of syscall results, can be performed.
5278
   All errnos that do_syscall() returns must be -TARGET_<errcode>. */
5279
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
5280
                    abi_long arg2, abi_long arg3, abi_long arg4,
5281
                    abi_long arg5, abi_long arg6, abi_long arg7,
5282
                    abi_long arg8)
5283
{
5284
    CPUState *cpu = ENV_GET_CPU(cpu_env);
5285
    abi_long ret;
5286
    struct stat st;
5287
    struct statfs stfs;
5288
    void *p;
5289

    
5290
#ifdef DEBUG
5291
    gemu_log("syscall %d", num);
5292
#endif
5293
    if(do_strace)
5294
        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
5295

    
5296
    switch(num) {
5297
    case TARGET_NR_exit:
5298
        /* In old applications this may be used to implement _exit(2).
5299
           However in threaded applictions it is used for thread termination,
5300
           and _exit_group is used for application termination.
5301
           Do thread termination if we have more then one thread.  */
5302
        /* FIXME: This probably breaks if a signal arrives.  We should probably
5303
           be disabling signals.  */
5304
        if (CPU_NEXT(first_cpu)) {
5305
            TaskState *ts;
5306

    
5307
            cpu_list_lock();
5308
            /* Remove the CPU from the list.  */
5309
            QTAILQ_REMOVE(&cpus, cpu, node);
5310
            cpu_list_unlock();
5311
            ts = ((CPUArchState *)cpu_env)->opaque;
5312
            if (ts->child_tidptr) {
5313
                put_user_u32(0, ts->child_tidptr);
5314
                sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
5315
                          NULL, NULL, 0);
5316
            }
5317
            thread_cpu = NULL;
5318
            object_unref(OBJECT(ENV_GET_CPU(cpu_env)));
5319
            g_free(ts);
5320
            pthread_exit(NULL);
5321
        }
5322
#ifdef TARGET_GPROF
5323
        _mcleanup();
5324
#endif
5325
        gdb_exit(cpu_env, arg1);
5326
        _exit(arg1);
5327
        ret = 0; /* avoid warning */
5328
        break;
5329
    case TARGET_NR_read:
5330
        if (arg3 == 0)
5331
            ret = 0;
5332
        else {
5333
            if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5334
                goto efault;
5335
            ret = get_errno(read(arg1, p, arg3));
5336
            unlock_user(p, arg2, ret);
5337
        }
5338
        break;
5339
    case TARGET_NR_write:
5340
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5341
            goto efault;
5342
        ret = get_errno(write(arg1, p, arg3));
5343
        unlock_user(p, arg2, 0);
5344
        break;
5345
    case TARGET_NR_open:
5346
        if (!(p = lock_user_string(arg1)))
5347
            goto efault;
5348
        ret = get_errno(do_open(cpu_env, p,
5349
                                target_to_host_bitmask(arg2, fcntl_flags_tbl),
5350
                                arg3));
5351
        unlock_user(p, arg1, 0);
5352
        break;
5353
#if defined(TARGET_NR_openat) && defined(__NR_openat)
5354
    case TARGET_NR_openat:
5355
        if (!(p = lock_user_string(arg2)))
5356
            goto efault;
5357
        ret = get_errno(sys_openat(arg1,
5358
                                   path(p),
5359
                                   target_to_host_bitmask(arg3, fcntl_flags_tbl),
5360
                                   arg4));
5361
        unlock_user(p, arg2, 0);
5362
        break;
5363
#endif
5364
    case TARGET_NR_close:
5365
        ret = get_errno(close(arg1));
5366
        break;
5367
    case TARGET_NR_brk:
5368
        ret = do_brk(arg1);
5369
        break;
5370
    case TARGET_NR_fork:
5371
        ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
5372
        break;
5373
#ifdef TARGET_NR_waitpid
5374
    case TARGET_NR_waitpid:
5375
        {
5376
            int status;
5377
            ret = get_errno(waitpid(arg1, &status, arg3));
5378
            if (!is_error(ret) && arg2 && ret
5379
                && put_user_s32(host_to_target_waitstatus(status), arg2))
5380
                goto efault;
5381
        }
5382
        break;
5383
#endif
5384
#ifdef TARGET_NR_waitid
5385
    case TARGET_NR_waitid:
5386
        {
5387
            siginfo_t info;
5388
            info.si_pid = 0;
5389
            ret = get_errno(waitid(arg1, arg2, &info, arg4));
5390
            if (!is_error(ret) && arg3 && info.si_pid != 0) {
5391
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
5392
                    goto efault;
5393
                host_to_target_siginfo(p, &info);
5394
                unlock_user(p, arg3, sizeof(target_siginfo_t));
5395
            }
5396
        }
5397
        break;
5398
#endif
5399
#ifdef TARGET_NR_creat /* not on alpha */
5400
    case TARGET_NR_creat:
5401
        if (!(p = lock_user_string(arg1)))
5402
            goto efault;
5403
        ret = get_errno(creat(p, arg2));
5404
        unlock_user(p, arg1, 0);
5405
        break;
5406
#endif
5407
    case TARGET_NR_link:
5408
        {
5409
            void * p2;
5410
            p = lock_user_string(arg1);
5411
            p2 = lock_user_string(arg2);
5412
            if (!p || !p2)
5413
                ret = -TARGET_EFAULT;
5414
            else
5415
                ret = get_errno(link(p, p2));
5416
            unlock_user(p2, arg2, 0);
5417
            unlock_user(p, arg1, 0);
5418
        }
5419
        break;
5420
#if defined(TARGET_NR_linkat)
5421
    case TARGET_NR_linkat:
5422
        {
5423
            void * p2 = NULL;
5424
            if (!arg2 || !arg4)
5425
                goto efault;
5426
            p  = lock_user_string(arg2);
5427
            p2 = lock_user_string(arg4);
5428
            if (!p || !p2)
5429
                ret = -TARGET_EFAULT;
5430
            else
5431
                ret = get_errno(linkat(arg1, p, arg3, p2, arg5));
5432
            unlock_user(p, arg2, 0);
5433
            unlock_user(p2, arg4, 0);
5434
        }
5435
        break;
5436
#endif
5437
    case TARGET_NR_unlink:
5438
        if (!(p = lock_user_string(arg1)))
5439
            goto efault;
5440
        ret = get_errno(unlink(p));
5441
        unlock_user(p, arg1, 0);
5442
        break;
5443
#if defined(TARGET_NR_unlinkat)
5444
    case TARGET_NR_unlinkat:
5445
        if (!(p = lock_user_string(arg2)))
5446
            goto efault;
5447
        ret = get_errno(unlinkat(arg1, p, arg3));
5448
        unlock_user(p, arg2, 0);
5449
        break;
5450
#endif
5451
    case TARGET_NR_execve:
5452
        {
5453
            char **argp, **envp;
5454
            int argc, envc;
5455
            abi_ulong gp;
5456
            abi_ulong guest_argp;
5457
            abi_ulong guest_envp;
5458
            abi_ulong addr;
5459
            char **q;
5460
            int total_size = 0;
5461

    
5462
            argc = 0;
5463
            guest_argp = arg2;
5464
            for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
5465
                if (get_user_ual(addr, gp))
5466
                    goto efault;
5467
                if (!addr)
5468
                    break;
5469
                argc++;
5470
            }
5471
            envc = 0;
5472
            guest_envp = arg3;
5473
            for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
5474
                if (get_user_ual(addr, gp))
5475
                    goto efault;
5476
                if (!addr)
5477
                    break;
5478
                envc++;
5479
            }
5480

    
5481
            argp = alloca((argc + 1) * sizeof(void *));
5482
            envp = alloca((envc + 1) * sizeof(void *));
5483

    
5484
            for (gp = guest_argp, q = argp; gp;
5485
                  gp += sizeof(abi_ulong), q++) {
5486
                if (get_user_ual(addr, gp))
5487
                    goto execve_efault;
5488
                if (!addr)
5489
                    break;
5490
                if (!(*q = lock_user_string(addr)))
5491
                    goto execve_efault;
5492
                total_size += strlen(*q) + 1;
5493
            }
5494
            *q = NULL;
5495

    
5496
            for (gp = guest_envp, q = envp; gp;
5497
                  gp += sizeof(abi_ulong), q++) {
5498
                if (get_user_ual(addr, gp))
5499
                    goto execve_efault;
5500
                if (!addr)
5501
                    break;
5502
                if (!(*q = lock_user_string(addr)))
5503
                    goto execve_efault;
5504
                total_size += strlen(*q) + 1;
5505
            }
5506
            *q = NULL;
5507

    
5508
            /* This case will not be caught by the host's execve() if its
5509
               page size is bigger than the target's. */
5510
            if (total_size > MAX_ARG_PAGES * TARGET_PAGE_SIZE) {
5511
                ret = -TARGET_E2BIG;
5512
                goto execve_end;
5513
            }
5514
            if (!(p = lock_user_string(arg1)))
5515
                goto execve_efault;
5516
            ret = get_errno(execve(p, argp, envp));
5517
            unlock_user(p, arg1, 0);
5518

    
5519
            goto execve_end;
5520

    
5521
        execve_efault:
5522
            ret = -TARGET_EFAULT;
5523

    
5524
        execve_end:
5525
            for (gp = guest_argp, q = argp; *q;
5526
                  gp += sizeof(abi_ulong), q++) {
5527
                if (get_user_ual(addr, gp)
5528
                    || !addr)
5529
                    break;
5530
                unlock_user(*q, addr, 0);
5531
            }
5532
            for (gp = guest_envp, q = envp; *q;
5533
                  gp += sizeof(abi_ulong), q++) {
5534
                if (get_user_ual(addr, gp)
5535
                    || !addr)
5536
                    break;
5537
                unlock_user(*q, addr, 0);
5538
            }
5539
        }
5540
        break;
5541
    case TARGET_NR_chdir:
5542
        if (!(p = lock_user_string(arg1)))
5543
            goto efault;
5544
        ret = get_errno(chdir(p));
5545
        unlock_user(p, arg1, 0);
5546
        break;
5547
#ifdef TARGET_NR_time
5548
    case TARGET_NR_time:
5549
        {
5550
            time_t host_time;
5551
            ret = get_errno(time(&host_time));
5552
            if (!is_error(ret)
5553
                && arg1
5554
                && put_user_sal(host_time, arg1))
5555
                goto efault;
5556
        }
5557
        break;
5558
#endif
5559
    case TARGET_NR_mknod:
5560
        if (!(p = lock_user_string(arg1)))
5561
            goto efault;
5562
        ret = get_errno(mknod(p, arg2, arg3));
5563
        unlock_user(p, arg1, 0);
5564
        break;
5565
#if defined(TARGET_NR_mknodat)
5566
    case TARGET_NR_mknodat:
5567
        if (!(p = lock_user_string(arg2)))
5568
            goto efault;
5569
        ret = get_errno(mknodat(arg1, p, arg3, arg4));
5570
        unlock_user(p, arg2, 0);
5571
        break;
5572
#endif
5573
    case TARGET_NR_chmod:
5574
        if (!(p = lock_user_string(arg1)))
5575
            goto efault;
5576
        ret = get_errno(chmod(p, arg2));
5577
        unlock_user(p, arg1, 0);
5578
        break;
5579
#ifdef TARGET_NR_break
5580
    case TARGET_NR_break:
5581
        goto unimplemented;
5582
#endif
5583
#ifdef TARGET_NR_oldstat
5584
    case TARGET_NR_oldstat:
5585
        goto unimplemented;
5586
#endif
5587
    case TARGET_NR_lseek:
5588
        ret = get_errno(lseek(arg1, arg2, arg3));
5589
        break;
5590
#if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA)
5591
    /* Alpha specific */
5592
    case TARGET_NR_getxpid:
5593
        ((CPUAlphaState *)cpu_env)->ir[IR_A4] = getppid();
5594
        ret = get_errno(getpid());
5595
        break;
5596
#endif
5597
#ifdef TARGET_NR_getpid
5598
    case TARGET_NR_getpid:
5599
        ret = get_errno(getpid());
5600
        break;
5601
#endif
5602
    case TARGET_NR_mount:
5603
                {
5604
                        /* need to look at the data field */
5605
                        void *p2, *p3;
5606
                        p = lock_user_string(arg1);
5607
                        p2 = lock_user_string(arg2);
5608
                        p3 = lock_user_string(arg3);
5609
                        if (!p || !p2 || !p3)
5610
                            ret = -TARGET_EFAULT;
5611
                        else {
5612
                            /* FIXME - arg5 should be locked, but it isn't clear how to
5613
                             * do that since it's not guaranteed to be a NULL-terminated
5614
                             * string.
5615
                             */
5616
                            if ( ! arg5 )
5617
                                ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, NULL));
5618
                            else
5619
                                ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
5620
                        }
5621
                        unlock_user(p, arg1, 0);
5622
                        unlock_user(p2, arg2, 0);
5623
                        unlock_user(p3, arg3, 0);
5624
                        break;
5625
                }
5626
#ifdef TARGET_NR_umount
5627
    case TARGET_NR_umount:
5628
        if (!(p = lock_user_string(arg1)))
5629
            goto efault;
5630
        ret = get_errno(umount(p));
5631
        unlock_user(p, arg1, 0);
5632
        break;
5633
#endif
5634
#ifdef TARGET_NR_stime /* not on alpha */
5635
    case TARGET_NR_stime:
5636
        {
5637
            time_t host_time;
5638
            if (get_user_sal(host_time, arg1))
5639
                goto efault;
5640
            ret = get_errno(stime(&host_time));
5641
        }
5642
        break;
5643
#endif
5644
    case TARGET_NR_ptrace:
5645
        goto unimplemented;
5646
#ifdef TARGET_NR_alarm /* not on alpha */
5647
    case TARGET_NR_alarm:
5648
        ret = alarm(arg1);
5649
        break;
5650
#endif
5651
#ifdef TARGET_NR_oldfstat
5652
    case TARGET_NR_oldfstat:
5653
        goto unimplemented;
5654
#endif
5655
#ifdef TARGET_NR_pause /* not on alpha */
5656
    case TARGET_NR_pause:
5657
        ret = get_errno(pause());
5658
        break;
5659
#endif
5660
#ifdef TARGET_NR_utime
5661
    case TARGET_NR_utime:
5662
        {
5663
            struct utimbuf tbuf, *host_tbuf;
5664
            struct target_utimbuf *target_tbuf;
5665
            if (arg2) {
5666
                if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
5667
                    goto efault;
5668
                tbuf.actime = tswapal(target_tbuf->actime);
5669
                tbuf.modtime = tswapal(target_tbuf->modtime);
5670
                unlock_user_struct(target_tbuf, arg2, 0);
5671
                host_tbuf = &tbuf;
5672
            } else {
5673
                host_tbuf = NULL;
5674
            }
5675
            if (!(p = lock_user_string(arg1)))
5676
                goto efault;
5677
            ret = get_errno(utime(p, host_tbuf));
5678
            unlock_user(p, arg1, 0);
5679
        }
5680
        break;
5681
#endif
5682
    case TARGET_NR_utimes:
5683
        {
5684
            struct timeval *tvp, tv[2];
5685
            if (arg2) {
5686
                if (copy_from_user_timeval(&tv[0], arg2)
5687
                    || copy_from_user_timeval(&tv[1],
5688
                                              arg2 + sizeof(struct target_timeval)))
5689
                    goto efault;
5690
                tvp = tv;
5691
            } else {
5692
                tvp = NULL;
5693
            }
5694
            if (!(p = lock_user_string(arg1)))
5695
                goto efault;
5696
            ret = get_errno(utimes(p, tvp));
5697
            unlock_user(p, arg1, 0);
5698
        }
5699
        break;
5700
#if defined(TARGET_NR_futimesat)
5701
    case TARGET_NR_futimesat:
5702
        {
5703
            struct timeval *tvp, tv[2];
5704
            if (arg3) {
5705
                if (copy_from_user_timeval(&tv[0], arg3)
5706
                    || copy_from_user_timeval(&tv[1],
5707
                                              arg3 + sizeof(struct target_timeval)))
5708
                    goto efault;
5709
                tvp = tv;
5710
            } else {
5711
                tvp = NULL;
5712
            }
5713
            if (!(p = lock_user_string(arg2)))
5714
                goto efault;
5715
            ret = get_errno(futimesat(arg1, path(p), tvp));
5716
            unlock_user(p, arg2, 0);
5717
        }
5718
        break;
5719
#endif
5720
#ifdef TARGET_NR_stty
5721
    case TARGET_NR_stty:
5722
        goto unimplemented;
5723
#endif
5724
#ifdef TARGET_NR_gtty
5725
    case TARGET_NR_gtty:
5726
        goto unimplemented;
5727
#endif
5728
    case TARGET_NR_access:
5729
        if (!(p = lock_user_string(arg1)))
5730
            goto efault;
5731
        ret = get_errno(access(path(p), arg2));
5732
        unlock_user(p, arg1, 0);
5733
        break;
5734
#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
5735
    case TARGET_NR_faccessat:
5736
        if (!(p = lock_user_string(arg2)))
5737
            goto efault;
5738
        ret = get_errno(faccessat(arg1, p, arg3, 0));
5739
        unlock_user(p, arg2, 0);
5740
        break;
5741
#endif
5742
#ifdef TARGET_NR_nice /* not on alpha */
5743
    case TARGET_NR_nice:
5744
        ret = get_errno(nice(arg1));
5745
        break;
5746
#endif
5747
#ifdef TARGET_NR_ftime
5748
    case TARGET_NR_ftime:
5749
        goto unimplemented;
5750
#endif
5751
    case TARGET_NR_sync:
5752
        sync();
5753
        ret = 0;
5754
        break;
5755
    case TARGET_NR_kill:
5756
        ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
5757
        break;
5758
    case TARGET_NR_rename:
5759
        {
5760
            void *p2;
5761
            p = lock_user_string(arg1);
5762
            p2 = lock_user_string(arg2);
5763
            if (!p || !p2)
5764
                ret = -TARGET_EFAULT;
5765
            else
5766
                ret = get_errno(rename(p, p2));
5767
            unlock_user(p2, arg2, 0);
5768
            unlock_user(p, arg1, 0);
5769
        }
5770
        break;
5771
#if defined(TARGET_NR_renameat)
5772
    case TARGET_NR_renameat:
5773
        {
5774
            void *p2;
5775
            p  = lock_user_string(arg2);
5776
            p2 = lock_user_string(arg4);
5777
            if (!p || !p2)
5778
                ret = -TARGET_EFAULT;
5779
            else
5780
                ret = get_errno(renameat(arg1, p, arg3, p2));
5781
            unlock_user(p2, arg4, 0);
5782
            unlock_user(p, arg2, 0);
5783
        }
5784
        break;
5785
#endif
5786
    case TARGET_NR_mkdir:
5787
        if (!(p = lock_user_string(arg1)))
5788
            goto efault;
5789
        ret = get_errno(mkdir(p, arg2));
5790
        unlock_user(p, arg1, 0);
5791
        break;
5792
#if defined(TARGET_NR_mkdirat)
5793
    case TARGET_NR_mkdirat:
5794
        if (!(p = lock_user_string(arg2)))
5795
            goto efault;
5796
        ret = get_errno(mkdirat(arg1, p, arg3));
5797
        unlock_user(p, arg2, 0);
5798
        break;
5799
#endif
5800
    case TARGET_NR_rmdir:
5801
        if (!(p = lock_user_string(arg1)))
5802
            goto efault;
5803
        ret = get_errno(rmdir(p));
5804
        unlock_user(p, arg1, 0);
5805
        break;
5806
    case TARGET_NR_dup:
5807
        ret = get_errno(dup(arg1));
5808
        break;
5809
    case TARGET_NR_pipe:
5810
        ret = do_pipe(cpu_env, arg1, 0, 0);
5811
        break;
5812
#ifdef TARGET_NR_pipe2
5813
    case TARGET_NR_pipe2:
5814
        ret = do_pipe(cpu_env, arg1,
5815
                      target_to_host_bitmask(arg2, fcntl_flags_tbl), 1);
5816
        break;
5817
#endif
5818
    case TARGET_NR_times:
5819
        {
5820
            struct target_tms *tmsp;
5821
            struct tms tms;
5822
            ret = get_errno(times(&tms));
5823
            if (arg1) {
5824
                tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
5825
                if (!tmsp)
5826
                    goto efault;
5827
                tmsp->tms_utime = tswapal(host_to_target_clock_t(tms.tms_utime));
5828
                tmsp->tms_stime = tswapal(host_to_target_clock_t(tms.tms_stime));
5829
                tmsp->tms_cutime = tswapal(host_to_target_clock_t(tms.tms_cutime));
5830
                tmsp->tms_cstime = tswapal(host_to_target_clock_t(tms.tms_cstime));
5831
            }
5832
            if (!is_error(ret))
5833
                ret = host_to_target_clock_t(ret);
5834
        }
5835
        break;
5836
#ifdef TARGET_NR_prof
5837
    case TARGET_NR_prof:
5838
        goto unimplemented;
5839
#endif
5840
#ifdef TARGET_NR_signal
5841
    case TARGET_NR_signal:
5842
        goto unimplemented;
5843
#endif
5844
    case TARGET_NR_acct:
5845
        if (arg1 == 0) {
5846
            ret = get_errno(acct(NULL));
5847
        } else {
5848
            if (!(p = lock_user_string(arg1)))
5849
                goto efault;
5850
            ret = get_errno(acct(path(p)));
5851
            unlock_user(p, arg1, 0);
5852
        }
5853
        break;
5854
#ifdef TARGET_NR_umount2
5855
    case TARGET_NR_umount2:
5856
        if (!(p = lock_user_string(arg1)))
5857
            goto efault;
5858
        ret = get_errno(umount2(p, arg2));
5859
        unlock_user(p, arg1, 0);
5860
        break;
5861
#endif
5862
#ifdef TARGET_NR_lock
5863
    case TARGET_NR_lock:
5864
        goto unimplemented;
5865
#endif
5866
    case TARGET_NR_ioctl:
5867
        ret = do_ioctl(arg1, arg2, arg3);
5868
        break;
5869
    case TARGET_NR_fcntl:
5870
        ret = do_fcntl(arg1, arg2, arg3);
5871
        break;
5872
#ifdef TARGET_NR_mpx
5873
    case TARGET_NR_mpx:
5874
        goto unimplemented;
5875
#endif
5876
    case TARGET_NR_setpgid:
5877
        ret = get_errno(setpgid(arg1, arg2));
5878
        break;
5879
#ifdef TARGET_NR_ulimit
5880
    case TARGET_NR_ulimit:
5881
        goto unimplemented;
5882
#endif
5883
#ifdef TARGET_NR_oldolduname
5884
    case TARGET_NR_oldolduname:
5885
        goto unimplemented;
5886
#endif
5887
    case TARGET_NR_umask:
5888
        ret = get_errno(umask(arg1));
5889
        break;
5890
    case TARGET_NR_chroot:
5891
        if (!(p = lock_user_string(arg1)))
5892
            goto efault;
5893
        ret = get_errno(chroot(p));
5894
        unlock_user(p, arg1, 0);
5895
        break;
5896
    case TARGET_NR_ustat:
5897
        goto unimplemented;
5898
    case TARGET_NR_dup2:
5899
        ret = get_errno(dup2(arg1, arg2));
5900
        break;
5901
#if defined(CONFIG_DUP3) && defined(TARGET_NR_dup3)
5902
    case TARGET_NR_dup3:
5903
        ret = get_errno(dup3(arg1, arg2, arg3));
5904
        break;
5905
#endif
5906
#ifdef TARGET_NR_getppid /* not on alpha */
5907
    case TARGET_NR_getppid:
5908
        ret = get_errno(getppid());
5909
        break;
5910
#endif
5911
    case TARGET_NR_getpgrp:
5912
        ret = get_errno(getpgrp());
5913
        break;
5914
    case TARGET_NR_setsid:
5915
        ret = get_errno(setsid());
5916
        break;
5917
#ifdef TARGET_NR_sigaction
5918
    case TARGET_NR_sigaction:
5919
        {
5920
#if defined(TARGET_ALPHA)
5921
            struct target_sigaction act, oact, *pact = 0;
5922
            struct target_old_sigaction *old_act;
5923
            if (arg2) {
5924
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
5925
                    goto efault;
5926
                act._sa_handler = old_act->_sa_handler;
5927
                target_siginitset(&act.sa_mask, old_act->sa_mask);
5928
                act.sa_flags = old_act->sa_flags;
5929
                act.sa_restorer = 0;
5930
                unlock_user_struct(old_act, arg2, 0);
5931
                pact = &act;
5932
            }
5933
            ret = get_errno(do_sigaction(arg1, pact, &oact));
5934
            if (!is_error(ret) && arg3) {
5935
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
5936
                    goto efault;
5937
                old_act->_sa_handler = oact._sa_handler;
5938
                old_act->sa_mask = oact.sa_mask.sig[0];
5939
                old_act->sa_flags = oact.sa_flags;
5940
                unlock_user_struct(old_act, arg3, 1);
5941
            }
5942
#elif defined(TARGET_MIPS)
5943
            struct target_sigaction act, oact, *pact, *old_act;
5944

    
5945
            if (arg2) {
5946
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
5947
                    goto efault;
5948
                act._sa_handler = old_act->_sa_handler;
5949
                target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
5950
                act.sa_flags = old_act->sa_flags;
5951
                unlock_user_struct(old_act, arg2, 0);
5952
                pact = &act;
5953
            } else {
5954
                pact = NULL;
5955
            }
5956

    
5957
            ret = get_errno(do_sigaction(arg1, pact, &oact));
5958

    
5959
            if (!is_error(ret) && arg3) {
5960
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
5961
                    goto efault;
5962
                old_act->_sa_handler = oact._sa_handler;
5963
                old_act->sa_flags = oact.sa_flags;
5964
                old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
5965
                old_act->sa_mask.sig[1] = 0;
5966
                old_act->sa_mask.sig[2] = 0;
5967
                old_act->sa_mask.sig[3] = 0;
5968
                unlock_user_struct(old_act, arg3, 1);
5969
            }
5970
#else
5971
            struct target_old_sigaction *old_act;
5972
            struct target_sigaction act, oact, *pact;
5973
            if (arg2) {
5974
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
5975
                    goto efault;
5976
                act._sa_handler = old_act->_sa_handler;
5977
                target_siginitset(&act.sa_mask, old_act->sa_mask);
5978
                act.sa_flags = old_act->sa_flags;
5979
                act.sa_restorer = old_act->sa_restorer;
5980
                unlock_user_struct(old_act, arg2, 0);
5981
                pact = &act;
5982
            } else {
5983
                pact = NULL;
5984
            }
5985
            ret = get_errno(do_sigaction(arg1, pact, &oact));
5986
            if (!is_error(ret) && arg3) {
5987
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
5988
                    goto efault;
5989
                old_act->_sa_handler = oact._sa_handler;
5990
                old_act->sa_mask = oact.sa_mask.sig[0];
5991
                old_act->sa_flags = oact.sa_flags;
5992
                old_act->sa_restorer = oact.sa_restorer;
5993
                unlock_user_struct(old_act, arg3, 1);
5994
            }
5995
#endif
5996
        }
5997
        break;
5998
#endif
5999
    case TARGET_NR_rt_sigaction:
6000
        {
6001
#if defined(TARGET_ALPHA)
6002
            struct target_sigaction act, oact, *pact = 0;
6003
            struct target_rt_sigaction *rt_act;
6004
            /* ??? arg4 == sizeof(sigset_t).  */
6005
            if (arg2) {
6006
                if (!lock_user_struct(VERIFY_READ, rt_act, arg2, 1))
6007
                    goto efault;
6008
                act._sa_handler = rt_act->_sa_handler;
6009
                act.sa_mask = rt_act->sa_mask;
6010
                act.sa_flags = rt_act->sa_flags;
6011
                act.sa_restorer = arg5;
6012
                unlock_user_struct(rt_act, arg2, 0);
6013
                pact = &act;
6014
            }
6015
            ret = get_errno(do_sigaction(arg1, pact, &oact));
6016
            if (!is_error(ret) && arg3) {
6017
                if (!lock_user_struct(VERIFY_WRITE, rt_act, arg3, 0))
6018
                    goto efault;
6019
                rt_act->_sa_handler = oact._sa_handler;
6020
                rt_act->sa_mask = oact.sa_mask;
6021
                rt_act->sa_flags = oact.sa_flags;
6022
                unlock_user_struct(rt_act, arg3, 1);
6023
            }
6024
#else
6025
            struct target_sigaction *act;
6026
            struct target_sigaction *oact;
6027

    
6028
            if (arg2) {
6029
                if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
6030
                    goto efault;
6031
            } else
6032
                act = NULL;
6033
            if (arg3) {
6034
                if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
6035
                    ret = -TARGET_EFAULT;
6036
                    goto rt_sigaction_fail;
6037
                }
6038
            } else
6039
                oact = NULL;
6040
            ret = get_errno(do_sigaction(arg1, act, oact));
6041
        rt_sigaction_fail:
6042
            if (act)
6043
                unlock_user_struct(act, arg2, 0);
6044
            if (oact)
6045
                unlock_user_struct(oact, arg3, 1);
6046
#endif
6047
        }
6048
        break;
6049
#ifdef TARGET_NR_sgetmask /* not on alpha */
6050
    case TARGET_NR_sgetmask:
6051
        {
6052
            sigset_t cur_set;
6053
            abi_ulong target_set;
6054
            sigprocmask(0, NULL, &cur_set);
6055
            host_to_target_old_sigset(&target_set, &cur_set);
6056
            ret = target_set;
6057
        }
6058
        break;
6059
#endif
6060
#ifdef TARGET_NR_ssetmask /* not on alpha */
6061
    case TARGET_NR_ssetmask:
6062
        {
6063
            sigset_t set, oset, cur_set;
6064
            abi_ulong target_set = arg1;
6065
            sigprocmask(0, NULL, &cur_set);
6066
            target_to_host_old_sigset(&set, &target_set);
6067
            sigorset(&set, &set, &cur_set);
6068
            sigprocmask(SIG_SETMASK, &set, &oset);
6069
            host_to_target_old_sigset(&target_set, &oset);
6070
            ret = target_set;
6071
        }
6072
        break;
6073
#endif
6074
#ifdef TARGET_NR_sigprocmask
6075
    case TARGET_NR_sigprocmask:
6076
        {
6077
#if defined(TARGET_ALPHA)
6078
            sigset_t set, oldset;
6079
            abi_ulong mask;
6080
            int how;
6081

    
6082
            switch (arg1) {
6083
            case TARGET_SIG_BLOCK:
6084
                how = SIG_BLOCK;
6085
                break;
6086
            case TARGET_SIG_UNBLOCK:
6087
                how = SIG_UNBLOCK;
6088
                break;
6089
            case TARGET_SIG_SETMASK:
6090
                how = SIG_SETMASK;
6091
                break;
6092
            default:
6093
                ret = -TARGET_EINVAL;
6094
                goto fail;
6095
            }
6096
            mask = arg2;
6097
            target_to_host_old_sigset(&set, &mask);
6098

    
6099
            ret = get_errno(sigprocmask(how, &set, &oldset));
6100
            if (!is_error(ret)) {
6101
                host_to_target_old_sigset(&mask, &oldset);
6102
                ret = mask;
6103
                ((CPUAlphaState *)cpu_env)->ir[IR_V0] = 0; /* force no error */
6104
            }
6105
#else
6106
            sigset_t set, oldset, *set_ptr;
6107
            int how;
6108

    
6109
            if (arg2) {
6110
                switch (arg1) {
6111
                case TARGET_SIG_BLOCK:
6112
                    how = SIG_BLOCK;
6113
                    break;
6114
                case TARGET_SIG_UNBLOCK:
6115
                    how = SIG_UNBLOCK;
6116
                    break;
6117
                case TARGET_SIG_SETMASK:
6118
                    how = SIG_SETMASK;
6119
                    break;
6120
                default:
6121
                    ret = -TARGET_EINVAL;
6122
                    goto fail;
6123
                }
6124
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
6125
                    goto efault;
6126
                target_to_host_old_sigset(&set, p);
6127
                unlock_user(p, arg2, 0);
6128
                set_ptr = &set;
6129
            } else {
6130
                how = 0;
6131
                set_ptr = NULL;
6132
            }
6133
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
6134
            if (!is_error(ret) && arg3) {
6135
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
6136
                    goto efault;
6137
                host_to_target_old_sigset(p, &oldset);
6138
                unlock_user(p, arg3, sizeof(target_sigset_t));
6139
            }
6140
#endif
6141
        }
6142
        break;
6143
#endif
6144
    case TARGET_NR_rt_sigprocmask:
6145
        {
6146
            int how = arg1;
6147
            sigset_t set, oldset, *set_ptr;
6148

    
6149
            if (arg2) {
6150
                switch(how) {
6151
                case TARGET_SIG_BLOCK:
6152
                    how = SIG_BLOCK;
6153
                    break;
6154
                case TARGET_SIG_UNBLOCK:
6155
                    how = SIG_UNBLOCK;
6156
                    break;
6157
                case TARGET_SIG_SETMASK:
6158
                    how = SIG_SETMASK;
6159
                    break;
6160
                default:
6161
                    ret = -TARGET_EINVAL;
6162
                    goto fail;
6163
                }
6164
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
6165
                    goto efault;
6166
                target_to_host_sigset(&set, p);
6167
                unlock_user(p, arg2, 0);
6168
                set_ptr = &set;
6169
            } else {
6170
                how = 0;
6171
                set_ptr = NULL;
6172
            }
6173
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
6174
            if (!is_error(ret) && arg3) {
6175
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
6176
                    goto efault;
6177
                host_to_target_sigset(p, &oldset);
6178
                unlock_user(p, arg3, sizeof(target_sigset_t));
6179
            }
6180
        }
6181
        break;
6182
#ifdef TARGET_NR_sigpending
6183
    case TARGET_NR_sigpending:
6184
        {
6185
            sigset_t set;
6186
            ret = get_errno(sigpending(&set));
6187
            if (!is_error(ret)) {
6188
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
6189
                    goto efault;
6190
                host_to_target_old_sigset(p, &set);
6191
                unlock_user(p, arg1, sizeof(target_sigset_t));
6192
            }
6193
        }
6194
        break;
6195
#endif
6196
    case TARGET_NR_rt_sigpending:
6197
        {
6198
            sigset_t set;
6199
            ret = get_errno(sigpending(&set));
6200
            if (!is_error(ret)) {
6201
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
6202
                    goto efault;
6203
                host_to_target_sigset(p, &set);
6204
                unlock_user(p, arg1, sizeof(target_sigset_t));
6205
            }
6206
        }
6207
        break;
6208
#ifdef TARGET_NR_sigsuspend
6209
    case TARGET_NR_sigsuspend:
6210
        {
6211
            sigset_t set;
6212
#if defined(TARGET_ALPHA)
6213
            abi_ulong mask = arg1;
6214
            target_to_host_old_sigset(&set, &mask);
6215
#else
6216
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
6217
                goto efault;
6218
            target_to_host_old_sigset(&set, p);
6219
            unlock_user(p, arg1, 0);
6220
#endif
6221
            ret = get_errno(sigsuspend(&set));
6222
        }
6223
        break;
6224
#endif
6225
    case TARGET_NR_rt_sigsuspend:
6226
        {
6227
            sigset_t set;
6228
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
6229
                goto efault;
6230
            target_to_host_sigset(&set, p);
6231
            unlock_user(p, arg1, 0);
6232
            ret = get_errno(sigsuspend(&set));
6233
        }
6234
        break;
6235
    case TARGET_NR_rt_sigtimedwait:
6236
        {
6237
            sigset_t set;
6238
            struct timespec uts, *puts;
6239
            siginfo_t uinfo;
6240

    
6241
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
6242
                goto efault;
6243
            target_to_host_sigset(&set, p);
6244
            unlock_user(p, arg1, 0);
6245
            if (arg3) {
6246
                puts = &uts;
6247
                target_to_host_timespec(puts, arg3);
6248
            } else {
6249
                puts = NULL;
6250
            }
6251
            ret = get_errno(sigtimedwait(&set, &uinfo, puts));
6252
            if (!is_error(ret) && arg2) {
6253
                if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
6254
                    goto efault;
6255
                host_to_target_siginfo(p, &uinfo);
6256
                unlock_user(p, arg2, sizeof(target_siginfo_t));
6257
            }
6258
        }
6259
        break;
6260
    case TARGET_NR_rt_sigqueueinfo:
6261
        {
6262
            siginfo_t uinfo;
6263
            if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
6264
                goto efault;
6265
            target_to_host_siginfo(&uinfo, p);
6266
            unlock_user(p, arg1, 0);
6267
            ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
6268
        }
6269
        break;
6270
#ifdef TARGET_NR_sigreturn
6271
    case TARGET_NR_sigreturn:
6272
        /* NOTE: ret is eax, so not transcoding must be done */
6273
        ret = do_sigreturn(cpu_env);
6274
        break;
6275
#endif
6276
    case TARGET_NR_rt_sigreturn:
6277
        /* NOTE: ret is eax, so not transcoding must be done */
6278
        ret = do_rt_sigreturn(cpu_env);
6279
        break;
6280
    case TARGET_NR_sethostname:
6281
        if (!(p = lock_user_string(arg1)))
6282
            goto efault;
6283
        ret = get_errno(sethostname(p, arg2));
6284
        unlock_user(p, arg1, 0);
6285
        break;
6286
    case TARGET_NR_setrlimit:
6287
        {
6288
            int resource = target_to_host_resource(arg1);
6289
            struct target_rlimit *target_rlim;
6290
            struct rlimit rlim;
6291
            if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
6292
                goto efault;
6293
            rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur);
6294
            rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max);
6295
            unlock_user_struct(target_rlim, arg2, 0);
6296
            ret = get_errno(setrlimit(resource, &rlim));
6297
        }
6298
        break;
6299
    case TARGET_NR_getrlimit:
6300
        {
6301
            int resource = target_to_host_resource(arg1);
6302
            struct target_rlimit *target_rlim;
6303
            struct rlimit rlim;
6304

    
6305
            ret = get_errno(getrlimit(resource, &rlim));
6306
            if (!is_error(ret)) {
6307
                if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
6308
                    goto efault;
6309
                target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
6310
                target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
6311
                unlock_user_struct(target_rlim, arg2, 1);
6312
            }
6313
        }
6314
        break;
6315
    case TARGET_NR_getrusage:
6316
        {
6317
            struct rusage rusage;
6318
            ret = get_errno(getrusage(arg1, &rusage));
6319
            if (!is_error(ret)) {
6320
                host_to_target_rusage(arg2, &rusage);
6321
            }
6322
        }
6323
        break;
6324
    case TARGET_NR_gettimeofday:
6325
        {
6326
            struct timeval tv;
6327
            ret = get_errno(gettimeofday(&tv, NULL));
6328
            if (!is_error(ret)) {
6329
                if (copy_to_user_timeval(arg1, &tv))
6330
                    goto efault;
6331
            }
6332
        }
6333
        break;
6334
    case TARGET_NR_settimeofday:
6335
        {
6336
            struct timeval tv;
6337
            if (copy_from_user_timeval(&tv, arg1))
6338
                goto efault;
6339
            ret = get_errno(settimeofday(&tv, NULL));
6340
        }
6341
        break;
6342
#if defined(TARGET_NR_select)
6343
    case TARGET_NR_select:
6344
#if defined(TARGET_S390X) || defined(TARGET_ALPHA)
6345
        ret = do_select(arg1, arg2, arg3, arg4, arg5);
6346
#else
6347
        {
6348
            struct target_sel_arg_struct *sel;
6349
            abi_ulong inp, outp, exp, tvp;
6350
            long nsel;
6351

    
6352
            if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
6353
                goto efault;
6354
            nsel = tswapal(sel->n);
6355
            inp = tswapal(sel->inp);
6356
            outp = tswapal(sel->outp);
6357
            exp = tswapal(sel->exp);
6358
            tvp = tswapal(sel->tvp);
6359
            unlock_user_struct(sel, arg1, 0);
6360
            ret = do_select(nsel, inp, outp, exp, tvp);
6361
        }
6362
#endif
6363
        break;
6364
#endif
6365
#ifdef TARGET_NR_pselect6
6366
    case TARGET_NR_pselect6:
6367
        {
6368
            abi_long rfd_addr, wfd_addr, efd_addr, n, ts_addr;
6369
            fd_set rfds, wfds, efds;
6370
            fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
6371
            struct timespec ts, *ts_ptr;
6372

    
6373
            /*
6374
             * The 6th arg is actually two args smashed together,
6375
             * so we cannot use the C library.
6376
             */
6377
            sigset_t set;
6378
            struct {
6379
                sigset_t *set;
6380
                size_t size;
6381
            } sig, *sig_ptr;
6382

    
6383
            abi_ulong arg_sigset, arg_sigsize, *arg7;
6384
            target_sigset_t *target_sigset;
6385

    
6386
            n = arg1;
6387
            rfd_addr = arg2;
6388
            wfd_addr = arg3;
6389
            efd_addr = arg4;
6390
            ts_addr = arg5;
6391

    
6392
            ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
6393
            if (ret) {
6394
                goto fail;
6395
            }
6396
            ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
6397
            if (ret) {
6398
                goto fail;
6399
            }
6400
            ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
6401
            if (ret) {
6402
                goto fail;
6403
            }
6404

    
6405
            /*
6406
             * This takes a timespec, and not a timeval, so we cannot
6407
             * use the do_select() helper ...
6408
             */
6409
            if (ts_addr) {
6410
                if (target_to_host_timespec(&ts, ts_addr)) {
6411
                    goto efault;
6412
                }
6413
                ts_ptr = &ts;
6414
            } else {
6415
                ts_ptr = NULL;
6416
            }
6417

    
6418
            /* Extract the two packed args for the sigset */
6419
            if (arg6) {
6420
                sig_ptr = &sig;
6421
                sig.size = _NSIG / 8;
6422

    
6423
                arg7 = lock_user(VERIFY_READ, arg6, sizeof(*arg7) * 2, 1);
6424
                if (!arg7) {
6425
                    goto efault;
6426
                }
6427
                arg_sigset = tswapal(arg7[0]);
6428
                arg_sigsize = tswapal(arg7[1]);
6429
                unlock_user(arg7, arg6, 0);
6430

    
6431
                if (arg_sigset) {
6432
                    sig.set = &set;
6433
                    if (arg_sigsize != sizeof(*target_sigset)) {
6434
                        /* Like the kernel, we enforce correct size sigsets */
6435
                        ret = -TARGET_EINVAL;
6436
                        goto fail;
6437
                    }
6438
                    target_sigset = lock_user(VERIFY_READ, arg_sigset,
6439
                                              sizeof(*target_sigset), 1);
6440
                    if (!target_sigset) {
6441
                        goto efault;
6442
                    }
6443
                    target_to_host_sigset(&set, target_sigset);
6444
                    unlock_user(target_sigset, arg_sigset, 0);
6445
                } else {
6446
                    sig.set = NULL;
6447
                }
6448
            } else {
6449
                sig_ptr = NULL;
6450
            }
6451

    
6452
            ret = get_errno(sys_pselect6(n, rfds_ptr, wfds_ptr, efds_ptr,
6453
                                         ts_ptr, sig_ptr));
6454

    
6455
            if (!is_error(ret)) {
6456
                if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
6457
                    goto efault;
6458
                if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
6459
                    goto efault;
6460
                if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
6461
                    goto efault;
6462

    
6463
                if (ts_addr && host_to_target_timespec(ts_addr, &ts))
6464
                    goto efault;
6465
            }
6466
        }
6467
        break;
6468
#endif
6469
    case TARGET_NR_symlink:
6470
        {
6471
            void *p2;
6472
            p = lock_user_string(arg1);
6473
            p2 = lock_user_string(arg2);
6474
            if (!p || !p2)
6475
                ret = -TARGET_EFAULT;
6476
            else
6477
                ret = get_errno(symlink(p, p2));
6478
            unlock_user(p2, arg2, 0);
6479
            unlock_user(p, arg1, 0);
6480
        }
6481
        break;
6482
#if defined(TARGET_NR_symlinkat)
6483
    case TARGET_NR_symlinkat:
6484
        {
6485
            void *p2;
6486
            p  = lock_user_string(arg1);
6487
            p2 = lock_user_string(arg3);
6488
            if (!p || !p2)
6489
                ret = -TARGET_EFAULT;
6490
            else
6491
                ret = get_errno(symlinkat(p, arg2, p2));
6492
            unlock_user(p2, arg3, 0);
6493
            unlock_user(p, arg1, 0);
6494
        }
6495
        break;
6496
#endif
6497
#ifdef TARGET_NR_oldlstat
6498
    case TARGET_NR_oldlstat:
6499
        goto unimplemented;
6500
#endif
6501
    case TARGET_NR_readlink:
6502
        {
6503
            void *p2;
6504
            p = lock_user_string(arg1);
6505
            p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
6506
            if (!p || !p2) {
6507
                ret = -TARGET_EFAULT;
6508
            } else if (is_proc_myself((const char *)p, "exe")) {
6509
                char real[PATH_MAX], *temp;
6510
                temp = realpath(exec_path, real);
6511
                ret = temp == NULL ? get_errno(-1) : strlen(real) ;
6512
                snprintf((char *)p2, arg3, "%s", real);
6513
            } else {
6514
                ret = get_errno(readlink(path(p), p2, arg3));
6515
            }
6516
            unlock_user(p2, arg2, ret);
6517
            unlock_user(p, arg1, 0);
6518
        }
6519
        break;
6520
#if defined(TARGET_NR_readlinkat)
6521
    case TARGET_NR_readlinkat:
6522
        {
6523
            void *p2;
6524
            p  = lock_user_string(arg2);
6525
            p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
6526
            if (!p || !p2) {
6527
                ret = -TARGET_EFAULT;
6528
            } else if (is_proc_myself((const char *)p, "exe")) {
6529
                char real[PATH_MAX], *temp;
6530
                temp = realpath(exec_path, real);
6531
                ret = temp == NULL ? get_errno(-1) : strlen(real) ;
6532
                snprintf((char *)p2, arg4, "%s", real);
6533
            } else {
6534
                ret = get_errno(readlinkat(arg1, path(p), p2, arg4));
6535
            }
6536
            unlock_user(p2, arg3, ret);
6537
            unlock_user(p, arg2, 0);
6538
        }
6539
        break;
6540
#endif
6541
#ifdef TARGET_NR_uselib
6542
    case TARGET_NR_uselib:
6543
        goto unimplemented;
6544
#endif
6545
#ifdef TARGET_NR_swapon
6546
    case TARGET_NR_swapon:
6547
        if (!(p = lock_user_string(arg1)))
6548
            goto efault;
6549
        ret = get_errno(swapon(p, arg2));
6550
        unlock_user(p, arg1, 0);
6551
        break;
6552
#endif
6553
    case TARGET_NR_reboot:
6554
        if (arg3 == LINUX_REBOOT_CMD_RESTART2) {
6555
           /* arg4 must be ignored in all other cases */
6556
           p = lock_user_string(arg4);
6557
           if (!p) {
6558
              goto efault;
6559
           }
6560
           ret = get_errno(reboot(arg1, arg2, arg3, p));
6561
           unlock_user(p, arg4, 0);
6562
        } else {
6563
           ret = get_errno(reboot(arg1, arg2, arg3, NULL));
6564
        }
6565
        break;
6566
#ifdef TARGET_NR_readdir
6567
    case TARGET_NR_readdir:
6568
        goto unimplemented;
6569
#endif
6570
#ifdef TARGET_NR_mmap
6571
    case TARGET_NR_mmap:
6572
#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || \
6573
    (defined(TARGET_ARM) && defined(TARGET_ABI32)) || \
6574
    defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) \
6575
    || defined(TARGET_S390X)
6576
        {
6577
            abi_ulong *v;
6578
            abi_ulong v1, v2, v3, v4, v5, v6;
6579
            if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
6580
                goto efault;
6581
            v1 = tswapal(v[0]);
6582
            v2 = tswapal(v[1]);
6583
            v3 = tswapal(v[2]);
6584
            v4 = tswapal(v[3]);
6585
            v5 = tswapal(v[4]);
6586
            v6 = tswapal(v[5]);
6587
            unlock_user(v, arg1, 0);
6588
            ret = get_errno(target_mmap(v1, v2, v3,
6589
                                        target_to_host_bitmask(v4, mmap_flags_tbl),
6590
                                        v5, v6));
6591
        }
6592
#else
6593
        ret = get_errno(target_mmap(arg1, arg2, arg3,
6594
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
6595
                                    arg5,
6596
                                    arg6));
6597
#endif
6598
        break;
6599
#endif
6600
#ifdef TARGET_NR_mmap2
6601
    case TARGET_NR_mmap2:
6602
#ifndef MMAP_SHIFT
6603
#define MMAP_SHIFT 12
6604
#endif
6605
        ret = get_errno(target_mmap(arg1, arg2, arg3,
6606
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
6607
                                    arg5,
6608
                                    arg6 << MMAP_SHIFT));
6609
        break;
6610
#endif
6611
    case TARGET_NR_munmap:
6612
        ret = get_errno(target_munmap(arg1, arg2));
6613
        break;
6614
    case TARGET_NR_mprotect:
6615
        {
6616
            TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
6617
            /* Special hack to detect libc making the stack executable.  */
6618
            if ((arg3 & PROT_GROWSDOWN)
6619
                && arg1 >= ts->info->stack_limit
6620
                && arg1 <= ts->info->start_stack) {
6621
                arg3 &= ~PROT_GROWSDOWN;
6622
                arg2 = arg2 + arg1 - ts->info->stack_limit;
6623
                arg1 = ts->info->stack_limit;
6624
            }
6625
        }
6626
        ret = get_errno(target_mprotect(arg1, arg2, arg3));
6627
        break;
6628
#ifdef TARGET_NR_mremap
6629
    case TARGET_NR_mremap:
6630
        ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
6631
        break;
6632
#endif
6633
        /* ??? msync/mlock/munlock are broken for softmmu.  */
6634
#ifdef TARGET_NR_msync
6635
    case TARGET_NR_msync:
6636
        ret = get_errno(msync(g2h(arg1), arg2, arg3));
6637
        break;
6638
#endif
6639
#ifdef TARGET_NR_mlock
6640
    case TARGET_NR_mlock:
6641
        ret = get_errno(mlock(g2h(arg1), arg2));
6642
        break;
6643
#endif
6644
#ifdef TARGET_NR_munlock
6645
    case TARGET_NR_munlock:
6646
        ret = get_errno(munlock(g2h(arg1), arg2));
6647
        break;
6648
#endif
6649
#ifdef TARGET_NR_mlockall
6650
    case TARGET_NR_mlockall:
6651
        ret = get_errno(mlockall(arg1));
6652
        break;
6653
#endif
6654
#ifdef TARGET_NR_munlockall
6655
    case TARGET_NR_munlockall:
6656
        ret = get_errno(munlockall());
6657
        break;
6658
#endif
6659
    case TARGET_NR_truncate:
6660
        if (!(p = lock_user_string(arg1)))
6661
            goto efault;
6662
        ret = get_errno(truncate(p, arg2));
6663
        unlock_user(p, arg1, 0);
6664
        break;
6665
    case TARGET_NR_ftruncate:
6666
        ret = get_errno(ftruncate(arg1, arg2));
6667
        break;
6668
    case TARGET_NR_fchmod:
6669
        ret = get_errno(fchmod(arg1, arg2));
6670
        break;
6671
#if defined(TARGET_NR_fchmodat)
6672
    case TARGET_NR_fchmodat:
6673
        if (!(p = lock_user_string(arg2)))
6674
            goto efault;
6675
        ret = get_errno(fchmodat(arg1, p, arg3, 0));
6676
        unlock_user(p, arg2, 0);
6677
        break;
6678
#endif
6679
    case TARGET_NR_getpriority:
6680
        /* Note that negative values are valid for getpriority, so we must
6681
           differentiate based on errno settings.  */
6682
        errno = 0;
6683
        ret = getpriority(arg1, arg2);
6684
        if (ret == -1 && errno != 0) {
6685
            ret = -host_to_target_errno(errno);
6686
            break;
6687
        }
6688
#ifdef TARGET_ALPHA
6689
        /* Return value is the unbiased priority.  Signal no error.  */
6690
        ((CPUAlphaState *)cpu_env)->ir[IR_V0] = 0;
6691
#else
6692
        /* Return value is a biased priority to avoid negative numbers.  */
6693
        ret = 20 - ret;
6694
#endif
6695
        break;
6696
    case TARGET_NR_setpriority:
6697
        ret = get_errno(setpriority(arg1, arg2, arg3));
6698
        break;
6699
#ifdef TARGET_NR_profil
6700
    case TARGET_NR_profil:
6701
        goto unimplemented;
6702
#endif
6703
    case TARGET_NR_statfs:
6704
        if (!(p = lock_user_string(arg1)))
6705
            goto efault;
6706
        ret = get_errno(statfs(path(p), &stfs));
6707
        unlock_user(p, arg1, 0);
6708
    convert_statfs:
6709
        if (!is_error(ret)) {
6710
            struct target_statfs *target_stfs;
6711

    
6712
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
6713
                goto efault;
6714
            __put_user(stfs.f_type, &target_stfs->f_type);
6715
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
6716
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
6717
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
6718
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
6719
            __put_user(stfs.f_files, &target_stfs->f_files);
6720
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
6721
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
6722
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
6723
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
6724
            __put_user(stfs.f_frsize, &target_stfs->f_frsize);
6725
            memset(target_stfs->f_spare, 0, sizeof(target_stfs->f_spare));
6726
            unlock_user_struct(target_stfs, arg2, 1);
6727
        }
6728
        break;
6729
    case TARGET_NR_fstatfs:
6730
        ret = get_errno(fstatfs(arg1, &stfs));
6731
        goto convert_statfs;
6732
#ifdef TARGET_NR_statfs64
6733
    case TARGET_NR_statfs64:
6734
        if (!(p = lock_user_string(arg1)))
6735
            goto efault;
6736
        ret = get_errno(statfs(path(p), &stfs));
6737
        unlock_user(p, arg1, 0);
6738
    convert_statfs64:
6739
        if (!is_error(ret)) {
6740
            struct target_statfs64 *target_stfs;
6741

    
6742
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
6743
                goto efault;
6744
            __put_user(stfs.f_type, &target_stfs->f_type);
6745
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
6746
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
6747
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
6748
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
6749
            __put_user(stfs.f_files, &target_stfs->f_files);
6750
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
6751
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
6752
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
6753
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
6754
            __put_user(stfs.f_frsize, &target_stfs->f_frsize);
6755
            memset(target_stfs->f_spare, 0, sizeof(target_stfs->f_spare));
6756
            unlock_user_struct(target_stfs, arg3, 1);
6757
        }
6758
        break;
6759
    case TARGET_NR_fstatfs64:
6760
        ret = get_errno(fstatfs(arg1, &stfs));
6761
        goto convert_statfs64;
6762
#endif
6763
#ifdef TARGET_NR_ioperm
6764
    case TARGET_NR_ioperm:
6765
        goto unimplemented;
6766
#endif
6767
#ifdef TARGET_NR_socketcall
6768
    case TARGET_NR_socketcall:
6769
        ret = do_socketcall(arg1, arg2);
6770
        break;
6771
#endif
6772
#ifdef TARGET_NR_accept
6773
    case TARGET_NR_accept:
6774
        ret = do_accept4(arg1, arg2, arg3, 0);
6775
        break;
6776
#endif
6777
#ifdef TARGET_NR_accept4
6778
    case TARGET_NR_accept4:
6779
#ifdef CONFIG_ACCEPT4
6780
        ret = do_accept4(arg1, arg2, arg3, arg4);
6781
#else
6782
        goto unimplemented;
6783
#endif
6784
        break;
6785
#endif
6786
#ifdef TARGET_NR_bind
6787
    case TARGET_NR_bind:
6788
        ret = do_bind(arg1, arg2, arg3);
6789
        break;
6790
#endif
6791
#ifdef TARGET_NR_connect
6792
    case TARGET_NR_connect:
6793
        ret = do_connect(arg1, arg2, arg3);
6794
        break;
6795
#endif
6796
#ifdef TARGET_NR_getpeername
6797
    case TARGET_NR_getpeername:
6798
        ret = do_getpeername(arg1, arg2, arg3);
6799
        break;
6800
#endif
6801
#ifdef TARGET_NR_getsockname
6802
    case TARGET_NR_getsockname:
6803
        ret = do_getsockname(arg1, arg2, arg3);
6804
        break;
6805
#endif
6806
#ifdef TARGET_NR_getsockopt
6807
    case TARGET_NR_getsockopt:
6808
        ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
6809
        break;
6810
#endif
6811
#ifdef TARGET_NR_listen
6812
    case TARGET_NR_listen:
6813
        ret = get_errno(listen(arg1, arg2));
6814
        break;
6815
#endif
6816
#ifdef TARGET_NR_recv
6817
    case TARGET_NR_recv:
6818
        ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
6819
        break;
6820
#endif
6821
#ifdef TARGET_NR_recvfrom
6822
    case TARGET_NR_recvfrom:
6823
        ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
6824
        break;
6825
#endif
6826
#ifdef TARGET_NR_recvmsg
6827
    case TARGET_NR_recvmsg:
6828
        ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
6829
        break;
6830
#endif
6831
#ifdef TARGET_NR_send
6832
    case TARGET_NR_send:
6833
        ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
6834
        break;
6835
#endif
6836
#ifdef TARGET_NR_sendmsg
6837
    case TARGET_NR_sendmsg:
6838
        ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
6839
        break;
6840
#endif
6841
#ifdef TARGET_NR_sendto
6842
    case TARGET_NR_sendto:
6843
        ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
6844
        break;
6845
#endif
6846
#ifdef TARGET_NR_shutdown
6847
    case TARGET_NR_shutdown:
6848
        ret = get_errno(shutdown(arg1, arg2));
6849
        break;
6850
#endif
6851
#ifdef TARGET_NR_socket
6852
    case TARGET_NR_socket:
6853
        ret = do_socket(arg1, arg2, arg3);
6854
        break;
6855
#endif
6856
#ifdef TARGET_NR_socketpair
6857
    case TARGET_NR_socketpair:
6858
        ret = do_socketpair(arg1, arg2, arg3, arg4);
6859
        break;
6860
#endif
6861
#ifdef TARGET_NR_setsockopt
6862
    case TARGET_NR_setsockopt:
6863
        ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
6864
        break;
6865
#endif
6866

    
6867
    case TARGET_NR_syslog:
6868
        if (!(p = lock_user_string(arg2)))
6869
            goto efault;
6870
        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
6871
        unlock_user(p, arg2, 0);
6872
        break;
6873

    
6874
    case TARGET_NR_setitimer:
6875
        {
6876
            struct itimerval value, ovalue, *pvalue;
6877

    
6878
            if (arg2) {
6879
                pvalue = &value;
6880
                if (copy_from_user_timeval(&pvalue->it_interval, arg2)
6881
                    || copy_from_user_timeval(&pvalue->it_value,
6882
                                              arg2 + sizeof(struct target_timeval)))
6883
                    goto efault;
6884
            } else {
6885
                pvalue = NULL;
6886
            }
6887
            ret = get_errno(setitimer(arg1, pvalue, &ovalue));
6888
            if (!is_error(ret) && arg3) {
6889
                if (copy_to_user_timeval(arg3,
6890
                                         &ovalue.it_interval)
6891
                    || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
6892
                                            &ovalue.it_value))
6893
                    goto efault;
6894
            }
6895
        }
6896
        break;
6897
    case TARGET_NR_getitimer:
6898
        {
6899
            struct itimerval value;
6900

    
6901
            ret = get_errno(getitimer(arg1, &value));
6902
            if (!is_error(ret) && arg2) {
6903
                if (copy_to_user_timeval(arg2,
6904
                                         &value.it_interval)
6905
                    || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
6906
                                            &value.it_value))
6907
                    goto efault;
6908
            }
6909
        }
6910
        break;
6911
    case TARGET_NR_stat:
6912
        if (!(p = lock_user_string(arg1)))
6913
            goto efault;
6914
        ret = get_errno(stat(path(p), &st));
6915
        unlock_user(p, arg1, 0);
6916
        goto do_stat;
6917
    case TARGET_NR_lstat:
6918
        if (!(p = lock_user_string(arg1)))
6919
            goto efault;
6920
        ret = get_errno(lstat(path(p), &st));
6921
        unlock_user(p, arg1, 0);
6922
        goto do_stat;
6923
    case TARGET_NR_fstat:
6924
        {
6925
            ret = get_errno(fstat(arg1, &st));
6926
        do_stat:
6927
            if (!is_error(ret)) {
6928
                struct target_stat *target_st;
6929

    
6930
                if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
6931
                    goto efault;
6932
                memset(target_st, 0, sizeof(*target_st));
6933
                __put_user(st.st_dev, &target_st->st_dev);
6934
                __put_user(st.st_ino, &target_st->st_ino);
6935
                __put_user(st.st_mode, &target_st->st_mode);
6936
                __put_user(st.st_uid, &target_st->st_uid);
6937
                __put_user(st.st_gid, &target_st->st_gid);
6938
                __put_user(st.st_nlink, &target_st->st_nlink);
6939
                __put_user(st.st_rdev, &target_st->st_rdev);
6940
                __put_user(st.st_size, &target_st->st_size);
6941
                __put_user(st.st_blksize, &target_st->st_blksize);
6942
                __put_user(st.st_blocks, &target_st->st_blocks);
6943
                __put_user(st.st_atime, &target_st->target_st_atime);
6944
                __put_user(st.st_mtime, &target_st->target_st_mtime);
6945
                __put_user(st.st_ctime, &target_st->target_st_ctime);
6946
                unlock_user_struct(target_st, arg2, 1);
6947
            }
6948
        }
6949
        break;
6950
#ifdef TARGET_NR_olduname
6951
    case TARGET_NR_olduname:
6952
        goto unimplemented;
6953
#endif
6954
#ifdef TARGET_NR_iopl
6955
    case TARGET_NR_iopl:
6956
        goto unimplemented;
6957
#endif
6958
    case TARGET_NR_vhangup:
6959
        ret = get_errno(vhangup());
6960
        break;
6961
#ifdef TARGET_NR_idle
6962
    case TARGET_NR_idle:
6963
        goto unimplemented;
6964
#endif
6965
#ifdef TARGET_NR_syscall
6966
    case TARGET_NR_syscall:
6967
        ret = do_syscall(cpu_env, arg1 & 0xffff, arg2, arg3, arg4, arg5,
6968
                         arg6, arg7, arg8, 0);
6969
        break;
6970
#endif
6971
    case TARGET_NR_wait4:
6972
        {
6973
            int status;
6974
            abi_long status_ptr = arg2;
6975
            struct rusage rusage, *rusage_ptr;
6976
            abi_ulong target_rusage = arg4;
6977
            if (target_rusage)
6978
                rusage_ptr = &rusage;
6979
            else
6980
                rusage_ptr = NULL;
6981
            ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
6982
            if (!is_error(ret)) {
6983
                if (status_ptr && ret) {
6984
                    status = host_to_target_waitstatus(status);
6985
                    if (put_user_s32(status, status_ptr))
6986
                        goto efault;
6987
                }
6988
                if (target_rusage)
6989
                    host_to_target_rusage(target_rusage, &rusage);
6990
            }
6991
        }
6992
        break;
6993
#ifdef TARGET_NR_swapoff
6994
    case TARGET_NR_swapoff:
6995
        if (!(p = lock_user_string(arg1)))
6996
            goto efault;
6997
        ret = get_errno(swapoff(p));
6998
        unlock_user(p, arg1, 0);
6999
        break;
7000
#endif
7001
    case TARGET_NR_sysinfo:
7002
        {
7003
            struct target_sysinfo *target_value;
7004
            struct sysinfo value;
7005
            ret = get_errno(sysinfo(&value));
7006
            if (!is_error(ret) && arg1)
7007
            {
7008
                if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
7009
                    goto efault;
7010
                __put_user(value.uptime, &target_value->uptime);
7011
                __put_user(value.loads[0], &target_value->loads[0]);
7012
                __put_user(value.loads[1], &target_value->loads[1]);
7013
                __put_user(value.loads[2], &target_value->loads[2]);
7014
                __put_user(value.totalram, &target_value->totalram);
7015
                __put_user(value.freeram, &target_value->freeram);
7016
                __put_user(value.sharedram, &target_value->sharedram);
7017
                __put_user(value.bufferram, &target_value->bufferram);
7018
                __put_user(value.totalswap, &target_value->totalswap);
7019
                __put_user(value.freeswap, &target_value->freeswap);
7020
                __put_user(value.procs, &target_value->procs);
7021
                __put_user(value.totalhigh, &target_value->totalhigh);
7022
                __put_user(value.freehigh, &target_value->freehigh);
7023
                __put_user(value.mem_unit, &target_value->mem_unit);
7024
                unlock_user_struct(target_value, arg1, 1);
7025
            }
7026
        }
7027
        break;
7028
#ifdef TARGET_NR_ipc
7029
    case TARGET_NR_ipc:
7030
        ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
7031
        break;
7032
#endif
7033
#ifdef TARGET_NR_semget
7034
    case TARGET_NR_semget:
7035
        ret = get_errno(semget(arg1, arg2, arg3));
7036
        break;
7037
#endif
7038
#ifdef TARGET_NR_semop
7039
    case TARGET_NR_semop:
7040
        ret = do_semop(arg1, arg2, arg3);
7041
        break;
7042
#endif
7043
#ifdef TARGET_NR_semctl
7044
    case TARGET_NR_semctl:
7045
        ret = do_semctl(arg1, arg2, arg3, (union target_semun)(abi_ulong)arg4);
7046
        break;
7047
#endif
7048
#ifdef TARGET_NR_msgctl
7049
    case TARGET_NR_msgctl:
7050
        ret = do_msgctl(arg1, arg2, arg3);
7051
        break;
7052
#endif
7053
#ifdef TARGET_NR_msgget
7054
    case TARGET_NR_msgget:
7055
        ret = get_errno(msgget(arg1, arg2));
7056
        break;
7057
#endif
7058
#ifdef TARGET_NR_msgrcv
7059
    case TARGET_NR_msgrcv:
7060
        ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
7061
        break;
7062
#endif
7063
#ifdef TARGET_NR_msgsnd
7064
    case TARGET_NR_msgsnd:
7065
        ret = do_msgsnd(arg1, arg2, arg3, arg4);
7066
        break;
7067
#endif
7068
#ifdef TARGET_NR_shmget
7069
    case TARGET_NR_shmget:
7070
        ret = get_errno(shmget(arg1, arg2, arg3));
7071
        break;
7072
#endif
7073
#ifdef TARGET_NR_shmctl
7074
    case TARGET_NR_shmctl:
7075
        ret = do_shmctl(arg1, arg2, arg3);
7076
        break;
7077
#endif
7078
#ifdef TARGET_NR_shmat
7079
    case TARGET_NR_shmat:
7080
        ret = do_shmat(arg1, arg2, arg3);
7081
        break;
7082
#endif
7083
#ifdef TARGET_NR_shmdt
7084
    case TARGET_NR_shmdt:
7085
        ret = do_shmdt(arg1);
7086
        break;
7087
#endif
7088
    case TARGET_NR_fsync:
7089
        ret = get_errno(fsync(arg1));
7090
        break;
7091
    case TARGET_NR_clone:
7092
        /* Linux manages to have three different orderings for its
7093
         * arguments to clone(); the BACKWARDS and BACKWARDS2 defines
7094
         * match the kernel's CONFIG_CLONE_* settings.
7095
         * Microblaze is further special in that it uses a sixth
7096
         * implicit argument to clone for the TLS pointer.
7097
         */
7098
#if defined(TARGET_MICROBLAZE)
7099
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg4, arg6, arg5));
7100
#elif defined(TARGET_CLONE_BACKWARDS)
7101
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
7102
#elif defined(TARGET_CLONE_BACKWARDS2)
7103
        ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg5, arg4));
7104
#else
7105
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
7106
#endif
7107
        break;
7108
#ifdef __NR_exit_group
7109
        /* new thread calls */
7110
    case TARGET_NR_exit_group:
7111
#ifdef TARGET_GPROF
7112
        _mcleanup();
7113
#endif
7114
        gdb_exit(cpu_env, arg1);
7115
        ret = get_errno(exit_group(arg1));
7116
        break;
7117
#endif
7118
    case TARGET_NR_setdomainname:
7119
        if (!(p = lock_user_string(arg1)))
7120
            goto efault;
7121
        ret = get_errno(setdomainname(p, arg2));
7122
        unlock_user(p, arg1, 0);
7123
        break;
7124
    case TARGET_NR_uname:
7125
        /* no need to transcode because we use the linux syscall */
7126
        {
7127
            struct new_utsname * buf;
7128

    
7129
            if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
7130
                goto efault;
7131
            ret = get_errno(sys_uname(buf));
7132
            if (!is_error(ret)) {
7133
                /* Overrite the native machine name with whatever is being
7134
                   emulated. */
7135
                strcpy (buf->machine, cpu_to_uname_machine(cpu_env));
7136
                /* Allow the user to override the reported release.  */
7137
                if (qemu_uname_release && *qemu_uname_release)
7138
                  strcpy (buf->release, qemu_uname_release);
7139
            }
7140
            unlock_user_struct(buf, arg1, 1);
7141
        }
7142
        break;
7143
#ifdef TARGET_I386
7144
    case TARGET_NR_modify_ldt:
7145
        ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
7146
        break;
7147
#if !defined(TARGET_X86_64)
7148
    case TARGET_NR_vm86old:
7149
        goto unimplemented;
7150
    case TARGET_NR_vm86:
7151
        ret = do_vm86(cpu_env, arg1, arg2);
7152
        break;
7153
#endif
7154
#endif
7155
    case TARGET_NR_adjtimex:
7156
        goto unimplemented;
7157
#ifdef TARGET_NR_create_module
7158
    case TARGET_NR_create_module:
7159
#endif
7160
    case TARGET_NR_init_module:
7161
    case TARGET_NR_delete_module:
7162
#ifdef TARGET_NR_get_kernel_syms
7163
    case TARGET_NR_get_kernel_syms:
7164
#endif
7165
        goto unimplemented;
7166
    case TARGET_NR_quotactl:
7167
        goto unimplemented;
7168
    case TARGET_NR_getpgid:
7169
        ret = get_errno(getpgid(arg1));
7170
        break;
7171
    case TARGET_NR_fchdir:
7172
        ret = get_errno(fchdir(arg1));
7173
        break;
7174
#ifdef TARGET_NR_bdflush /* not on x86_64 */
7175
    case TARGET_NR_bdflush:
7176
        goto unimplemented;
7177
#endif
7178
#ifdef TARGET_NR_sysfs
7179
    case TARGET_NR_sysfs:
7180
        goto unimplemented;
7181
#endif
7182
    case TARGET_NR_personality:
7183
        ret = get_errno(personality(arg1));
7184
        break;
7185
#ifdef TARGET_NR_afs_syscall
7186
    case TARGET_NR_afs_syscall:
7187
        goto unimplemented;
7188
#endif
7189
#ifdef TARGET_NR__llseek /* Not on alpha */
7190
    case TARGET_NR__llseek:
7191
        {
7192
            int64_t res;
7193
#if !defined(__NR_llseek)
7194
            res = lseek(arg1, ((uint64_t)arg2 << 32) | arg3, arg5);
7195
            if (res == -1) {
7196
                ret = get_errno(res);
7197
            } else {
7198
                ret = 0;
7199
            }
7200
#else
7201
            ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
7202
#endif
7203
            if ((ret == 0) && put_user_s64(res, arg4)) {
7204
                goto efault;
7205
            }
7206
        }
7207
        break;
7208
#endif
7209
    case TARGET_NR_getdents:
7210
#ifdef __NR_getdents
7211
#if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
7212
        {
7213
            struct target_dirent *target_dirp;
7214
            struct linux_dirent *dirp;
7215
            abi_long count = arg3;
7216

    
7217
            dirp = malloc(count);
7218
            if (!dirp) {
7219
                ret = -TARGET_ENOMEM;
7220
                goto fail;
7221
            }
7222

    
7223
            ret = get_errno(sys_getdents(arg1, dirp, count));
7224
            if (!is_error(ret)) {
7225
                struct linux_dirent *de;
7226
                struct target_dirent *tde;
7227
                int len = ret;
7228
                int reclen, treclen;
7229
                int count1, tnamelen;
7230

    
7231
                count1 = 0;
7232
                de = dirp;
7233
                if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
7234
                    goto efault;
7235
                tde = target_dirp;
7236
                while (len > 0) {
7237
                    reclen = de->d_reclen;
7238
                    tnamelen = reclen - offsetof(struct linux_dirent, d_name);
7239
                    assert(tnamelen >= 0);
7240
                    treclen = tnamelen + offsetof(struct target_dirent, d_name);
7241
                    assert(count1 + treclen <= count);
7242
                    tde->d_reclen = tswap16(treclen);
7243
                    tde->d_ino = tswapal(de->d_ino);
7244
                    tde->d_off = tswapal(de->d_off);
7245
                    memcpy(tde->d_name, de->d_name, tnamelen);
7246
                    de = (struct linux_dirent *)((char *)de + reclen);
7247
                    len -= reclen;
7248
                    tde = (struct target_dirent *)((char *)tde + treclen);
7249
                    count1 += treclen;
7250
                }
7251
                ret = count1;
7252
                unlock_user(target_dirp, arg2, ret);
7253
            }
7254
            free(dirp);
7255
        }
7256
#else
7257
        {
7258
            struct linux_dirent *dirp;
7259
            abi_long count = arg3;
7260

    
7261
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
7262
                goto efault;
7263
            ret = get_errno(sys_getdents(arg1, dirp, count));
7264
            if (!is_error(ret)) {
7265
                struct linux_dirent *de;
7266
                int len = ret;
7267
                int reclen;
7268
                de = dirp;
7269
                while (len > 0) {
7270
                    reclen = de->d_reclen;
7271
                    if (reclen > len)
7272
                        break;
7273
                    de->d_reclen = tswap16(reclen);
7274
                    tswapls(&de->d_ino);
7275
                    tswapls(&de->d_off);
7276
                    de = (struct linux_dirent *)((char *)de + reclen);
7277
                    len -= reclen;
7278
                }
7279
            }
7280
            unlock_user(dirp, arg2, ret);
7281
        }
7282
#endif
7283
#else
7284
        /* Implement getdents in terms of getdents64 */
7285
        {
7286
            struct linux_dirent64 *dirp;
7287
            abi_long count = arg3;
7288

    
7289
            dirp = lock_user(VERIFY_WRITE, arg2, count, 0);
7290
            if (!dirp) {
7291
                goto efault;
7292
            }
7293
            ret = get_errno(sys_getdents64(arg1, dirp, count));
7294
            if (!is_error(ret)) {
7295
                /* Convert the dirent64 structs to target dirent.  We do this
7296
                 * in-place, since we can guarantee that a target_dirent is no
7297
                 * larger than a dirent64; however this means we have to be
7298
                 * careful to read everything before writing in the new format.
7299
                 */
7300
                struct linux_dirent64 *de;
7301
                struct target_dirent *tde;
7302
                int len = ret;
7303
                int tlen = 0;
7304

    
7305
                de = dirp;
7306
                tde = (struct target_dirent *)dirp;
7307
                while (len > 0) {
7308
                    int namelen, treclen;
7309
                    int reclen = de->d_reclen;
7310
                    uint64_t ino = de->d_ino;
7311
                    int64_t off = de->d_off;
7312
                    uint8_t type = de->d_type;
7313

    
7314
                    namelen = strlen(de->d_name);
7315
                    treclen = offsetof(struct target_dirent, d_name)
7316
                        + namelen + 2;
7317
                    treclen = QEMU_ALIGN_UP(treclen, sizeof(abi_long));
7318

    
7319
                    memmove(tde->d_name, de->d_name, namelen + 1);
7320
                    tde->d_ino = tswapal(ino);
7321
                    tde->d_off = tswapal(off);
7322
                    tde->d_reclen = tswap16(treclen);
7323
                    /* The target_dirent type is in what was formerly a padding
7324
                     * byte at the end of the structure:
7325
                     */
7326
                    *(((char *)tde) + treclen - 1) = type;
7327

    
7328
                    de = (struct linux_dirent64 *)((char *)de + reclen);
7329
                    tde = (struct target_dirent *)((char *)tde + treclen);
7330
                    len -= reclen;
7331
                    tlen += treclen;
7332
                }
7333
                ret = tlen;
7334
            }
7335
            unlock_user(dirp, arg2, ret);
7336
        }
7337
#endif
7338
        break;
7339
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
7340
    case TARGET_NR_getdents64:
7341
        {
7342
            struct linux_dirent64 *dirp;
7343
            abi_long count = arg3;
7344
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
7345
                goto efault;
7346
            ret = get_errno(sys_getdents64(arg1, dirp, count));
7347
            if (!is_error(ret)) {
7348
                struct linux_dirent64 *de;
7349
                int len = ret;
7350
                int reclen;
7351
                de = dirp;
7352
                while (len > 0) {
7353
                    reclen = de->d_reclen;
7354
                    if (reclen > len)
7355
                        break;
7356
                    de->d_reclen = tswap16(reclen);
7357
                    tswap64s((uint64_t *)&de->d_ino);
7358
                    tswap64s((uint64_t *)&de->d_off);
7359
                    de = (struct linux_dirent64 *)((char *)de + reclen);
7360
                    len -= reclen;
7361
                }
7362
            }
7363
            unlock_user(dirp, arg2, ret);
7364
        }
7365
        break;
7366
#endif /* TARGET_NR_getdents64 */
7367
#if defined(TARGET_NR__newselect)
7368
    case TARGET_NR__newselect:
7369
        ret = do_select(arg1, arg2, arg3, arg4, arg5);
7370
        break;
7371
#endif
7372
#if defined(TARGET_NR_poll) || defined(TARGET_NR_ppoll)
7373
# ifdef TARGET_NR_poll
7374
    case TARGET_NR_poll:
7375
# endif
7376
# ifdef TARGET_NR_ppoll
7377
    case TARGET_NR_ppoll:
7378
# endif
7379
        {
7380
            struct target_pollfd *target_pfd;
7381
            unsigned int nfds = arg2;
7382
            int timeout = arg3;
7383
            struct pollfd *pfd;
7384
            unsigned int i;
7385

    
7386
            target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
7387
            if (!target_pfd)
7388
                goto efault;
7389

    
7390
            pfd = alloca(sizeof(struct pollfd) * nfds);
7391
            for(i = 0; i < nfds; i++) {
7392
                pfd[i].fd = tswap32(target_pfd[i].fd);
7393
                pfd[i].events = tswap16(target_pfd[i].events);
7394
            }
7395

    
7396
# ifdef TARGET_NR_ppoll
7397
            if (num == TARGET_NR_ppoll) {
7398
                struct timespec _timeout_ts, *timeout_ts = &_timeout_ts;
7399
                target_sigset_t *target_set;
7400
                sigset_t _set, *set = &_set;
7401

    
7402
                if (arg3) {
7403
                    if (target_to_host_timespec(timeout_ts, arg3)) {
7404
                        unlock_user(target_pfd, arg1, 0);
7405
                        goto efault;
7406
                    }
7407
                } else {
7408
                    timeout_ts = NULL;
7409
                }
7410

    
7411
                if (arg4) {
7412
                    target_set = lock_user(VERIFY_READ, arg4, sizeof(target_sigset_t), 1);
7413
                    if (!target_set) {
7414
                        unlock_user(target_pfd, arg1, 0);
7415
                        goto efault;
7416
                    }
7417
                    target_to_host_sigset(set, target_set);
7418
                } else {
7419
                    set = NULL;
7420
                }
7421

    
7422
                ret = get_errno(sys_ppoll(pfd, nfds, timeout_ts, set, _NSIG/8));
7423

    
7424
                if (!is_error(ret) && arg3) {
7425
                    host_to_target_timespec(arg3, timeout_ts);
7426
                }
7427
                if (arg4) {
7428
                    unlock_user(target_set, arg4, 0);
7429
                }
7430
            } else
7431
# endif
7432
                ret = get_errno(poll(pfd, nfds, timeout));
7433

    
7434
            if (!is_error(ret)) {
7435
                for(i = 0; i < nfds; i++) {
7436
                    target_pfd[i].revents = tswap16(pfd[i].revents);
7437
                }
7438
            }
7439
            unlock_user(target_pfd, arg1, sizeof(struct target_pollfd) * nfds);
7440
        }
7441
        break;
7442
#endif
7443
    case TARGET_NR_flock:
7444
        /* NOTE: the flock constant seems to be the same for every
7445
           Linux platform */
7446
        ret = get_errno(flock(arg1, arg2));
7447
        break;
7448
    case TARGET_NR_readv:
7449
        {
7450
            struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 0);
7451
            if (vec != NULL) {
7452
                ret = get_errno(readv(arg1, vec, arg3));
7453
                unlock_iovec(vec, arg2, arg3, 1);
7454
            } else {
7455
                ret = -host_to_target_errno(errno);
7456
            }
7457
        }
7458
        break;
7459
    case TARGET_NR_writev:
7460
        {
7461
            struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
7462
            if (vec != NULL) {
7463
                ret = get_errno(writev(arg1, vec, arg3));
7464
                unlock_iovec(vec, arg2, arg3, 0);
7465
            } else {
7466
                ret = -host_to_target_errno(errno);
7467
            }
7468
        }
7469
        break;
7470
    case TARGET_NR_getsid:
7471
        ret = get_errno(getsid(arg1));
7472
        break;
7473
#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
7474
    case TARGET_NR_fdatasync:
7475
        ret = get_errno(fdatasync(arg1));
7476
        break;
7477
#endif
7478
    case TARGET_NR__sysctl:
7479
        /* We don't implement this, but ENOTDIR is always a safe
7480
           return value. */
7481
        ret = -TARGET_ENOTDIR;
7482
        break;
7483
    case TARGET_NR_sched_getaffinity:
7484
        {
7485
            unsigned int mask_size;
7486
            unsigned long *mask;
7487

    
7488
            /*
7489
             * sched_getaffinity needs multiples of ulong, so need to take
7490
             * care of mismatches between target ulong and host ulong sizes.
7491
             */
7492
            if (arg2 & (sizeof(abi_ulong) - 1)) {
7493
                ret = -TARGET_EINVAL;
7494
                break;
7495
            }
7496
            mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
7497

    
7498
            mask = alloca(mask_size);
7499
            ret = get_errno(sys_sched_getaffinity(arg1, mask_size, mask));
7500

    
7501
            if (!is_error(ret)) {
7502
                if (copy_to_user(arg3, mask, ret)) {
7503
                    goto efault;
7504
                }
7505
            }
7506
        }
7507
        break;
7508
    case TARGET_NR_sched_setaffinity:
7509
        {
7510
            unsigned int mask_size;
7511
            unsigned long *mask;
7512

    
7513
            /*
7514
             * sched_setaffinity needs multiples of ulong, so need to take
7515
             * care of mismatches between target ulong and host ulong sizes.
7516
             */
7517
            if (arg2 & (sizeof(abi_ulong) - 1)) {
7518
                ret = -TARGET_EINVAL;
7519
                break;
7520
            }
7521
            mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
7522

    
7523
            mask = alloca(mask_size);
7524
            if (!lock_user_struct(VERIFY_READ, p, arg3, 1)) {
7525
                goto efault;
7526
            }
7527
            memcpy(mask, p, arg2);
7528
            unlock_user_struct(p, arg2, 0);
7529

    
7530
            ret = get_errno(sys_sched_setaffinity(arg1, mask_size, mask));
7531
        }
7532
        break;
7533
    case TARGET_NR_sched_setparam:
7534
        {
7535
            struct sched_param *target_schp;
7536
            struct sched_param schp;
7537

    
7538
            if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
7539
                goto efault;
7540
            schp.sched_priority = tswap32(target_schp->sched_priority);
7541
            unlock_user_struct(target_schp, arg2, 0);
7542
            ret = get_errno(sched_setparam(arg1, &schp));
7543
        }
7544
        break;
7545
    case TARGET_NR_sched_getparam:
7546
        {
7547
            struct sched_param *target_schp;
7548
            struct sched_param schp;
7549
            ret = get_errno(sched_getparam(arg1, &schp));
7550
            if (!is_error(ret)) {
7551
                if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
7552
                    goto efault;
7553
                target_schp->sched_priority = tswap32(schp.sched_priority);
7554
                unlock_user_struct(target_schp, arg2, 1);
7555
            }
7556
        }
7557
        break;
7558
    case TARGET_NR_sched_setscheduler:
7559
        {
7560
            struct sched_param *target_schp;
7561
            struct sched_param schp;
7562
            if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
7563
                goto efault;
7564
            schp.sched_priority = tswap32(target_schp->sched_priority);
7565
            unlock_user_struct(target_schp, arg3, 0);
7566
            ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
7567
        }
7568
        break;
7569
    case TARGET_NR_sched_getscheduler:
7570
        ret = get_errno(sched_getscheduler(arg1));
7571
        break;
7572
    case TARGET_NR_sched_yield:
7573
        ret = get_errno(sched_yield());
7574
        break;
7575
    case TARGET_NR_sched_get_priority_max:
7576
        ret = get_errno(sched_get_priority_max(arg1));
7577
        break;
7578
    case TARGET_NR_sched_get_priority_min:
7579
        ret = get_errno(sched_get_priority_min(arg1));
7580
        break;
7581
    case TARGET_NR_sched_rr_get_interval:
7582
        {
7583
            struct timespec ts;
7584
            ret = get_errno(sched_rr_get_interval(arg1, &ts));
7585
            if (!is_error(ret)) {
7586
                host_to_target_timespec(arg2, &ts);
7587
            }
7588
        }
7589
        break;
7590
    case TARGET_NR_nanosleep:
7591
        {
7592
            struct timespec req, rem;
7593
            target_to_host_timespec(&req, arg1);
7594
            ret = get_errno(nanosleep(&req, &rem));
7595
            if (is_error(ret) && arg2) {
7596
                host_to_target_timespec(arg2, &rem);
7597
            }
7598
        }
7599
        break;
7600
#ifdef TARGET_NR_query_module
7601
    case TARGET_NR_query_module:
7602
        goto unimplemented;
7603
#endif
7604
#ifdef TARGET_NR_nfsservctl
7605
    case TARGET_NR_nfsservctl:
7606
        goto unimplemented;
7607
#endif
7608
    case TARGET_NR_prctl:
7609
        switch (arg1) {
7610
        case PR_GET_PDEATHSIG:
7611
        {
7612
            int deathsig;
7613
            ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
7614
            if (!is_error(ret) && arg2
7615
                && put_user_ual(deathsig, arg2)) {
7616
                goto efault;
7617
            }
7618
            break;
7619
        }
7620
#ifdef PR_GET_NAME
7621
        case PR_GET_NAME:
7622
        {
7623
            void *name = lock_user(VERIFY_WRITE, arg2, 16, 1);
7624
            if (!name) {
7625
                goto efault;
7626
            }
7627
            ret = get_errno(prctl(arg1, (unsigned long)name,
7628
                                  arg3, arg4, arg5));
7629
            unlock_user(name, arg2, 16);
7630
            break;
7631
        }
7632
        case PR_SET_NAME:
7633
        {
7634
            void *name = lock_user(VERIFY_READ, arg2, 16, 1);
7635
            if (!name) {
7636
                goto efault;
7637
            }
7638
            ret = get_errno(prctl(arg1, (unsigned long)name,
7639
                                  arg3, arg4, arg5));
7640
            unlock_user(name, arg2, 0);
7641
            break;
7642
        }
7643
#endif
7644
        default:
7645
            /* Most prctl options have no pointer arguments */
7646
            ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
7647
            break;
7648
        }
7649
        break;
7650
#ifdef TARGET_NR_arch_prctl
7651
    case TARGET_NR_arch_prctl:
7652
#if defined(TARGET_I386) && !defined(TARGET_ABI32)
7653
        ret = do_arch_prctl(cpu_env, arg1, arg2);
7654
        break;
7655
#else
7656
        goto unimplemented;
7657
#endif
7658
#endif
7659
#ifdef TARGET_NR_pread64
7660
    case TARGET_NR_pread64:
7661
        if (regpairs_aligned(cpu_env)) {
7662
            arg4 = arg5;
7663
            arg5 = arg6;
7664
        }
7665
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
7666
            goto efault;
7667
        ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
7668
        unlock_user(p, arg2, ret);
7669
        break;
7670
    case TARGET_NR_pwrite64:
7671
        if (regpairs_aligned(cpu_env)) {
7672
            arg4 = arg5;
7673
            arg5 = arg6;
7674
        }
7675
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
7676
            goto efault;
7677
        ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
7678
        unlock_user(p, arg2, 0);
7679
        break;
7680
#endif
7681
    case TARGET_NR_getcwd:
7682
        if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
7683
            goto efault;
7684
        ret = get_errno(sys_getcwd1(p, arg2));
7685
        unlock_user(p, arg1, ret);
7686
        break;
7687
    case TARGET_NR_capget:
7688
        goto unimplemented;
7689
    case TARGET_NR_capset:
7690
        goto unimplemented;
7691
    case TARGET_NR_sigaltstack:
7692
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
7693
    defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA) || \
7694
    defined(TARGET_M68K) || defined(TARGET_S390X) || defined(TARGET_OPENRISC)
7695
        ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUArchState *)cpu_env));
7696
        break;
7697
#else
7698
        goto unimplemented;
7699
#endif
7700

    
7701
#ifdef CONFIG_SENDFILE
7702
    case TARGET_NR_sendfile:
7703
    {
7704
        off_t *offp = NULL;
7705
        off_t off;
7706
        if (arg3) {
7707
            ret = get_user_sal(off, arg3);
7708
            if (is_error(ret)) {
7709
                break;
7710
            }
7711
            offp = &off;
7712
        }
7713
        ret = get_errno(sendfile(arg1, arg2, offp, arg4));
7714
        if (!is_error(ret) && arg3) {
7715
            abi_long ret2 = put_user_sal(off, arg3);
7716
            if (is_error(ret2)) {
7717
                ret = ret2;
7718
            }
7719
        }
7720
        break;
7721
    }
7722
#ifdef TARGET_NR_sendfile64
7723
    case TARGET_NR_sendfile64:
7724
    {
7725
        off_t *offp = NULL;
7726
        off_t off;
7727
        if (arg3) {
7728
            ret = get_user_s64(off, arg3);
7729
            if (is_error(ret)) {
7730
                break;
7731
            }
7732
            offp = &off;
7733
        }
7734
        ret = get_errno(sendfile(arg1, arg2, offp, arg4));
7735
        if (!is_error(ret) && arg3) {
7736
            abi_long ret2 = put_user_s64(off, arg3);
7737
            if (is_error(ret2)) {
7738
                ret = ret2;
7739
            }
7740
        }
7741
        break;
7742
    }
7743
#endif
7744
#else
7745
    case TARGET_NR_sendfile:
7746
#ifdef TARGET_NR_sendfile64
7747
    case TARGET_NR_sendfile64:
7748
#endif
7749
        goto unimplemented;
7750
#endif
7751

    
7752
#ifdef TARGET_NR_getpmsg
7753
    case TARGET_NR_getpmsg:
7754
        goto unimplemented;
7755
#endif
7756
#ifdef TARGET_NR_putpmsg
7757
    case TARGET_NR_putpmsg:
7758
        goto unimplemented;
7759
#endif
7760
#ifdef TARGET_NR_vfork
7761
    case TARGET_NR_vfork:
7762
        ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
7763
                        0, 0, 0, 0));
7764
        break;
7765
#endif
7766
#ifdef TARGET_NR_ugetrlimit
7767
    case TARGET_NR_ugetrlimit:
7768
    {
7769
        struct rlimit rlim;
7770
        int resource = target_to_host_resource(arg1);
7771
        ret = get_errno(getrlimit(resource, &rlim));
7772
        if (!is_error(ret)) {
7773
            struct target_rlimit *target_rlim;
7774
            if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
7775
                goto efault;
7776
            target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
7777
            target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
7778
            unlock_user_struct(target_rlim, arg2, 1);
7779
        }
7780
        break;
7781
    }
7782
#endif
7783
#ifdef TARGET_NR_truncate64
7784
    case TARGET_NR_truncate64:
7785
        if (!(p = lock_user_string(arg1)))
7786
            goto efault;
7787
        ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
7788
        unlock_user(p, arg1, 0);
7789
        break;
7790
#endif
7791
#ifdef TARGET_NR_ftruncate64
7792
    case TARGET_NR_ftruncate64:
7793
        ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
7794
        break;
7795
#endif
7796
#ifdef TARGET_NR_stat64
7797
    case TARGET_NR_stat64:
7798
        if (!(p = lock_user_string(arg1)))
7799
            goto efault;
7800
        ret = get_errno(stat(path(p), &st));
7801
        unlock_user(p, arg1, 0);
7802
        if (!is_error(ret))
7803
            ret = host_to_target_stat64(cpu_env, arg2, &st);
7804
        break;
7805
#endif
7806
#ifdef TARGET_NR_lstat64
7807
    case TARGET_NR_lstat64:
7808
        if (!(p = lock_user_string(arg1)))
7809
            goto efault;
7810
        ret = get_errno(lstat(path(p), &st));
7811
        unlock_user(p, arg1, 0);
7812
        if (!is_error(ret))
7813
            ret = host_to_target_stat64(cpu_env, arg2, &st);
7814
        break;
7815
#endif
7816
#ifdef TARGET_NR_fstat64
7817
    case TARGET_NR_fstat64:
7818
        ret = get_errno(fstat(arg1, &st));
7819
        if (!is_error(ret))
7820
            ret = host_to_target_stat64(cpu_env, arg2, &st);
7821
        break;
7822
#endif
7823
#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat))
7824
#ifdef TARGET_NR_fstatat64
7825
    case TARGET_NR_fstatat64:
7826
#endif
7827
#ifdef TARGET_NR_newfstatat
7828
    case TARGET_NR_newfstatat:
7829
#endif
7830
        if (!(p = lock_user_string(arg2)))
7831
            goto efault;
7832
        ret = get_errno(fstatat(arg1, path(p), &st, arg4));
7833
        if (!is_error(ret))
7834
            ret = host_to_target_stat64(cpu_env, arg3, &st);
7835
        break;
7836
#endif
7837
    case TARGET_NR_lchown:
7838
        if (!(p = lock_user_string(arg1)))
7839
            goto efault;
7840
        ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
7841
        unlock_user(p, arg1, 0);
7842
        break;
7843
#ifdef TARGET_NR_getuid
7844
    case TARGET_NR_getuid:
7845
        ret = get_errno(high2lowuid(getuid()));
7846
        break;
7847
#endif
7848
#ifdef TARGET_NR_getgid
7849
    case TARGET_NR_getgid:
7850
        ret = get_errno(high2lowgid(getgid()));
7851
        break;
7852
#endif
7853
#ifdef TARGET_NR_geteuid
7854
    case TARGET_NR_geteuid:
7855
        ret = get_errno(high2lowuid(geteuid()));
7856
        break;
7857
#endif
7858
#ifdef TARGET_NR_getegid
7859
    case TARGET_NR_getegid:
7860
        ret = get_errno(high2lowgid(getegid()));
7861
        break;
7862
#endif
7863
    case TARGET_NR_setreuid:
7864
        ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
7865
        break;
7866
    case TARGET_NR_setregid:
7867
        ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
7868
        break;
7869
    case TARGET_NR_getgroups:
7870
        {
7871
            int gidsetsize = arg1;
7872
            target_id *target_grouplist;
7873
            gid_t *grouplist;
7874
            int i;
7875

    
7876
            grouplist = alloca(gidsetsize * sizeof(gid_t));
7877
            ret = get_errno(getgroups(gidsetsize, grouplist));
7878
            if (gidsetsize == 0)
7879
                break;
7880
            if (!is_error(ret)) {
7881
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * sizeof(target_id), 0);
7882
                if (!target_grouplist)
7883
                    goto efault;
7884
                for(i = 0;i < ret; i++)
7885
                    target_grouplist[i] = tswapid(high2lowgid(grouplist[i]));
7886
                unlock_user(target_grouplist, arg2, gidsetsize * sizeof(target_id));
7887
            }
7888
        }
7889
        break;
7890
    case TARGET_NR_setgroups:
7891
        {
7892
            int gidsetsize = arg1;
7893
            target_id *target_grouplist;
7894
            gid_t *grouplist = NULL;
7895
            int i;
7896
            if (gidsetsize) {
7897
                grouplist = alloca(gidsetsize * sizeof(gid_t));
7898
                target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * sizeof(target_id), 1);
7899
                if (!target_grouplist) {
7900
                    ret = -TARGET_EFAULT;
7901
                    goto fail;
7902
                }
7903
                for (i = 0; i < gidsetsize; i++) {
7904
                    grouplist[i] = low2highgid(tswapid(target_grouplist[i]));
7905
                }
7906
                unlock_user(target_grouplist, arg2, 0);
7907
            }
7908
            ret = get_errno(setgroups(gidsetsize, grouplist));
7909
        }
7910
        break;
7911
    case TARGET_NR_fchown:
7912
        ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
7913
        break;
7914
#if defined(TARGET_NR_fchownat)
7915
    case TARGET_NR_fchownat:
7916
        if (!(p = lock_user_string(arg2))) 
7917
            goto efault;
7918
        ret = get_errno(fchownat(arg1, p, low2highuid(arg3),
7919
                                 low2highgid(arg4), arg5));
7920
        unlock_user(p, arg2, 0);
7921
        break;
7922
#endif
7923
#ifdef TARGET_NR_setresuid
7924
    case TARGET_NR_setresuid:
7925
        ret = get_errno(setresuid(low2highuid(arg1),
7926
                                  low2highuid(arg2),
7927
                                  low2highuid(arg3)));
7928
        break;
7929
#endif
7930
#ifdef TARGET_NR_getresuid
7931
    case TARGET_NR_getresuid:
7932
        {
7933
            uid_t ruid, euid, suid;
7934
            ret = get_errno(getresuid(&ruid, &euid, &suid));
7935
            if (!is_error(ret)) {
7936
                if (put_user_u16(high2lowuid(ruid), arg1)
7937
                    || put_user_u16(high2lowuid(euid), arg2)
7938
                    || put_user_u16(high2lowuid(suid), arg3))
7939
                    goto efault;
7940
            }
7941
        }
7942
        break;
7943
#endif
7944
#ifdef TARGET_NR_getresgid
7945
    case TARGET_NR_setresgid:
7946
        ret = get_errno(setresgid(low2highgid(arg1),
7947
                                  low2highgid(arg2),
7948
                                  low2highgid(arg3)));
7949
        break;
7950
#endif
7951
#ifdef TARGET_NR_getresgid
7952
    case TARGET_NR_getresgid:
7953
        {
7954
            gid_t rgid, egid, sgid;
7955
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
7956
            if (!is_error(ret)) {
7957
                if (put_user_u16(high2lowgid(rgid), arg1)
7958
                    || put_user_u16(high2lowgid(egid), arg2)
7959
                    || put_user_u16(high2lowgid(sgid), arg3))
7960
                    goto efault;
7961
            }
7962
        }
7963
        break;
7964
#endif
7965
    case TARGET_NR_chown:
7966
        if (!(p = lock_user_string(arg1)))
7967
            goto efault;
7968
        ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
7969
        unlock_user(p, arg1, 0);
7970
        break;
7971
    case TARGET_NR_setuid:
7972
        ret = get_errno(setuid(low2highuid(arg1)));
7973
        break;
7974
    case TARGET_NR_setgid:
7975
        ret = get_errno(setgid(low2highgid(arg1)));
7976
        break;
7977
    case TARGET_NR_setfsuid:
7978
        ret = get_errno(setfsuid(arg1));
7979
        break;
7980
    case TARGET_NR_setfsgid:
7981
        ret = get_errno(setfsgid(arg1));
7982
        break;
7983

    
7984
#ifdef TARGET_NR_lchown32
7985
    case TARGET_NR_lchown32:
7986
        if (!(p = lock_user_string(arg1)))
7987
            goto efault;
7988
        ret = get_errno(lchown(p, arg2, arg3));
7989
        unlock_user(p, arg1, 0);
7990
        break;
7991
#endif
7992
#ifdef TARGET_NR_getuid32
7993
    case TARGET_NR_getuid32:
7994
        ret = get_errno(getuid());
7995
        break;
7996
#endif
7997

    
7998
#if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
7999
   /* Alpha specific */
8000
    case TARGET_NR_getxuid:
8001
         {
8002
            uid_t euid;
8003
            euid=geteuid();
8004
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
8005
         }
8006
        ret = get_errno(getuid());
8007
        break;
8008
#endif
8009
#if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
8010
   /* Alpha specific */
8011
    case TARGET_NR_getxgid:
8012
         {
8013
            uid_t egid;
8014
            egid=getegid();
8015
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
8016
         }
8017
        ret = get_errno(getgid());
8018
        break;
8019
#endif
8020
#if defined(TARGET_NR_osf_getsysinfo) && defined(TARGET_ALPHA)
8021
    /* Alpha specific */
8022
    case TARGET_NR_osf_getsysinfo:
8023
        ret = -TARGET_EOPNOTSUPP;
8024
        switch (arg1) {
8025
          case TARGET_GSI_IEEE_FP_CONTROL:
8026
            {
8027
                uint64_t swcr, fpcr = cpu_alpha_load_fpcr (cpu_env);
8028

    
8029
                /* Copied from linux ieee_fpcr_to_swcr.  */
8030
                swcr = (fpcr >> 35) & SWCR_STATUS_MASK;
8031
                swcr |= (fpcr >> 36) & SWCR_MAP_DMZ;
8032
                swcr |= (~fpcr >> 48) & (SWCR_TRAP_ENABLE_INV
8033
                                        | SWCR_TRAP_ENABLE_DZE
8034
                                        | SWCR_TRAP_ENABLE_OVF);
8035
                swcr |= (~fpcr >> 57) & (SWCR_TRAP_ENABLE_UNF
8036
                                        | SWCR_TRAP_ENABLE_INE);
8037
                swcr |= (fpcr >> 47) & SWCR_MAP_UMZ;
8038
                swcr |= (~fpcr >> 41) & SWCR_TRAP_ENABLE_DNO;
8039

    
8040
                if (put_user_u64 (swcr, arg2))
8041
                        goto efault;
8042
                ret = 0;
8043
            }
8044
            break;
8045

    
8046
          /* case GSI_IEEE_STATE_AT_SIGNAL:
8047
             -- Not implemented in linux kernel.
8048
             case GSI_UACPROC:
8049
             -- Retrieves current unaligned access state; not much used.
8050
             case GSI_PROC_TYPE:
8051
             -- Retrieves implver information; surely not used.
8052
             case GSI_GET_HWRPB:
8053
             -- Grabs a copy of the HWRPB; surely not used.
8054
          */
8055
        }
8056
        break;
8057
#endif
8058
#if defined(TARGET_NR_osf_setsysinfo) && defined(TARGET_ALPHA)
8059
    /* Alpha specific */
8060
    case TARGET_NR_osf_setsysinfo:
8061
        ret = -TARGET_EOPNOTSUPP;
8062
        switch (arg1) {
8063
          case TARGET_SSI_IEEE_FP_CONTROL:
8064
            {
8065
                uint64_t swcr, fpcr, orig_fpcr;
8066

    
8067
                if (get_user_u64 (swcr, arg2)) {
8068
                    goto efault;
8069
                }
8070
                orig_fpcr = cpu_alpha_load_fpcr(cpu_env);
8071
                fpcr = orig_fpcr & FPCR_DYN_MASK;
8072

    
8073
                /* Copied from linux ieee_swcr_to_fpcr.  */
8074
                fpcr |= (swcr & SWCR_STATUS_MASK) << 35;
8075
                fpcr |= (swcr & SWCR_MAP_DMZ) << 36;
8076
                fpcr |= (~swcr & (SWCR_TRAP_ENABLE_INV
8077
                                  | SWCR_TRAP_ENABLE_DZE
8078
                                  | SWCR_TRAP_ENABLE_OVF)) << 48;
8079
                fpcr |= (~swcr & (SWCR_TRAP_ENABLE_UNF
8080
                                  | SWCR_TRAP_ENABLE_INE)) << 57;
8081
                fpcr |= (swcr & SWCR_MAP_UMZ ? FPCR_UNDZ | FPCR_UNFD : 0);
8082
                fpcr |= (~swcr & SWCR_TRAP_ENABLE_DNO) << 41;
8083

    
8084
                cpu_alpha_store_fpcr(cpu_env, fpcr);
8085
                ret = 0;
8086
            }
8087
            break;
8088

    
8089
          case TARGET_SSI_IEEE_RAISE_EXCEPTION:
8090
            {
8091
                uint64_t exc, fpcr, orig_fpcr;
8092
                int si_code;
8093

    
8094
                if (get_user_u64(exc, arg2)) {
8095
                    goto efault;
8096
                }
8097

    
8098
                orig_fpcr = cpu_alpha_load_fpcr(cpu_env);
8099

    
8100
                /* We only add to the exception status here.  */
8101
                fpcr = orig_fpcr | ((exc & SWCR_STATUS_MASK) << 35);
8102

    
8103
                cpu_alpha_store_fpcr(cpu_env, fpcr);
8104
                ret = 0;
8105

    
8106
                /* Old exceptions are not signaled.  */
8107
                fpcr &= ~(orig_fpcr & FPCR_STATUS_MASK);
8108

    
8109
                /* If any exceptions set by this call,
8110
                   and are unmasked, send a signal.  */
8111
                si_code = 0;
8112
                if ((fpcr & (FPCR_INE | FPCR_INED)) == FPCR_INE) {
8113
                    si_code = TARGET_FPE_FLTRES;
8114
                }
8115
                if ((fpcr & (FPCR_UNF | FPCR_UNFD)) == FPCR_UNF) {
8116
                    si_code = TARGET_FPE_FLTUND;
8117
                }
8118
                if ((fpcr & (FPCR_OVF | FPCR_OVFD)) == FPCR_OVF) {
8119
                    si_code = TARGET_FPE_FLTOVF;
8120
                }
8121
                if ((fpcr & (FPCR_DZE | FPCR_DZED)) == FPCR_DZE) {
8122
                    si_code = TARGET_FPE_FLTDIV;
8123
                }
8124
                if ((fpcr & (FPCR_INV | FPCR_INVD)) == FPCR_INV) {
8125
                    si_code = TARGET_FPE_FLTINV;
8126
                }
8127
                if (si_code != 0) {
8128
                    target_siginfo_t info;
8129
                    info.si_signo = SIGFPE;
8130
                    info.si_errno = 0;
8131
                    info.si_code = si_code;
8132
                    info._sifields._sigfault._addr
8133
                        = ((CPUArchState *)cpu_env)->pc;
8134
                    queue_signal((CPUArchState *)cpu_env, info.si_signo, &info);
8135
                }
8136
            }
8137
            break;
8138

    
8139
          /* case SSI_NVPAIRS:
8140
             -- Used with SSIN_UACPROC to enable unaligned accesses.
8141
             case SSI_IEEE_STATE_AT_SIGNAL:
8142
             case SSI_IEEE_IGNORE_STATE_AT_SIGNAL:
8143
             -- Not implemented in linux kernel
8144
          */
8145
        }
8146
        break;
8147
#endif
8148
#ifdef TARGET_NR_osf_sigprocmask
8149
    /* Alpha specific.  */
8150
    case TARGET_NR_osf_sigprocmask:
8151
        {
8152
            abi_ulong mask;
8153
            int how;
8154
            sigset_t set, oldset;
8155

    
8156
            switch(arg1) {
8157
            case TARGET_SIG_BLOCK:
8158
                how = SIG_BLOCK;
8159
                break;
8160
            case TARGET_SIG_UNBLOCK:
8161
                how = SIG_UNBLOCK;
8162
                break;
8163
            case TARGET_SIG_SETMASK:
8164
                how = SIG_SETMASK;
8165
                break;
8166
            default:
8167
                ret = -TARGET_EINVAL;
8168
                goto fail;
8169
            }
8170
            mask = arg2;
8171
            target_to_host_old_sigset(&set, &mask);
8172
            sigprocmask(how, &set, &oldset);
8173
            host_to_target_old_sigset(&mask, &oldset);
8174
            ret = mask;
8175
        }
8176
        break;
8177
#endif
8178

    
8179
#ifdef TARGET_NR_getgid32
8180
    case TARGET_NR_getgid32:
8181
        ret = get_errno(getgid());
8182
        break;
8183
#endif
8184
#ifdef TARGET_NR_geteuid32
8185
    case TARGET_NR_geteuid32:
8186
        ret = get_errno(geteuid());
8187
        break;
8188
#endif
8189
#ifdef TARGET_NR_getegid32
8190
    case TARGET_NR_getegid32:
8191
        ret = get_errno(getegid());
8192
        break;
8193
#endif
8194
#ifdef TARGET_NR_setreuid32
8195
    case TARGET_NR_setreuid32:
8196
        ret = get_errno(setreuid(arg1, arg2));
8197
        break;
8198
#endif
8199
#ifdef TARGET_NR_setregid32
8200
    case TARGET_NR_setregid32:
8201
        ret = get_errno(setregid(arg1, arg2));
8202
        break;
8203
#endif
8204
#ifdef TARGET_NR_getgroups32
8205
    case TARGET_NR_getgroups32:
8206
        {
8207
            int gidsetsize = arg1;
8208
            uint32_t *target_grouplist;
8209
            gid_t *grouplist;
8210
            int i;
8211

    
8212
            grouplist = alloca(gidsetsize * sizeof(gid_t));
8213
            ret = get_errno(getgroups(gidsetsize, grouplist));
8214
            if (gidsetsize == 0)
8215
                break;
8216
            if (!is_error(ret)) {
8217
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
8218
                if (!target_grouplist) {
8219
                    ret = -TARGET_EFAULT;
8220
                    goto fail;
8221
                }
8222
                for(i = 0;i < ret; i++)
8223
                    target_grouplist[i] = tswap32(grouplist[i]);
8224
                unlock_user(target_grouplist, arg2, gidsetsize * 4);
8225
            }
8226
        }
8227
        break;
8228
#endif
8229
#ifdef TARGET_NR_setgroups32
8230
    case TARGET_NR_setgroups32:
8231
        {
8232
            int gidsetsize = arg1;
8233
            uint32_t *target_grouplist;
8234
            gid_t *grouplist;
8235
            int i;
8236

    
8237
            grouplist = alloca(gidsetsize * sizeof(gid_t));
8238
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
8239
            if (!target_grouplist) {
8240
                ret = -TARGET_EFAULT;
8241
                goto fail;
8242
            }
8243
            for(i = 0;i < gidsetsize; i++)
8244
                grouplist[i] = tswap32(target_grouplist[i]);
8245
            unlock_user(target_grouplist, arg2, 0);
8246
            ret = get_errno(setgroups(gidsetsize, grouplist));
8247
        }
8248
        break;
8249
#endif
8250
#ifdef TARGET_NR_fchown32
8251
    case TARGET_NR_fchown32:
8252
        ret = get_errno(fchown(arg1, arg2, arg3));
8253
        break;
8254
#endif
8255
#ifdef TARGET_NR_setresuid32
8256
    case TARGET_NR_setresuid32:
8257
        ret = get_errno(setresuid(arg1, arg2, arg3));
8258
        break;
8259
#endif
8260
#ifdef TARGET_NR_getresuid32
8261
    case TARGET_NR_getresuid32:
8262
        {
8263
            uid_t ruid, euid, suid;
8264
            ret = get_errno(getresuid(&ruid, &euid, &suid));
8265
            if (!is_error(ret)) {
8266
                if (put_user_u32(ruid, arg1)
8267
                    || put_user_u32(euid, arg2)
8268
                    || put_user_u32(suid, arg3))
8269
                    goto efault;
8270
            }
8271
        }
8272
        break;
8273
#endif
8274
#ifdef TARGET_NR_setresgid32
8275
    case TARGET_NR_setresgid32:
8276
        ret = get_errno(setresgid(arg1, arg2, arg3));
8277
        break;
8278
#endif
8279
#ifdef TARGET_NR_getresgid32
8280
    case TARGET_NR_getresgid32:
8281
        {
8282
            gid_t rgid, egid, sgid;
8283
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
8284
            if (!is_error(ret)) {
8285
                if (put_user_u32(rgid, arg1)
8286
                    || put_user_u32(egid, arg2)
8287
                    || put_user_u32(sgid, arg3))
8288
                    goto efault;
8289
            }
8290
        }
8291
        break;
8292
#endif
8293
#ifdef TARGET_NR_chown32
8294
    case TARGET_NR_chown32:
8295
        if (!(p = lock_user_string(arg1)))
8296
            goto efault;
8297
        ret = get_errno(chown(p, arg2, arg3));
8298
        unlock_user(p, arg1, 0);
8299
        break;
8300
#endif
8301
#ifdef TARGET_NR_setuid32
8302
    case TARGET_NR_setuid32:
8303
        ret = get_errno(setuid(arg1));
8304
        break;
8305
#endif
8306
#ifdef TARGET_NR_setgid32
8307
    case TARGET_NR_setgid32:
8308
        ret = get_errno(setgid(arg1));
8309
        break;
8310
#endif
8311
#ifdef TARGET_NR_setfsuid32
8312
    case TARGET_NR_setfsuid32:
8313
        ret = get_errno(setfsuid(arg1));
8314
        break;
8315
#endif
8316
#ifdef TARGET_NR_setfsgid32
8317
    case TARGET_NR_setfsgid32:
8318
        ret = get_errno(setfsgid(arg1));
8319
        break;
8320
#endif
8321

    
8322
    case TARGET_NR_pivot_root:
8323
        goto unimplemented;
8324
#ifdef TARGET_NR_mincore
8325
    case TARGET_NR_mincore:
8326
        {
8327
            void *a;
8328
            ret = -TARGET_EFAULT;
8329
            if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
8330
                goto efault;
8331
            if (!(p = lock_user_string(arg3)))
8332
                goto mincore_fail;
8333
            ret = get_errno(mincore(a, arg2, p));
8334
            unlock_user(p, arg3, ret);
8335
            mincore_fail:
8336
            unlock_user(a, arg1, 0);
8337
        }
8338
        break;
8339
#endif
8340
#ifdef TARGET_NR_arm_fadvise64_64
8341
    case TARGET_NR_arm_fadvise64_64:
8342
        {
8343
                /*
8344
                 * arm_fadvise64_64 looks like fadvise64_64 but
8345
                 * with different argument order
8346
                 */
8347
                abi_long temp;
8348
                temp = arg3;
8349
                arg3 = arg4;
8350
                arg4 = temp;
8351
        }
8352
#endif
8353
#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64) || defined(TARGET_NR_fadvise64)
8354
#ifdef TARGET_NR_fadvise64_64
8355
    case TARGET_NR_fadvise64_64:
8356
#endif
8357
#ifdef TARGET_NR_fadvise64
8358
    case TARGET_NR_fadvise64:
8359
#endif
8360
#ifdef TARGET_S390X
8361
        switch (arg4) {
8362
        case 4: arg4 = POSIX_FADV_NOREUSE + 1; break; /* make sure it's an invalid value */
8363
        case 5: arg4 = POSIX_FADV_NOREUSE + 2; break; /* ditto */
8364
        case 6: arg4 = POSIX_FADV_DONTNEED; break;
8365
        case 7: arg4 = POSIX_FADV_NOREUSE; break;
8366
        default: break;
8367
        }
8368
#endif
8369
        ret = -posix_fadvise(arg1, arg2, arg3, arg4);
8370
        break;
8371
#endif
8372
#ifdef TARGET_NR_madvise
8373
    case TARGET_NR_madvise:
8374
        /* A straight passthrough may not be safe because qemu sometimes
8375
           turns private file-backed mappings into anonymous mappings.
8376
           This will break MADV_DONTNEED.
8377
           This is a hint, so ignoring and returning success is ok.  */
8378
        ret = get_errno(0);
8379
        break;
8380
#endif
8381
#if TARGET_ABI_BITS == 32
8382
    case TARGET_NR_fcntl64:
8383
    {
8384
        int cmd;
8385
        struct flock64 fl;
8386
        struct target_flock64 *target_fl;
8387
#ifdef TARGET_ARM
8388
        struct target_eabi_flock64 *target_efl;
8389
#endif
8390

    
8391
        cmd = target_to_host_fcntl_cmd(arg2);
8392
        if (cmd == -TARGET_EINVAL) {
8393
            ret = cmd;
8394
            break;
8395
        }
8396

    
8397
        switch(arg2) {
8398
        case TARGET_F_GETLK64:
8399
#ifdef TARGET_ARM
8400
            if (((CPUARMState *)cpu_env)->eabi) {
8401
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
8402
                    goto efault;
8403
                fl.l_type = tswap16(target_efl->l_type);
8404
                fl.l_whence = tswap16(target_efl->l_whence);
8405
                fl.l_start = tswap64(target_efl->l_start);
8406
                fl.l_len = tswap64(target_efl->l_len);
8407
                fl.l_pid = tswap32(target_efl->l_pid);
8408
                unlock_user_struct(target_efl, arg3, 0);
8409
            } else
8410
#endif
8411
            {
8412
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
8413
                    goto efault;
8414
                fl.l_type = tswap16(target_fl->l_type);
8415
                fl.l_whence = tswap16(target_fl->l_whence);
8416
                fl.l_start = tswap64(target_fl->l_start);
8417
                fl.l_len = tswap64(target_fl->l_len);
8418
                fl.l_pid = tswap32(target_fl->l_pid);
8419
                unlock_user_struct(target_fl, arg3, 0);
8420
            }
8421
            ret = get_errno(fcntl(arg1, cmd, &fl));
8422
            if (ret == 0) {
8423
#ifdef TARGET_ARM
8424
                if (((CPUARMState *)cpu_env)->eabi) {
8425
                    if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) 
8426
                        goto efault;
8427
                    target_efl->l_type = tswap16(fl.l_type);
8428
                    target_efl->l_whence = tswap16(fl.l_whence);
8429
                    target_efl->l_start = tswap64(fl.l_start);
8430
                    target_efl->l_len = tswap64(fl.l_len);
8431
                    target_efl->l_pid = tswap32(fl.l_pid);
8432
                    unlock_user_struct(target_efl, arg3, 1);
8433
                } else
8434
#endif
8435
                {
8436
                    if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) 
8437
                        goto efault;
8438
                    target_fl->l_type = tswap16(fl.l_type);
8439
                    target_fl->l_whence = tswap16(fl.l_whence);
8440
                    target_fl->l_start = tswap64(fl.l_start);
8441
                    target_fl->l_len = tswap64(fl.l_len);
8442
                    target_fl->l_pid = tswap32(fl.l_pid);
8443
                    unlock_user_struct(target_fl, arg3, 1);
8444
                }
8445
            }
8446
            break;
8447

    
8448
        case TARGET_F_SETLK64:
8449
        case TARGET_F_SETLKW64:
8450
#ifdef TARGET_ARM
8451
            if (((CPUARMState *)cpu_env)->eabi) {
8452
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
8453
                    goto efault;
8454
                fl.l_type = tswap16(target_efl->l_type);
8455
                fl.l_whence = tswap16(target_efl->l_whence);
8456
                fl.l_start = tswap64(target_efl->l_start);
8457
                fl.l_len = tswap64(target_efl->l_len);
8458
                fl.l_pid = tswap32(target_efl->l_pid);
8459
                unlock_user_struct(target_efl, arg3, 0);
8460
            } else
8461
#endif
8462
            {
8463
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
8464
                    goto efault;
8465
                fl.l_type = tswap16(target_fl->l_type);
8466
                fl.l_whence = tswap16(target_fl->l_whence);
8467
                fl.l_start = tswap64(target_fl->l_start);
8468
                fl.l_len = tswap64(target_fl->l_len);
8469
                fl.l_pid = tswap32(target_fl->l_pid);
8470
                unlock_user_struct(target_fl, arg3, 0);
8471
            }
8472
            ret = get_errno(fcntl(arg1, cmd, &fl));
8473
            break;
8474
        default:
8475
            ret = do_fcntl(arg1, arg2, arg3);
8476
            break;
8477
        }
8478
        break;
8479
    }
8480
#endif
8481
#ifdef TARGET_NR_cacheflush
8482
    case TARGET_NR_cacheflush:
8483
        /* self-modifying code is handled automatically, so nothing needed */
8484
        ret = 0;
8485
        break;
8486
#endif
8487
#ifdef TARGET_NR_security
8488
    case TARGET_NR_security:
8489
        goto unimplemented;
8490
#endif
8491
#ifdef TARGET_NR_getpagesize
8492
    case TARGET_NR_getpagesize:
8493
        ret = TARGET_PAGE_SIZE;
8494
        break;
8495
#endif
8496
    case TARGET_NR_gettid:
8497
        ret = get_errno(gettid());
8498
        break;
8499
#ifdef TARGET_NR_readahead
8500
    case TARGET_NR_readahead:
8501
#if TARGET_ABI_BITS == 32
8502
        if (regpairs_aligned(cpu_env)) {
8503
            arg2 = arg3;
8504
            arg3 = arg4;
8505
            arg4 = arg5;
8506
        }
8507
        ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
8508
#else
8509
        ret = get_errno(readahead(arg1, arg2, arg3));
8510
#endif
8511
        break;
8512
#endif
8513
#ifdef CONFIG_ATTR
8514
#ifdef TARGET_NR_setxattr
8515
    case TARGET_NR_listxattr:
8516
    case TARGET_NR_llistxattr:
8517
    {
8518
        void *p, *b = 0;
8519
        if (arg2) {
8520
            b = lock_user(VERIFY_WRITE, arg2, arg3, 0);
8521
            if (!b) {
8522
                ret = -TARGET_EFAULT;
8523
                break;
8524
            }
8525
        }
8526
        p = lock_user_string(arg1);
8527
        if (p) {
8528
            if (num == TARGET_NR_listxattr) {
8529
                ret = get_errno(listxattr(p, b, arg3));
8530
            } else {
8531
                ret = get_errno(llistxattr(p, b, arg3));
8532
            }
8533
        } else {
8534
            ret = -TARGET_EFAULT;
8535
        }
8536
        unlock_user(p, arg1, 0);
8537
        unlock_user(b, arg2, arg3);
8538
        break;
8539
    }
8540
    case TARGET_NR_flistxattr:
8541
    {
8542
        void *b = 0;
8543
        if (arg2) {
8544
            b = lock_user(VERIFY_WRITE, arg2, arg3, 0);
8545
            if (!b) {
8546
                ret = -TARGET_EFAULT;
8547
                break;
8548
            }
8549
        }
8550
        ret = get_errno(flistxattr(arg1, b, arg3));
8551
        unlock_user(b, arg2, arg3);
8552
        break;
8553
    }
8554
    case TARGET_NR_setxattr:
8555
    case TARGET_NR_lsetxattr:
8556
        {
8557
            void *p, *n, *v = 0;
8558
            if (arg3) {
8559
                v = lock_user(VERIFY_READ, arg3, arg4, 1);
8560
                if (!v) {
8561
                    ret = -TARGET_EFAULT;
8562
                    break;
8563
                }
8564
            }
8565
            p = lock_user_string(arg1);
8566
            n = lock_user_string(arg2);
8567
            if (p && n) {
8568
                if (num == TARGET_NR_setxattr) {
8569
                    ret = get_errno(setxattr(p, n, v, arg4, arg5));
8570
                } else {
8571
                    ret = get_errno(lsetxattr(p, n, v, arg4, arg5));
8572
                }
8573
            } else {
8574
                ret = -TARGET_EFAULT;
8575
            }
8576
            unlock_user(p, arg1, 0);
8577
            unlock_user(n, arg2, 0);
8578
            unlock_user(v, arg3, 0);
8579
        }
8580
        break;
8581
    case TARGET_NR_fsetxattr:
8582
        {
8583
            void *n, *v = 0;
8584
            if (arg3) {
8585
                v = lock_user(VERIFY_READ, arg3, arg4, 1);
8586
                if (!v) {
8587
                    ret = -TARGET_EFAULT;
8588
                    break;
8589
                }
8590
            }
8591
            n = lock_user_string(arg2);
8592
            if (n) {
8593
                ret = get_errno(fsetxattr(arg1, n, v, arg4, arg5));
8594
            } else {
8595
                ret = -TARGET_EFAULT;
8596
            }
8597
            unlock_user(n, arg2, 0);
8598
            unlock_user(v, arg3, 0);
8599
        }
8600
        break;
8601
    case TARGET_NR_getxattr:
8602
    case TARGET_NR_lgetxattr:
8603
        {
8604
            void *p, *n, *v = 0;
8605
            if (arg3) {
8606
                v = lock_user(VERIFY_WRITE, arg3, arg4, 0);
8607
                if (!v) {
8608
                    ret = -TARGET_EFAULT;
8609
                    break;
8610
                }
8611
            }
8612
            p = lock_user_string(arg1);
8613
            n = lock_user_string(arg2);
8614
            if (p && n) {
8615
                if (num == TARGET_NR_getxattr) {
8616
                    ret = get_errno(getxattr(p, n, v, arg4));
8617
                } else {
8618
                    ret = get_errno(lgetxattr(p, n, v, arg4));
8619
                }
8620
            } else {
8621
                ret = -TARGET_EFAULT;
8622
            }
8623
            unlock_user(p, arg1, 0);
8624
            unlock_user(n, arg2, 0);
8625
            unlock_user(v, arg3, arg4);
8626
        }
8627
        break;
8628
    case TARGET_NR_fgetxattr:
8629
        {
8630
            void *n, *v = 0;
8631
            if (arg3) {
8632
                v = lock_user(VERIFY_WRITE, arg3, arg4, 0);
8633
                if (!v) {
8634
                    ret = -TARGET_EFAULT;
8635
                    break;
8636
                }
8637
            }
8638
            n = lock_user_string(arg2);
8639
            if (n) {
8640
                ret = get_errno(fgetxattr(arg1, n, v, arg4));
8641
            } else {
8642
                ret = -TARGET_EFAULT;
8643
            }
8644
            unlock_user(n, arg2, 0);
8645
            unlock_user(v, arg3, arg4);
8646
        }
8647
        break;
8648
    case TARGET_NR_removexattr:
8649
    case TARGET_NR_lremovexattr:
8650
        {
8651
            void *p, *n;
8652
            p = lock_user_string(arg1);
8653
            n = lock_user_string(arg2);
8654
            if (p && n) {
8655
                if (num == TARGET_NR_removexattr) {
8656
                    ret = get_errno(removexattr(p, n));
8657
                } else {
8658
                    ret = get_errno(lremovexattr(p, n));
8659
                }
8660
            } else {
8661
                ret = -TARGET_EFAULT;
8662
            }
8663
            unlock_user(p, arg1, 0);
8664
            unlock_user(n, arg2, 0);
8665
        }
8666
        break;
8667
    case TARGET_NR_fremovexattr:
8668
        {
8669
            void *n;
8670
            n = lock_user_string(arg2);
8671
            if (n) {
8672
                ret = get_errno(fremovexattr(arg1, n));
8673
            } else {
8674
                ret = -TARGET_EFAULT;
8675
            }
8676
            unlock_user(n, arg2, 0);
8677
        }
8678
        break;
8679
#endif
8680
#endif /* CONFIG_ATTR */
8681
#ifdef TARGET_NR_set_thread_area
8682
    case TARGET_NR_set_thread_area:
8683
#if defined(TARGET_MIPS)
8684
      ((CPUMIPSState *) cpu_env)->tls_value = arg1;
8685
      ret = 0;
8686
      break;
8687
#elif defined(TARGET_CRIS)
8688
      if (arg1 & 0xff)
8689
          ret = -TARGET_EINVAL;
8690
      else {
8691
          ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
8692
          ret = 0;
8693
      }
8694
      break;
8695
#elif defined(TARGET_I386) && defined(TARGET_ABI32)
8696
      ret = do_set_thread_area(cpu_env, arg1);
8697
      break;
8698
#elif defined(TARGET_M68K)
8699
      {
8700
          TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
8701
          ts->tp_value = arg1;
8702
          ret = 0;
8703
          break;
8704
      }
8705
#else
8706
      goto unimplemented_nowarn;
8707
#endif
8708
#endif
8709
#ifdef TARGET_NR_get_thread_area
8710
    case TARGET_NR_get_thread_area:
8711
#if defined(TARGET_I386) && defined(TARGET_ABI32)
8712
        ret = do_get_thread_area(cpu_env, arg1);
8713
        break;
8714
#elif defined(TARGET_M68K)
8715
        {
8716
            TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
8717
            ret = ts->tp_value;
8718
            break;
8719
        }
8720
#else
8721
        goto unimplemented_nowarn;
8722
#endif
8723
#endif
8724
#ifdef TARGET_NR_getdomainname
8725
    case TARGET_NR_getdomainname:
8726
        goto unimplemented_nowarn;
8727
#endif
8728

    
8729
#ifdef TARGET_NR_clock_gettime
8730
    case TARGET_NR_clock_gettime:
8731
    {
8732
        struct timespec ts;
8733
        ret = get_errno(clock_gettime(arg1, &ts));
8734
        if (!is_error(ret)) {
8735
            host_to_target_timespec(arg2, &ts);
8736
        }
8737
        break;
8738
    }
8739
#endif
8740
#ifdef TARGET_NR_clock_getres
8741
    case TARGET_NR_clock_getres:
8742
    {
8743
        struct timespec ts;
8744
        ret = get_errno(clock_getres(arg1, &ts));
8745
        if (!is_error(ret)) {
8746
            host_to_target_timespec(arg2, &ts);
8747
        }
8748
        break;
8749
    }
8750
#endif
8751
#ifdef TARGET_NR_clock_nanosleep
8752
    case TARGET_NR_clock_nanosleep:
8753
    {
8754
        struct timespec ts;
8755
        target_to_host_timespec(&ts, arg3);
8756
        ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
8757
        if (arg4)
8758
            host_to_target_timespec(arg4, &ts);
8759
        break;
8760
    }
8761
#endif
8762

    
8763
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
8764
    case TARGET_NR_set_tid_address:
8765
        ret = get_errno(set_tid_address((int *)g2h(arg1)));
8766
        break;
8767
#endif
8768

    
8769
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
8770
    case TARGET_NR_tkill:
8771
        ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
8772
        break;
8773
#endif
8774

    
8775
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
8776
    case TARGET_NR_tgkill:
8777
        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
8778
                        target_to_host_signal(arg3)));
8779
        break;
8780
#endif
8781

    
8782
#ifdef TARGET_NR_set_robust_list
8783
    case TARGET_NR_set_robust_list:
8784
    case TARGET_NR_get_robust_list:
8785
        /* The ABI for supporting robust futexes has userspace pass
8786
         * the kernel a pointer to a linked list which is updated by
8787
         * userspace after the syscall; the list is walked by the kernel
8788
         * when the thread exits. Since the linked list in QEMU guest
8789
         * memory isn't a valid linked list for the host and we have
8790
         * no way to reliably intercept the thread-death event, we can't
8791
         * support these. Silently return ENOSYS so that guest userspace
8792
         * falls back to a non-robust futex implementation (which should
8793
         * be OK except in the corner case of the guest crashing while
8794
         * holding a mutex that is shared with another process via
8795
         * shared memory).
8796
         */
8797
        goto unimplemented_nowarn;
8798
#endif
8799

    
8800
#if defined(TARGET_NR_utimensat)
8801
    case TARGET_NR_utimensat:
8802
        {
8803
            struct timespec *tsp, ts[2];
8804
            if (!arg3) {
8805
                tsp = NULL;
8806
            } else {
8807
                target_to_host_timespec(ts, arg3);
8808
                target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
8809
                tsp = ts;
8810
            }
8811
            if (!arg2)
8812
                ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4));
8813
            else {
8814
                if (!(p = lock_user_string(arg2))) {
8815
                    ret = -TARGET_EFAULT;
8816
                    goto fail;
8817
                }
8818
                ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4));
8819
                unlock_user(p, arg2, 0);
8820
            }
8821
        }
8822
        break;
8823
#endif
8824
    case TARGET_NR_futex:
8825
        ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
8826
        break;
8827
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
8828
    case TARGET_NR_inotify_init:
8829
        ret = get_errno(sys_inotify_init());
8830
        break;
8831
#endif
8832
#ifdef CONFIG_INOTIFY1
8833
#if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
8834
    case TARGET_NR_inotify_init1:
8835
        ret = get_errno(sys_inotify_init1(arg1));
8836
        break;
8837
#endif
8838
#endif
8839
#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
8840
    case TARGET_NR_inotify_add_watch:
8841
        p = lock_user_string(arg2);
8842
        ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
8843
        unlock_user(p, arg2, 0);
8844
        break;
8845
#endif
8846
#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
8847
    case TARGET_NR_inotify_rm_watch:
8848
        ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
8849
        break;
8850
#endif
8851

    
8852
#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
8853
    case TARGET_NR_mq_open:
8854
        {
8855
            struct mq_attr posix_mq_attr;
8856

    
8857
            p = lock_user_string(arg1 - 1);
8858
            if (arg4 != 0)
8859
                copy_from_user_mq_attr (&posix_mq_attr, arg4);
8860
            ret = get_errno(mq_open(p, arg2, arg3, &posix_mq_attr));
8861
            unlock_user (p, arg1, 0);
8862
        }
8863
        break;
8864

    
8865
    case TARGET_NR_mq_unlink:
8866
        p = lock_user_string(arg1 - 1);
8867
        ret = get_errno(mq_unlink(p));
8868
        unlock_user (p, arg1, 0);
8869
        break;
8870

    
8871
    case TARGET_NR_mq_timedsend:
8872
        {
8873
            struct timespec ts;
8874

    
8875
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
8876
            if (arg5 != 0) {
8877
                target_to_host_timespec(&ts, arg5);
8878
                ret = get_errno(mq_timedsend(arg1, p, arg3, arg4, &ts));
8879
                host_to_target_timespec(arg5, &ts);
8880
            }
8881
            else
8882
                ret = get_errno(mq_send(arg1, p, arg3, arg4));
8883
            unlock_user (p, arg2, arg3);
8884
        }
8885
        break;
8886

    
8887
    case TARGET_NR_mq_timedreceive:
8888
        {
8889
            struct timespec ts;
8890
            unsigned int prio;
8891

    
8892
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
8893
            if (arg5 != 0) {
8894
                target_to_host_timespec(&ts, arg5);
8895
                ret = get_errno(mq_timedreceive(arg1, p, arg3, &prio, &ts));
8896
                host_to_target_timespec(arg5, &ts);
8897
            }
8898
            else
8899
                ret = get_errno(mq_receive(arg1, p, arg3, &prio));
8900
            unlock_user (p, arg2, arg3);
8901
            if (arg4 != 0)
8902
                put_user_u32(prio, arg4);
8903
        }
8904
        break;
8905

    
8906
    /* Not implemented for now... */
8907
/*     case TARGET_NR_mq_notify: */
8908
/*         break; */
8909

    
8910
    case TARGET_NR_mq_getsetattr:
8911
        {
8912
            struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
8913
            ret = 0;
8914
            if (arg3 != 0) {
8915
                ret = mq_getattr(arg1, &posix_mq_attr_out);
8916
                copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
8917
            }
8918
            if (arg2 != 0) {
8919
                copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
8920
                ret |= mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_attr_out);
8921
            }
8922

    
8923
        }
8924
        break;
8925
#endif
8926

    
8927
#ifdef CONFIG_SPLICE
8928
#ifdef TARGET_NR_tee
8929
    case TARGET_NR_tee:
8930
        {
8931
            ret = get_errno(tee(arg1,arg2,arg3,arg4));
8932
        }
8933
        break;
8934
#endif
8935
#ifdef TARGET_NR_splice
8936
    case TARGET_NR_splice:
8937
        {
8938
            loff_t loff_in, loff_out;
8939
            loff_t *ploff_in = NULL, *ploff_out = NULL;
8940
            if(arg2) {
8941
                get_user_u64(loff_in, arg2);
8942
                ploff_in = &loff_in;
8943
            }
8944
            if(arg4) {
8945
                get_user_u64(loff_out, arg2);
8946
                ploff_out = &loff_out;
8947
            }
8948
            ret = get_errno(splice(arg1, ploff_in, arg3, ploff_out, arg5, arg6));
8949
        }
8950
        break;
8951
#endif
8952
#ifdef TARGET_NR_vmsplice
8953
        case TARGET_NR_vmsplice:
8954
        {
8955
            struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
8956
            if (vec != NULL) {
8957
                ret = get_errno(vmsplice(arg1, vec, arg3, arg4));
8958
                unlock_iovec(vec, arg2, arg3, 0);
8959
            } else {
8960
                ret = -host_to_target_errno(errno);
8961
            }
8962
        }
8963
        break;
8964
#endif
8965
#endif /* CONFIG_SPLICE */
8966
#ifdef CONFIG_EVENTFD
8967
#if defined(TARGET_NR_eventfd)
8968
    case TARGET_NR_eventfd:
8969
        ret = get_errno(eventfd(arg1, 0));
8970
        break;
8971
#endif
8972
#if defined(TARGET_NR_eventfd2)
8973
    case TARGET_NR_eventfd2:
8974
    {
8975
        int host_flags = arg2 & (~(TARGET_O_NONBLOCK | TARGET_O_CLOEXEC));
8976
        if (arg2 & TARGET_O_NONBLOCK) {
8977
            host_flags |= O_NONBLOCK;
8978
        }
8979
        if (arg2 & TARGET_O_CLOEXEC) {
8980
            host_flags |= O_CLOEXEC;
8981
        }
8982
        ret = get_errno(eventfd(arg1, host_flags));
8983
        break;
8984
    }
8985
#endif
8986
#endif /* CONFIG_EVENTFD  */
8987
#if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate)
8988
    case TARGET_NR_fallocate:
8989
#if TARGET_ABI_BITS == 32
8990
        ret = get_errno(fallocate(arg1, arg2, target_offset64(arg3, arg4),
8991
                                  target_offset64(arg5, arg6)));
8992
#else
8993
        ret = get_errno(fallocate(arg1, arg2, arg3, arg4));
8994
#endif
8995
        break;
8996
#endif
8997
#if defined(CONFIG_SYNC_FILE_RANGE)
8998
#if defined(TARGET_NR_sync_file_range)
8999
    case TARGET_NR_sync_file_range:
9000
#if TARGET_ABI_BITS == 32
9001
#if defined(TARGET_MIPS)
9002
        ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
9003
                                        target_offset64(arg5, arg6), arg7));
9004
#else
9005
        ret = get_errno(sync_file_range(arg1, target_offset64(arg2, arg3),
9006
                                        target_offset64(arg4, arg5), arg6));
9007
#endif /* !TARGET_MIPS */
9008
#else
9009
        ret = get_errno(sync_file_range(arg1, arg2, arg3, arg4));
9010
#endif
9011
        break;
9012
#endif
9013
#if defined(TARGET_NR_sync_file_range2)
9014
    case TARGET_NR_sync_file_range2:
9015
        /* This is like sync_file_range but the arguments are reordered */
9016
#if TARGET_ABI_BITS == 32
9017
        ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
9018
                                        target_offset64(arg5, arg6), arg2));
9019
#else
9020
        ret = get_errno(sync_file_range(arg1, arg3, arg4, arg2));
9021
#endif
9022
        break;
9023
#endif
9024
#endif
9025
#if defined(CONFIG_EPOLL)
9026
#if defined(TARGET_NR_epoll_create)
9027
    case TARGET_NR_epoll_create:
9028
        ret = get_errno(epoll_create(arg1));
9029
        break;
9030
#endif
9031
#if defined(TARGET_NR_epoll_create1) && defined(CONFIG_EPOLL_CREATE1)
9032
    case TARGET_NR_epoll_create1:
9033
        ret = get_errno(epoll_create1(arg1));
9034
        break;
9035
#endif
9036
#if defined(TARGET_NR_epoll_ctl)
9037
    case TARGET_NR_epoll_ctl:
9038
    {
9039
        struct epoll_event ep;
9040
        struct epoll_event *epp = 0;
9041
        if (arg4) {
9042
            struct target_epoll_event *target_ep;
9043
            if (!lock_user_struct(VERIFY_READ, target_ep, arg4, 1)) {
9044
                goto efault;
9045
            }
9046
            ep.events = tswap32(target_ep->events);
9047
            /* The epoll_data_t union is just opaque data to the kernel,
9048
             * so we transfer all 64 bits across and need not worry what
9049
             * actual data type it is.
9050
             */
9051
            ep.data.u64 = tswap64(target_ep->data.u64);
9052
            unlock_user_struct(target_ep, arg4, 0);
9053
            epp = &ep;
9054
        }
9055
        ret = get_errno(epoll_ctl(arg1, arg2, arg3, epp));
9056
        break;
9057
    }
9058
#endif
9059

    
9060
#if defined(TARGET_NR_epoll_pwait) && defined(CONFIG_EPOLL_PWAIT)
9061
#define IMPLEMENT_EPOLL_PWAIT
9062
#endif
9063
#if defined(TARGET_NR_epoll_wait) || defined(IMPLEMENT_EPOLL_PWAIT)
9064
#if defined(TARGET_NR_epoll_wait)
9065
    case TARGET_NR_epoll_wait:
9066
#endif
9067
#if defined(IMPLEMENT_EPOLL_PWAIT)
9068
    case TARGET_NR_epoll_pwait:
9069
#endif
9070
    {
9071
        struct target_epoll_event *target_ep;
9072
        struct epoll_event *ep;
9073
        int epfd = arg1;
9074
        int maxevents = arg3;
9075
        int timeout = arg4;
9076

    
9077
        target_ep = lock_user(VERIFY_WRITE, arg2,
9078
                              maxevents * sizeof(struct target_epoll_event), 1);
9079
        if (!target_ep) {
9080
            goto efault;
9081
        }
9082

    
9083
        ep = alloca(maxevents * sizeof(struct epoll_event));
9084

    
9085
        switch (num) {
9086
#if defined(IMPLEMENT_EPOLL_PWAIT)
9087
        case TARGET_NR_epoll_pwait:
9088
        {
9089
            target_sigset_t *target_set;
9090
            sigset_t _set, *set = &_set;
9091

    
9092
            if (arg5) {
9093
                target_set = lock_user(VERIFY_READ, arg5,
9094
                                       sizeof(target_sigset_t), 1);
9095
                if (!target_set) {
9096
                    unlock_user(target_ep, arg2, 0);
9097
                    goto efault;
9098
                }
9099
                target_to_host_sigset(set, target_set);
9100
                unlock_user(target_set, arg5, 0);
9101
            } else {
9102
                set = NULL;
9103
            }
9104

    
9105
            ret = get_errno(epoll_pwait(epfd, ep, maxevents, timeout, set));
9106
            break;
9107
        }
9108
#endif
9109
#if defined(TARGET_NR_epoll_wait)
9110
        case TARGET_NR_epoll_wait:
9111
            ret = get_errno(epoll_wait(epfd, ep, maxevents, timeout));
9112
            break;
9113
#endif
9114
        default:
9115
            ret = -TARGET_ENOSYS;
9116
        }
9117
        if (!is_error(ret)) {
9118
            int i;
9119
            for (i = 0; i < ret; i++) {
9120
                target_ep[i].events = tswap32(ep[i].events);
9121
                target_ep[i].data.u64 = tswap64(ep[i].data.u64);
9122
            }
9123
        }
9124
        unlock_user(target_ep, arg2, ret * sizeof(struct target_epoll_event));
9125
        break;
9126
    }
9127
#endif
9128
#endif
9129
#ifdef TARGET_NR_prlimit64
9130
    case TARGET_NR_prlimit64:
9131
    {
9132
        /* args: pid, resource number, ptr to new rlimit, ptr to old rlimit */
9133
        struct target_rlimit64 *target_rnew, *target_rold;
9134
        struct host_rlimit64 rnew, rold, *rnewp = 0;
9135
        if (arg3) {
9136
            if (!lock_user_struct(VERIFY_READ, target_rnew, arg3, 1)) {
9137
                goto efault;
9138
            }
9139
            rnew.rlim_cur = tswap64(target_rnew->rlim_cur);
9140
            rnew.rlim_max = tswap64(target_rnew->rlim_max);
9141
            unlock_user_struct(target_rnew, arg3, 0);
9142
            rnewp = &rnew;
9143
        }
9144

    
9145
        ret = get_errno(sys_prlimit64(arg1, arg2, rnewp, arg4 ? &rold : 0));
9146
        if (!is_error(ret) && arg4) {
9147
            if (!lock_user_struct(VERIFY_WRITE, target_rold, arg4, 1)) {
9148
                goto efault;
9149
            }
9150
            target_rold->rlim_cur = tswap64(rold.rlim_cur);
9151
            target_rold->rlim_max = tswap64(rold.rlim_max);
9152
            unlock_user_struct(target_rold, arg4, 1);
9153
        }
9154
        break;
9155
    }
9156
#endif
9157
#ifdef TARGET_NR_gethostname
9158
    case TARGET_NR_gethostname:
9159
    {
9160
        char *name = lock_user(VERIFY_WRITE, arg1, arg2, 0);
9161
        if (name) {
9162
            ret = get_errno(gethostname(name, arg2));
9163
            unlock_user(name, arg1, arg2);
9164
        } else {
9165
            ret = -TARGET_EFAULT;
9166
        }
9167
        break;
9168
    }
9169
#endif
9170
#ifdef TARGET_NR_atomic_cmpxchg_32
9171
    case TARGET_NR_atomic_cmpxchg_32:
9172
    {
9173
        /* should use start_exclusive from main.c */
9174
        abi_ulong mem_value;
9175
        if (get_user_u32(mem_value, arg6)) {
9176
            target_siginfo_t info;
9177
            info.si_signo = SIGSEGV;
9178
            info.si_errno = 0;
9179
            info.si_code = TARGET_SEGV_MAPERR;
9180
            info._sifields._sigfault._addr = arg6;
9181
            queue_signal((CPUArchState *)cpu_env, info.si_signo, &info);
9182
            ret = 0xdeadbeef;
9183

    
9184
        }
9185
        if (mem_value == arg2)
9186
            put_user_u32(arg1, arg6);
9187
        ret = mem_value;
9188
        break;
9189
    }
9190
#endif
9191
#ifdef TARGET_NR_atomic_barrier
9192
    case TARGET_NR_atomic_barrier:
9193
    {
9194
        /* Like the kernel implementation and the qemu arm barrier, no-op this? */
9195
        break;
9196
    }
9197
#endif
9198
    default:
9199
    unimplemented:
9200
        gemu_log("qemu: Unsupported syscall: %d\n", num);
9201
#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
9202
    unimplemented_nowarn:
9203
#endif
9204
        ret = -TARGET_ENOSYS;
9205
        break;
9206
    }
9207
fail:
9208
#ifdef DEBUG
9209
    gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
9210
#endif
9211
    if(do_strace)
9212
        print_syscall_ret(num, ret);
9213
    return ret;
9214
efault:
9215
    ret = -TARGET_EFAULT;
9216
    goto fail;
9217
}