Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ f19e00d7

History | View | Annotate | Download (287.9 kB)

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

    
114
#include "qemu.h"
115

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

    
119
//#define DEBUG
120

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

    
125

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

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

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

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

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

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

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

    
171

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

    
180

    
181
#define __NR_sys_uname __NR_uname
182
#define __NR_sys_getcwd1 __NR_getcwd
183
#define __NR_sys_getdents __NR_getdents
184
#define __NR_sys_getdents64 __NR_getdents64
185
#define __NR_sys_getpriority __NR_getpriority
186
#define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
187
#define __NR_sys_syslog __NR_syslog
188
#define __NR_sys_tgkill __NR_tgkill
189
#define __NR_sys_tkill __NR_tkill
190
#define __NR_sys_futex __NR_futex
191
#define __NR_sys_inotify_init __NR_inotify_init
192
#define __NR_sys_inotify_add_watch __NR_inotify_add_watch
193
#define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
194

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

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

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

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

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

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

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

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

    
311
#undef COPY_UTSNAME_FIELD
312
}
313

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

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

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

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

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

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

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

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

    
432

    
433
#if defined(TARGET_NR_timer_create)
434
/* Maxiumum of 32 active POSIX timers allowed at any one time. */
435
static timer_t g_posix_timers[32] = { 0, } ;
436

    
437
static inline int next_free_host_timer(void)
438
{
439
    int k ;
440
    /* FIXME: Does finding the next free slot require a lock? */
441
    for (k = 0; k < ARRAY_SIZE(g_posix_timers); k++) {
442
        if (g_posix_timers[k] == 0) {
443
            g_posix_timers[k] = (timer_t) 1;
444
            return k;
445
        }
446
    }
447
    return -1;
448
}
449
#endif
450

    
451
/* ARM EABI and MIPS expect 64bit types aligned even on pairs or registers */
452
#ifdef TARGET_ARM
453
static inline int regpairs_aligned(void *cpu_env) {
454
    return ((((CPUARMState *)cpu_env)->eabi) == 1) ;
455
}
456
#elif defined(TARGET_MIPS)
457
static inline int regpairs_aligned(void *cpu_env) { return 1; }
458
#elif defined(TARGET_PPC) && !defined(TARGET_PPC64)
459
/* SysV AVI for PPC32 expects 64bit parameters to be passed on odd/even pairs
460
 * of registers which translates to the same as ARM/MIPS, because we start with
461
 * r3 as arg1 */
462
static inline int regpairs_aligned(void *cpu_env) { return 1; }
463
#else
464
static inline int regpairs_aligned(void *cpu_env) { return 0; }
465
#endif
466

    
467
#define ERRNO_TABLE_SIZE 1200
468

    
469
/* target_to_host_errno_table[] is initialized from
470
 * host_to_target_errno_table[] in syscall_init(). */
471
static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
472
};
473

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

    
586
static inline int host_to_target_errno(int err)
587
{
588
    if(host_to_target_errno_table[err])
589
        return host_to_target_errno_table[err];
590
    return err;
591
}
592

    
593
static inline int target_to_host_errno(int err)
594
{
595
    if (target_to_host_errno_table[err])
596
        return target_to_host_errno_table[err];
597
    return err;
598
}
599

    
600
static inline abi_long get_errno(abi_long ret)
601
{
602
    if (ret == -1)
603
        return -host_to_target_errno(errno);
604
    else
605
        return ret;
606
}
607

    
608
static inline int is_error(abi_long ret)
609
{
610
    return (abi_ulong)ret >= (abi_ulong)(-4096);
611
}
612

    
613
char *target_strerror(int err)
614
{
615
    if ((err >= ERRNO_TABLE_SIZE) || (err < 0)) {
616
        return NULL;
617
    }
618
    return strerror(target_to_host_errno(err));
619
}
620

    
621
static abi_ulong target_brk;
622
static abi_ulong target_original_brk;
623
static abi_ulong brk_page;
624

    
625
void target_set_brk(abi_ulong new_brk)
626
{
627
    target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
628
    brk_page = HOST_PAGE_ALIGN(target_brk);
629
}
630

    
631
//#define DEBUGF_BRK(message, args...) do { fprintf(stderr, (message), ## args); } while (0)
632
#define DEBUGF_BRK(message, args...)
633

    
634
/* do_brk() must return target values and target errnos. */
635
abi_long do_brk(abi_ulong new_brk)
636
{
637
    abi_long mapped_addr;
638
    int        new_alloc_size;
639

    
640
    DEBUGF_BRK("do_brk(" TARGET_ABI_FMT_lx ") -> ", new_brk);
641

    
642
    if (!new_brk) {
643
        DEBUGF_BRK(TARGET_ABI_FMT_lx " (!new_brk)\n", target_brk);
644
        return target_brk;
645
    }
646
    if (new_brk < target_original_brk) {
647
        DEBUGF_BRK(TARGET_ABI_FMT_lx " (new_brk < target_original_brk)\n",
648
                   target_brk);
649
        return target_brk;
650
    }
651

    
652
    /* If the new brk is less than the highest page reserved to the
653
     * target heap allocation, set it and we're almost done...  */
654
    if (new_brk <= brk_page) {
655
        /* Heap contents are initialized to zero, as for anonymous
656
         * mapped pages.  */
657
        if (new_brk > target_brk) {
658
            memset(g2h(target_brk), 0, new_brk - target_brk);
659
        }
660
        target_brk = new_brk;
661
        DEBUGF_BRK(TARGET_ABI_FMT_lx " (new_brk <= brk_page)\n", target_brk);
662
            return target_brk;
663
    }
664

    
665
    /* We need to allocate more memory after the brk... Note that
666
     * we don't use MAP_FIXED because that will map over the top of
667
     * any existing mapping (like the one with the host libc or qemu
668
     * itself); instead we treat "mapped but at wrong address" as
669
     * a failure and unmap again.
670
     */
671
    new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page);
672
    mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
673
                                        PROT_READ|PROT_WRITE,
674
                                        MAP_ANON|MAP_PRIVATE, 0, 0));
675

    
676
    if (mapped_addr == brk_page) {
677
        /* Heap contents are initialized to zero, as for anonymous
678
         * mapped pages.  Technically the new pages are already
679
         * initialized to zero since they *are* anonymous mapped
680
         * pages, however we have to take care with the contents that
681
         * come from the remaining part of the previous page: it may
682
         * contains garbage data due to a previous heap usage (grown
683
         * then shrunken).  */
684
        memset(g2h(target_brk), 0, brk_page - target_brk);
685

    
686
        target_brk = new_brk;
687
        brk_page = HOST_PAGE_ALIGN(target_brk);
688
        DEBUGF_BRK(TARGET_ABI_FMT_lx " (mapped_addr == brk_page)\n",
689
            target_brk);
690
        return target_brk;
691
    } else if (mapped_addr != -1) {
692
        /* Mapped but at wrong address, meaning there wasn't actually
693
         * enough space for this brk.
694
         */
695
        target_munmap(mapped_addr, new_alloc_size);
696
        mapped_addr = -1;
697
        DEBUGF_BRK(TARGET_ABI_FMT_lx " (mapped_addr != -1)\n", target_brk);
698
    }
699
    else {
700
        DEBUGF_BRK(TARGET_ABI_FMT_lx " (otherwise)\n", target_brk);
701
    }
702

    
703
#if defined(TARGET_ALPHA)
704
    /* We (partially) emulate OSF/1 on Alpha, which requires we
705
       return a proper errno, not an unchanged brk value.  */
706
    return -TARGET_ENOMEM;
707
#endif
708
    /* For everything else, return the previous break. */
709
    return target_brk;
710
}
711

    
712
static inline abi_long copy_from_user_fdset(fd_set *fds,
713
                                            abi_ulong target_fds_addr,
714
                                            int n)
715
{
716
    int i, nw, j, k;
717
    abi_ulong b, *target_fds;
718

    
719
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
720
    if (!(target_fds = lock_user(VERIFY_READ,
721
                                 target_fds_addr,
722
                                 sizeof(abi_ulong) * nw,
723
                                 1)))
724
        return -TARGET_EFAULT;
725

    
726
    FD_ZERO(fds);
727
    k = 0;
728
    for (i = 0; i < nw; i++) {
729
        /* grab the abi_ulong */
730
        __get_user(b, &target_fds[i]);
731
        for (j = 0; j < TARGET_ABI_BITS; j++) {
732
            /* check the bit inside the abi_ulong */
733
            if ((b >> j) & 1)
734
                FD_SET(k, fds);
735
            k++;
736
        }
737
    }
738

    
739
    unlock_user(target_fds, target_fds_addr, 0);
740

    
741
    return 0;
742
}
743

    
744
static inline abi_ulong copy_from_user_fdset_ptr(fd_set *fds, fd_set **fds_ptr,
745
                                                 abi_ulong target_fds_addr,
746
                                                 int n)
747
{
748
    if (target_fds_addr) {
749
        if (copy_from_user_fdset(fds, target_fds_addr, n))
750
            return -TARGET_EFAULT;
751
        *fds_ptr = fds;
752
    } else {
753
        *fds_ptr = NULL;
754
    }
755
    return 0;
756
}
757

    
758
static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
759
                                          const fd_set *fds,
760
                                          int n)
761
{
762
    int i, nw, j, k;
763
    abi_long v;
764
    abi_ulong *target_fds;
765

    
766
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
767
    if (!(target_fds = lock_user(VERIFY_WRITE,
768
                                 target_fds_addr,
769
                                 sizeof(abi_ulong) * nw,
770
                                 0)))
771
        return -TARGET_EFAULT;
772

    
773
    k = 0;
774
    for (i = 0; i < nw; i++) {
775
        v = 0;
776
        for (j = 0; j < TARGET_ABI_BITS; j++) {
777
            v |= ((abi_ulong)(FD_ISSET(k, fds) != 0) << j);
778
            k++;
779
        }
780
        __put_user(v, &target_fds[i]);
781
    }
782

    
783
    unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
784

    
785
    return 0;
786
}
787

    
788
#if defined(__alpha__)
789
#define HOST_HZ 1024
790
#else
791
#define HOST_HZ 100
792
#endif
793

    
794
static inline abi_long host_to_target_clock_t(long ticks)
795
{
796
#if HOST_HZ == TARGET_HZ
797
    return ticks;
798
#else
799
    return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
800
#endif
801
}
802

    
803
static inline abi_long host_to_target_rusage(abi_ulong target_addr,
804
                                             const struct rusage *rusage)
805
{
806
    struct target_rusage *target_rusage;
807

    
808
    if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
809
        return -TARGET_EFAULT;
810
    target_rusage->ru_utime.tv_sec = tswapal(rusage->ru_utime.tv_sec);
811
    target_rusage->ru_utime.tv_usec = tswapal(rusage->ru_utime.tv_usec);
812
    target_rusage->ru_stime.tv_sec = tswapal(rusage->ru_stime.tv_sec);
813
    target_rusage->ru_stime.tv_usec = tswapal(rusage->ru_stime.tv_usec);
814
    target_rusage->ru_maxrss = tswapal(rusage->ru_maxrss);
815
    target_rusage->ru_ixrss = tswapal(rusage->ru_ixrss);
816
    target_rusage->ru_idrss = tswapal(rusage->ru_idrss);
817
    target_rusage->ru_isrss = tswapal(rusage->ru_isrss);
818
    target_rusage->ru_minflt = tswapal(rusage->ru_minflt);
819
    target_rusage->ru_majflt = tswapal(rusage->ru_majflt);
820
    target_rusage->ru_nswap = tswapal(rusage->ru_nswap);
821
    target_rusage->ru_inblock = tswapal(rusage->ru_inblock);
822
    target_rusage->ru_oublock = tswapal(rusage->ru_oublock);
823
    target_rusage->ru_msgsnd = tswapal(rusage->ru_msgsnd);
824
    target_rusage->ru_msgrcv = tswapal(rusage->ru_msgrcv);
825
    target_rusage->ru_nsignals = tswapal(rusage->ru_nsignals);
826
    target_rusage->ru_nvcsw = tswapal(rusage->ru_nvcsw);
827
    target_rusage->ru_nivcsw = tswapal(rusage->ru_nivcsw);
828
    unlock_user_struct(target_rusage, target_addr, 1);
829

    
830
    return 0;
831
}
832

    
833
static inline rlim_t target_to_host_rlim(abi_ulong target_rlim)
834
{
835
    abi_ulong target_rlim_swap;
836
    rlim_t result;
837
    
838
    target_rlim_swap = tswapal(target_rlim);
839
    if (target_rlim_swap == TARGET_RLIM_INFINITY)
840
        return RLIM_INFINITY;
841

    
842
    result = target_rlim_swap;
843
    if (target_rlim_swap != (rlim_t)result)
844
        return RLIM_INFINITY;
845
    
846
    return result;
847
}
848

    
849
static inline abi_ulong host_to_target_rlim(rlim_t rlim)
850
{
851
    abi_ulong target_rlim_swap;
852
    abi_ulong result;
853
    
854
    if (rlim == RLIM_INFINITY || rlim != (abi_long)rlim)
855
        target_rlim_swap = TARGET_RLIM_INFINITY;
856
    else
857
        target_rlim_swap = rlim;
858
    result = tswapal(target_rlim_swap);
859
    
860
    return result;
861
}
862

    
863
static inline int target_to_host_resource(int code)
864
{
865
    switch (code) {
866
    case TARGET_RLIMIT_AS:
867
        return RLIMIT_AS;
868
    case TARGET_RLIMIT_CORE:
869
        return RLIMIT_CORE;
870
    case TARGET_RLIMIT_CPU:
871
        return RLIMIT_CPU;
872
    case TARGET_RLIMIT_DATA:
873
        return RLIMIT_DATA;
874
    case TARGET_RLIMIT_FSIZE:
875
        return RLIMIT_FSIZE;
876
    case TARGET_RLIMIT_LOCKS:
877
        return RLIMIT_LOCKS;
878
    case TARGET_RLIMIT_MEMLOCK:
879
        return RLIMIT_MEMLOCK;
880
    case TARGET_RLIMIT_MSGQUEUE:
881
        return RLIMIT_MSGQUEUE;
882
    case TARGET_RLIMIT_NICE:
883
        return RLIMIT_NICE;
884
    case TARGET_RLIMIT_NOFILE:
885
        return RLIMIT_NOFILE;
886
    case TARGET_RLIMIT_NPROC:
887
        return RLIMIT_NPROC;
888
    case TARGET_RLIMIT_RSS:
889
        return RLIMIT_RSS;
890
    case TARGET_RLIMIT_RTPRIO:
891
        return RLIMIT_RTPRIO;
892
    case TARGET_RLIMIT_SIGPENDING:
893
        return RLIMIT_SIGPENDING;
894
    case TARGET_RLIMIT_STACK:
895
        return RLIMIT_STACK;
896
    default:
897
        return code;
898
    }
899
}
900

    
901
static inline abi_long copy_from_user_timeval(struct timeval *tv,
902
                                              abi_ulong target_tv_addr)
903
{
904
    struct target_timeval *target_tv;
905

    
906
    if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
907
        return -TARGET_EFAULT;
908

    
909
    __get_user(tv->tv_sec, &target_tv->tv_sec);
910
    __get_user(tv->tv_usec, &target_tv->tv_usec);
911

    
912
    unlock_user_struct(target_tv, target_tv_addr, 0);
913

    
914
    return 0;
915
}
916

    
917
static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
918
                                            const struct timeval *tv)
919
{
920
    struct target_timeval *target_tv;
921

    
922
    if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
923
        return -TARGET_EFAULT;
924

    
925
    __put_user(tv->tv_sec, &target_tv->tv_sec);
926
    __put_user(tv->tv_usec, &target_tv->tv_usec);
927

    
928
    unlock_user_struct(target_tv, target_tv_addr, 1);
929

    
930
    return 0;
931
}
932

    
933
#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
934
#include <mqueue.h>
935

    
936
static inline abi_long copy_from_user_mq_attr(struct mq_attr *attr,
937
                                              abi_ulong target_mq_attr_addr)
938
{
939
    struct target_mq_attr *target_mq_attr;
940

    
941
    if (!lock_user_struct(VERIFY_READ, target_mq_attr,
942
                          target_mq_attr_addr, 1))
943
        return -TARGET_EFAULT;
944

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

    
950
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0);
951

    
952
    return 0;
953
}
954

    
955
static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr,
956
                                            const struct mq_attr *attr)
957
{
958
    struct target_mq_attr *target_mq_attr;
959

    
960
    if (!lock_user_struct(VERIFY_WRITE, target_mq_attr,
961
                          target_mq_attr_addr, 0))
962
        return -TARGET_EFAULT;
963

    
964
    __put_user(attr->mq_flags, &target_mq_attr->mq_flags);
965
    __put_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
966
    __put_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
967
    __put_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
968

    
969
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1);
970

    
971
    return 0;
972
}
973
#endif
974

    
975
#if defined(TARGET_NR_select) || defined(TARGET_NR__newselect)
976
/* do_select() must return target values and target errnos. */
977
static abi_long do_select(int n,
978
                          abi_ulong rfd_addr, abi_ulong wfd_addr,
979
                          abi_ulong efd_addr, abi_ulong target_tv_addr)
980
{
981
    fd_set rfds, wfds, efds;
982
    fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
983
    struct timeval tv, *tv_ptr;
984
    abi_long ret;
985

    
986
    ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
987
    if (ret) {
988
        return ret;
989
    }
990
    ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
991
    if (ret) {
992
        return ret;
993
    }
994
    ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
995
    if (ret) {
996
        return ret;
997
    }
998

    
999
    if (target_tv_addr) {
1000
        if (copy_from_user_timeval(&tv, target_tv_addr))
1001
            return -TARGET_EFAULT;
1002
        tv_ptr = &tv;
1003
    } else {
1004
        tv_ptr = NULL;
1005
    }
1006

    
1007
    ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
1008

    
1009
    if (!is_error(ret)) {
1010
        if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
1011
            return -TARGET_EFAULT;
1012
        if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
1013
            return -TARGET_EFAULT;
1014
        if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
1015
            return -TARGET_EFAULT;
1016

    
1017
        if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
1018
            return -TARGET_EFAULT;
1019
    }
1020

    
1021
    return ret;
1022
}
1023
#endif
1024

    
1025
static abi_long do_pipe2(int host_pipe[], int flags)
1026
{
1027
#ifdef CONFIG_PIPE2
1028
    return pipe2(host_pipe, flags);
1029
#else
1030
    return -ENOSYS;
1031
#endif
1032
}
1033

    
1034
static abi_long do_pipe(void *cpu_env, abi_ulong pipedes,
1035
                        int flags, int is_pipe2)
1036
{
1037
    int host_pipe[2];
1038
    abi_long ret;
1039
    ret = flags ? do_pipe2(host_pipe, flags) : pipe(host_pipe);
1040

    
1041
    if (is_error(ret))
1042
        return get_errno(ret);
1043

    
1044
    /* Several targets have special calling conventions for the original
1045
       pipe syscall, but didn't replicate this into the pipe2 syscall.  */
1046
    if (!is_pipe2) {
1047
#if defined(TARGET_ALPHA)
1048
        ((CPUAlphaState *)cpu_env)->ir[IR_A4] = host_pipe[1];
1049
        return host_pipe[0];
1050
#elif defined(TARGET_MIPS)
1051
        ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1];
1052
        return host_pipe[0];
1053
#elif defined(TARGET_SH4)
1054
        ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
1055
        return host_pipe[0];
1056
#elif defined(TARGET_SPARC)
1057
        ((CPUSPARCState*)cpu_env)->regwptr[1] = host_pipe[1];
1058
        return host_pipe[0];
1059
#endif
1060
    }
1061

    
1062
    if (put_user_s32(host_pipe[0], pipedes)
1063
        || put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0])))
1064
        return -TARGET_EFAULT;
1065
    return get_errno(ret);
1066
}
1067

    
1068
static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn,
1069
                                              abi_ulong target_addr,
1070
                                              socklen_t len)
1071
{
1072
    struct target_ip_mreqn *target_smreqn;
1073

    
1074
    target_smreqn = lock_user(VERIFY_READ, target_addr, len, 1);
1075
    if (!target_smreqn)
1076
        return -TARGET_EFAULT;
1077
    mreqn->imr_multiaddr.s_addr = target_smreqn->imr_multiaddr.s_addr;
1078
    mreqn->imr_address.s_addr = target_smreqn->imr_address.s_addr;
1079
    if (len == sizeof(struct target_ip_mreqn))
1080
        mreqn->imr_ifindex = tswapal(target_smreqn->imr_ifindex);
1081
    unlock_user(target_smreqn, target_addr, 0);
1082

    
1083
    return 0;
1084
}
1085

    
1086
static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
1087
                                               abi_ulong target_addr,
1088
                                               socklen_t len)
1089
{
1090
    const socklen_t unix_maxlen = sizeof (struct sockaddr_un);
1091
    sa_family_t sa_family;
1092
    struct target_sockaddr *target_saddr;
1093

    
1094
    target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
1095
    if (!target_saddr)
1096
        return -TARGET_EFAULT;
1097

    
1098
    sa_family = tswap16(target_saddr->sa_family);
1099

    
1100
    /* Oops. The caller might send a incomplete sun_path; sun_path
1101
     * must be terminated by \0 (see the manual page), but
1102
     * unfortunately it is quite common to specify sockaddr_un
1103
     * length as "strlen(x->sun_path)" while it should be
1104
     * "strlen(...) + 1". We'll fix that here if needed.
1105
     * Linux kernel has a similar feature.
1106
     */
1107

    
1108
    if (sa_family == AF_UNIX) {
1109
        if (len < unix_maxlen && len > 0) {
1110
            char *cp = (char*)target_saddr;
1111

    
1112
            if ( cp[len-1] && !cp[len] )
1113
                len++;
1114
        }
1115
        if (len > unix_maxlen)
1116
            len = unix_maxlen;
1117
    }
1118

    
1119
    memcpy(addr, target_saddr, len);
1120
    addr->sa_family = sa_family;
1121
    unlock_user(target_saddr, target_addr, 0);
1122

    
1123
    return 0;
1124
}
1125

    
1126
static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
1127
                                               struct sockaddr *addr,
1128
                                               socklen_t len)
1129
{
1130
    struct target_sockaddr *target_saddr;
1131

    
1132
    target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
1133
    if (!target_saddr)
1134
        return -TARGET_EFAULT;
1135
    memcpy(target_saddr, addr, len);
1136
    target_saddr->sa_family = tswap16(addr->sa_family);
1137
    unlock_user(target_saddr, target_addr, len);
1138

    
1139
    return 0;
1140
}
1141

    
1142
static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
1143
                                           struct target_msghdr *target_msgh)
1144
{
1145
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1146
    abi_long msg_controllen;
1147
    abi_ulong target_cmsg_addr;
1148
    struct target_cmsghdr *target_cmsg;
1149
    socklen_t space = 0;
1150
    
1151
    msg_controllen = tswapal(target_msgh->msg_controllen);
1152
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1153
        goto the_end;
1154
    target_cmsg_addr = tswapal(target_msgh->msg_control);
1155
    target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
1156
    if (!target_cmsg)
1157
        return -TARGET_EFAULT;
1158

    
1159
    while (cmsg && target_cmsg) {
1160
        void *data = CMSG_DATA(cmsg);
1161
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
1162

    
1163
        int len = tswapal(target_cmsg->cmsg_len)
1164
                  - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
1165

    
1166
        space += CMSG_SPACE(len);
1167
        if (space > msgh->msg_controllen) {
1168
            space -= CMSG_SPACE(len);
1169
            gemu_log("Host cmsg overflow\n");
1170
            break;
1171
        }
1172

    
1173
        if (tswap32(target_cmsg->cmsg_level) == TARGET_SOL_SOCKET) {
1174
            cmsg->cmsg_level = SOL_SOCKET;
1175
        } else {
1176
            cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
1177
        }
1178
        cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
1179
        cmsg->cmsg_len = CMSG_LEN(len);
1180

    
1181
        if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1182
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1183
            memcpy(data, target_data, len);
1184
        } else {
1185
            int *fd = (int *)data;
1186
            int *target_fd = (int *)target_data;
1187
            int i, numfds = len / sizeof(int);
1188

    
1189
            for (i = 0; i < numfds; i++)
1190
                fd[i] = tswap32(target_fd[i]);
1191
        }
1192

    
1193
        cmsg = CMSG_NXTHDR(msgh, cmsg);
1194
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1195
    }
1196
    unlock_user(target_cmsg, target_cmsg_addr, 0);
1197
 the_end:
1198
    msgh->msg_controllen = space;
1199
    return 0;
1200
}
1201

    
1202
static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
1203
                                           struct msghdr *msgh)
1204
{
1205
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1206
    abi_long msg_controllen;
1207
    abi_ulong target_cmsg_addr;
1208
    struct target_cmsghdr *target_cmsg;
1209
    socklen_t space = 0;
1210

    
1211
    msg_controllen = tswapal(target_msgh->msg_controllen);
1212
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1213
        goto the_end;
1214
    target_cmsg_addr = tswapal(target_msgh->msg_control);
1215
    target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
1216
    if (!target_cmsg)
1217
        return -TARGET_EFAULT;
1218

    
1219
    while (cmsg && target_cmsg) {
1220
        void *data = CMSG_DATA(cmsg);
1221
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
1222

    
1223
        int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
1224

    
1225
        space += TARGET_CMSG_SPACE(len);
1226
        if (space > msg_controllen) {
1227
            space -= TARGET_CMSG_SPACE(len);
1228
            gemu_log("Target cmsg overflow\n");
1229
            break;
1230
        }
1231

    
1232
        if (cmsg->cmsg_level == SOL_SOCKET) {
1233
            target_cmsg->cmsg_level = tswap32(TARGET_SOL_SOCKET);
1234
        } else {
1235
            target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
1236
        }
1237
        target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
1238
        target_cmsg->cmsg_len = tswapal(TARGET_CMSG_LEN(len));
1239

    
1240
        if ((cmsg->cmsg_level == SOL_SOCKET) &&
1241
                                (cmsg->cmsg_type == SCM_RIGHTS)) {
1242
            int *fd = (int *)data;
1243
            int *target_fd = (int *)target_data;
1244
            int i, numfds = len / sizeof(int);
1245

    
1246
            for (i = 0; i < numfds; i++)
1247
                target_fd[i] = tswap32(fd[i]);
1248
        } else if ((cmsg->cmsg_level == SOL_SOCKET) &&
1249
                                (cmsg->cmsg_type == SO_TIMESTAMP) &&
1250
                                (len == sizeof(struct timeval))) {
1251
            /* copy struct timeval to target */
1252
            struct timeval *tv = (struct timeval *)data;
1253
            struct target_timeval *target_tv =
1254
                                        (struct target_timeval *)target_data;
1255

    
1256
            target_tv->tv_sec = tswapal(tv->tv_sec);
1257
            target_tv->tv_usec = tswapal(tv->tv_usec);
1258
        } else {
1259
            gemu_log("Unsupported ancillary data: %d/%d\n",
1260
                                        cmsg->cmsg_level, cmsg->cmsg_type);
1261
            memcpy(target_data, data, len);
1262
        }
1263

    
1264
        cmsg = CMSG_NXTHDR(msgh, cmsg);
1265
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1266
    }
1267
    unlock_user(target_cmsg, target_cmsg_addr, space);
1268
 the_end:
1269
    target_msgh->msg_controllen = tswapal(space);
1270
    return 0;
1271
}
1272

    
1273
/* do_setsockopt() Must return target values and target errnos. */
1274
static abi_long do_setsockopt(int sockfd, int level, int optname,
1275
                              abi_ulong optval_addr, socklen_t optlen)
1276
{
1277
    abi_long ret;
1278
    int val;
1279
    struct ip_mreqn *ip_mreq;
1280
    struct ip_mreq_source *ip_mreq_source;
1281

    
1282
    switch(level) {
1283
    case SOL_TCP:
1284
        /* TCP options all take an 'int' value.  */
1285
        if (optlen < sizeof(uint32_t))
1286
            return -TARGET_EINVAL;
1287

    
1288
        if (get_user_u32(val, optval_addr))
1289
            return -TARGET_EFAULT;
1290
        ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1291
        break;
1292
    case SOL_IP:
1293
        switch(optname) {
1294
        case IP_TOS:
1295
        case IP_TTL:
1296
        case IP_HDRINCL:
1297
        case IP_ROUTER_ALERT:
1298
        case IP_RECVOPTS:
1299
        case IP_RETOPTS:
1300
        case IP_PKTINFO:
1301
        case IP_MTU_DISCOVER:
1302
        case IP_RECVERR:
1303
        case IP_RECVTOS:
1304
#ifdef IP_FREEBIND
1305
        case IP_FREEBIND:
1306
#endif
1307
        case IP_MULTICAST_TTL:
1308
        case IP_MULTICAST_LOOP:
1309
            val = 0;
1310
            if (optlen >= sizeof(uint32_t)) {
1311
                if (get_user_u32(val, optval_addr))
1312
                    return -TARGET_EFAULT;
1313
            } else if (optlen >= 1) {
1314
                if (get_user_u8(val, optval_addr))
1315
                    return -TARGET_EFAULT;
1316
            }
1317
            ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1318
            break;
1319
        case IP_ADD_MEMBERSHIP:
1320
        case IP_DROP_MEMBERSHIP:
1321
            if (optlen < sizeof (struct target_ip_mreq) ||
1322
                optlen > sizeof (struct target_ip_mreqn))
1323
                return -TARGET_EINVAL;
1324

    
1325
            ip_mreq = (struct ip_mreqn *) alloca(optlen);
1326
            target_to_host_ip_mreq(ip_mreq, optval_addr, optlen);
1327
            ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq, optlen));
1328
            break;
1329

    
1330
        case IP_BLOCK_SOURCE:
1331
        case IP_UNBLOCK_SOURCE:
1332
        case IP_ADD_SOURCE_MEMBERSHIP:
1333
        case IP_DROP_SOURCE_MEMBERSHIP:
1334
            if (optlen != sizeof (struct target_ip_mreq_source))
1335
                return -TARGET_EINVAL;
1336

    
1337
            ip_mreq_source = lock_user(VERIFY_READ, optval_addr, optlen, 1);
1338
            ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq_source, optlen));
1339
            unlock_user (ip_mreq_source, optval_addr, 0);
1340
            break;
1341

    
1342
        default:
1343
            goto unimplemented;
1344
        }
1345
        break;
1346
    case SOL_IPV6:
1347
        switch (optname) {
1348
        case IPV6_MTU_DISCOVER:
1349
        case IPV6_MTU:
1350
        case IPV6_V6ONLY:
1351
        case IPV6_RECVPKTINFO:
1352
            val = 0;
1353
            if (optlen < sizeof(uint32_t)) {
1354
                return -TARGET_EINVAL;
1355
            }
1356
            if (get_user_u32(val, optval_addr)) {
1357
                return -TARGET_EFAULT;
1358
            }
1359
            ret = get_errno(setsockopt(sockfd, level, optname,
1360
                                       &val, sizeof(val)));
1361
            break;
1362
        default:
1363
            goto unimplemented;
1364
        }
1365
        break;
1366
    case SOL_RAW:
1367
        switch (optname) {
1368
        case ICMP_FILTER:
1369
            /* struct icmp_filter takes an u32 value */
1370
            if (optlen < sizeof(uint32_t)) {
1371
                return -TARGET_EINVAL;
1372
            }
1373

    
1374
            if (get_user_u32(val, optval_addr)) {
1375
                return -TARGET_EFAULT;
1376
            }
1377
            ret = get_errno(setsockopt(sockfd, level, optname,
1378
                                       &val, sizeof(val)));
1379
            break;
1380

    
1381
        default:
1382
            goto unimplemented;
1383
        }
1384
        break;
1385
    case TARGET_SOL_SOCKET:
1386
        switch (optname) {
1387
        case TARGET_SO_RCVTIMEO:
1388
        {
1389
                struct timeval tv;
1390

    
1391
                optname = SO_RCVTIMEO;
1392

    
1393
set_timeout:
1394
                if (optlen != sizeof(struct target_timeval)) {
1395
                    return -TARGET_EINVAL;
1396
                }
1397

    
1398
                if (copy_from_user_timeval(&tv, optval_addr)) {
1399
                    return -TARGET_EFAULT;
1400
                }
1401

    
1402
                ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname,
1403
                                &tv, sizeof(tv)));
1404
                return ret;
1405
        }
1406
        case TARGET_SO_SNDTIMEO:
1407
                optname = SO_SNDTIMEO;
1408
                goto set_timeout;
1409
        case TARGET_SO_ATTACH_FILTER:
1410
        {
1411
                struct target_sock_fprog *tfprog;
1412
                struct target_sock_filter *tfilter;
1413
                struct sock_fprog fprog;
1414
                struct sock_filter *filter;
1415
                int i;
1416

    
1417
                if (optlen != sizeof(*tfprog)) {
1418
                    return -TARGET_EINVAL;
1419
                }
1420
                if (!lock_user_struct(VERIFY_READ, tfprog, optval_addr, 0)) {
1421
                    return -TARGET_EFAULT;
1422
                }
1423
                if (!lock_user_struct(VERIFY_READ, tfilter,
1424
                                      tswapal(tfprog->filter), 0)) {
1425
                    unlock_user_struct(tfprog, optval_addr, 1);
1426
                    return -TARGET_EFAULT;
1427
                }
1428

    
1429
                fprog.len = tswap16(tfprog->len);
1430
                filter = malloc(fprog.len * sizeof(*filter));
1431
                if (filter == NULL) {
1432
                    unlock_user_struct(tfilter, tfprog->filter, 1);
1433
                    unlock_user_struct(tfprog, optval_addr, 1);
1434
                    return -TARGET_ENOMEM;
1435
                }
1436
                for (i = 0; i < fprog.len; i++) {
1437
                    filter[i].code = tswap16(tfilter[i].code);
1438
                    filter[i].jt = tfilter[i].jt;
1439
                    filter[i].jf = tfilter[i].jf;
1440
                    filter[i].k = tswap32(tfilter[i].k);
1441
                }
1442
                fprog.filter = filter;
1443

    
1444
                ret = get_errno(setsockopt(sockfd, SOL_SOCKET,
1445
                                SO_ATTACH_FILTER, &fprog, sizeof(fprog)));
1446
                free(filter);
1447

    
1448
                unlock_user_struct(tfilter, tfprog->filter, 1);
1449
                unlock_user_struct(tfprog, optval_addr, 1);
1450
                return ret;
1451
        }
1452
            /* Options with 'int' argument.  */
1453
        case TARGET_SO_DEBUG:
1454
                optname = SO_DEBUG;
1455
                break;
1456
        case TARGET_SO_REUSEADDR:
1457
                optname = SO_REUSEADDR;
1458
                break;
1459
        case TARGET_SO_TYPE:
1460
                optname = SO_TYPE;
1461
                break;
1462
        case TARGET_SO_ERROR:
1463
                optname = SO_ERROR;
1464
                break;
1465
        case TARGET_SO_DONTROUTE:
1466
                optname = SO_DONTROUTE;
1467
                break;
1468
        case TARGET_SO_BROADCAST:
1469
                optname = SO_BROADCAST;
1470
                break;
1471
        case TARGET_SO_SNDBUF:
1472
                optname = SO_SNDBUF;
1473
                break;
1474
        case TARGET_SO_RCVBUF:
1475
                optname = SO_RCVBUF;
1476
                break;
1477
        case TARGET_SO_KEEPALIVE:
1478
                optname = SO_KEEPALIVE;
1479
                break;
1480
        case TARGET_SO_OOBINLINE:
1481
                optname = SO_OOBINLINE;
1482
                break;
1483
        case TARGET_SO_NO_CHECK:
1484
                optname = SO_NO_CHECK;
1485
                break;
1486
        case TARGET_SO_PRIORITY:
1487
                optname = SO_PRIORITY;
1488
                break;
1489
#ifdef SO_BSDCOMPAT
1490
        case TARGET_SO_BSDCOMPAT:
1491
                optname = SO_BSDCOMPAT;
1492
                break;
1493
#endif
1494
        case TARGET_SO_PASSCRED:
1495
                optname = SO_PASSCRED;
1496
                break;
1497
        case TARGET_SO_TIMESTAMP:
1498
                optname = SO_TIMESTAMP;
1499
                break;
1500
        case TARGET_SO_RCVLOWAT:
1501
                optname = SO_RCVLOWAT;
1502
                break;
1503
            break;
1504
        default:
1505
            goto unimplemented;
1506
        }
1507
        if (optlen < sizeof(uint32_t))
1508
            return -TARGET_EINVAL;
1509

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

    
1522
/* do_getsockopt() Must return target values and target errnos. */
1523
static abi_long do_getsockopt(int sockfd, int level, int optname,
1524
                              abi_ulong optval_addr, abi_ulong optlen)
1525
{
1526
    abi_long ret;
1527
    int len, val;
1528
    socklen_t lv;
1529

    
1530
    switch(level) {
1531
    case TARGET_SOL_SOCKET:
1532
        level = SOL_SOCKET;
1533
        switch (optname) {
1534
        /* These don't just return a single integer */
1535
        case TARGET_SO_LINGER:
1536
        case TARGET_SO_RCVTIMEO:
1537
        case TARGET_SO_SNDTIMEO:
1538
        case TARGET_SO_PEERNAME:
1539
            goto unimplemented;
1540
        case TARGET_SO_PEERCRED: {
1541
            struct ucred cr;
1542
            socklen_t crlen;
1543
            struct target_ucred *tcr;
1544

    
1545
            if (get_user_u32(len, optlen)) {
1546
                return -TARGET_EFAULT;
1547
            }
1548
            if (len < 0) {
1549
                return -TARGET_EINVAL;
1550
            }
1551

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

    
1704
static struct iovec *lock_iovec(int type, abi_ulong target_addr,
1705
                                int count, int copy)
1706
{
1707
    struct target_iovec *target_vec;
1708
    struct iovec *vec;
1709
    abi_ulong total_len, max_len;
1710
    int i;
1711
    int err = 0;
1712

    
1713
    if (count == 0) {
1714
        errno = 0;
1715
        return NULL;
1716
    }
1717
    if (count < 0 || count > IOV_MAX) {
1718
        errno = EINVAL;
1719
        return NULL;
1720
    }
1721

    
1722
    vec = calloc(count, sizeof(struct iovec));
1723
    if (vec == NULL) {
1724
        errno = ENOMEM;
1725
        return NULL;
1726
    }
1727

    
1728
    target_vec = lock_user(VERIFY_READ, target_addr,
1729
                           count * sizeof(struct target_iovec), 1);
1730
    if (target_vec == NULL) {
1731
        err = EFAULT;
1732
        goto fail2;
1733
    }
1734

    
1735
    /* ??? If host page size > target page size, this will result in a
1736
       value larger than what we can actually support.  */
1737
    max_len = 0x7fffffff & TARGET_PAGE_MASK;
1738
    total_len = 0;
1739

    
1740
    for (i = 0; i < count; i++) {
1741
        abi_ulong base = tswapal(target_vec[i].iov_base);
1742
        abi_long len = tswapal(target_vec[i].iov_len);
1743

    
1744
        if (len < 0) {
1745
            err = EINVAL;
1746
            goto fail;
1747
        } else if (len == 0) {
1748
            /* Zero length pointer is ignored.  */
1749
            vec[i].iov_base = 0;
1750
        } else {
1751
            vec[i].iov_base = lock_user(type, base, len, copy);
1752
            if (!vec[i].iov_base) {
1753
                err = EFAULT;
1754
                goto fail;
1755
            }
1756
            if (len > max_len - total_len) {
1757
                len = max_len - total_len;
1758
            }
1759
        }
1760
        vec[i].iov_len = len;
1761
        total_len += len;
1762
    }
1763

    
1764
    unlock_user(target_vec, target_addr, 0);
1765
    return vec;
1766

    
1767
 fail:
1768
    unlock_user(target_vec, target_addr, 0);
1769
 fail2:
1770
    free(vec);
1771
    errno = err;
1772
    return NULL;
1773
}
1774

    
1775
static void unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1776
                         int count, int copy)
1777
{
1778
    struct target_iovec *target_vec;
1779
    int i;
1780

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

    
1795
    free(vec);
1796
}
1797

    
1798
static inline int target_to_host_sock_type(int *type)
1799
{
1800
    int host_type = 0;
1801
    int target_type = *type;
1802

    
1803
    switch (target_type & TARGET_SOCK_TYPE_MASK) {
1804
    case TARGET_SOCK_DGRAM:
1805
        host_type = SOCK_DGRAM;
1806
        break;
1807
    case TARGET_SOCK_STREAM:
1808
        host_type = SOCK_STREAM;
1809
        break;
1810
    default:
1811
        host_type = target_type & TARGET_SOCK_TYPE_MASK;
1812
        break;
1813
    }
1814
    if (target_type & TARGET_SOCK_CLOEXEC) {
1815
#if defined(SOCK_CLOEXEC)
1816
        host_type |= SOCK_CLOEXEC;
1817
#else
1818
        return -TARGET_EINVAL;
1819
#endif
1820
    }
1821
    if (target_type & TARGET_SOCK_NONBLOCK) {
1822
#if defined(SOCK_NONBLOCK)
1823
        host_type |= SOCK_NONBLOCK;
1824
#elif !defined(O_NONBLOCK)
1825
        return -TARGET_EINVAL;
1826
#endif
1827
    }
1828
    *type = host_type;
1829
    return 0;
1830
}
1831

    
1832
/* Try to emulate socket type flags after socket creation.  */
1833
static int sock_flags_fixup(int fd, int target_type)
1834
{
1835
#if !defined(SOCK_NONBLOCK) && defined(O_NONBLOCK)
1836
    if (target_type & TARGET_SOCK_NONBLOCK) {
1837
        int flags = fcntl(fd, F_GETFL);
1838
        if (fcntl(fd, F_SETFL, O_NONBLOCK | flags) == -1) {
1839
            close(fd);
1840
            return -TARGET_EINVAL;
1841
        }
1842
    }
1843
#endif
1844
    return fd;
1845
}
1846

    
1847
/* do_socket() Must return target values and target errnos. */
1848
static abi_long do_socket(int domain, int type, int protocol)
1849
{
1850
    int target_type = type;
1851
    int ret;
1852

    
1853
    ret = target_to_host_sock_type(&type);
1854
    if (ret) {
1855
        return ret;
1856
    }
1857

    
1858
    if (domain == PF_NETLINK)
1859
        return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1860
    ret = get_errno(socket(domain, type, protocol));
1861
    if (ret >= 0) {
1862
        ret = sock_flags_fixup(ret, target_type);
1863
    }
1864
    return ret;
1865
}
1866

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

    
1874
    if ((int)addrlen < 0) {
1875
        return -TARGET_EINVAL;
1876
    }
1877

    
1878
    addr = alloca(addrlen+1);
1879

    
1880
    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1881
    if (ret)
1882
        return ret;
1883

    
1884
    return get_errno(bind(sockfd, addr, addrlen));
1885
}
1886

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

    
1894
    if ((int)addrlen < 0) {
1895
        return -TARGET_EINVAL;
1896
    }
1897

    
1898
    addr = alloca(addrlen);
1899

    
1900
    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1901
    if (ret)
1902
        return ret;
1903

    
1904
    return get_errno(connect(sockfd, addr, addrlen));
1905
}
1906

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

    
1917
    if (msgp->msg_name) {
1918
        msg.msg_namelen = tswap32(msgp->msg_namelen);
1919
        msg.msg_name = alloca(msg.msg_namelen);
1920
        ret = target_to_host_sockaddr(msg.msg_name, tswapal(msgp->msg_name),
1921
                                msg.msg_namelen);
1922
        if (ret) {
1923
            goto out2;
1924
        }
1925
    } else {
1926
        msg.msg_name = NULL;
1927
        msg.msg_namelen = 0;
1928
    }
1929
    msg.msg_controllen = 2 * tswapal(msgp->msg_controllen);
1930
    msg.msg_control = alloca(msg.msg_controllen);
1931
    msg.msg_flags = tswap32(msgp->msg_flags);
1932

    
1933
    count = tswapal(msgp->msg_iovlen);
1934
    target_vec = tswapal(msgp->msg_iov);
1935
    vec = lock_iovec(send ? VERIFY_READ : VERIFY_WRITE,
1936
                     target_vec, count, send);
1937
    if (vec == NULL) {
1938
        ret = -host_to_target_errno(errno);
1939
        goto out2;
1940
    }
1941
    msg.msg_iovlen = count;
1942
    msg.msg_iov = vec;
1943

    
1944
    if (send) {
1945
        ret = target_to_host_cmsg(&msg, msgp);
1946
        if (ret == 0)
1947
            ret = get_errno(sendmsg(fd, &msg, flags));
1948
    } else {
1949
        ret = get_errno(recvmsg(fd, &msg, flags));
1950
        if (!is_error(ret)) {
1951
            len = ret;
1952
            ret = host_to_target_cmsg(msgp, &msg);
1953
            if (!is_error(ret)) {
1954
                msgp->msg_namelen = tswap32(msg.msg_namelen);
1955
                if (msg.msg_name != NULL) {
1956
                    ret = host_to_target_sockaddr(tswapal(msgp->msg_name),
1957
                                    msg.msg_name, msg.msg_namelen);
1958
                    if (ret) {
1959
                        goto out;
1960
                    }
1961
                }
1962

    
1963
                ret = len;
1964
            }
1965
        }
1966
    }
1967

    
1968
out:
1969
    unlock_iovec(vec, target_vec, count, !send);
1970
out2:
1971
    return ret;
1972
}
1973

    
1974
static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1975
                               int flags, int send)
1976
{
1977
    abi_long ret;
1978
    struct target_msghdr *msgp;
1979

    
1980
    if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1981
                          msgp,
1982
                          target_msg,
1983
                          send ? 1 : 0)) {
1984
        return -TARGET_EFAULT;
1985
    }
1986
    ret = do_sendrecvmsg_locked(fd, msgp, flags, send);
1987
    unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1988
    return ret;
1989
}
1990

    
1991
#ifdef TARGET_NR_sendmmsg
1992
/* We don't rely on the C library to have sendmmsg/recvmmsg support,
1993
 * so it might not have this *mmsg-specific flag either.
1994
 */
1995
#ifndef MSG_WAITFORONE
1996
#define MSG_WAITFORONE 0x10000
1997
#endif
1998

    
1999
static abi_long do_sendrecvmmsg(int fd, abi_ulong target_msgvec,
2000
                                unsigned int vlen, unsigned int flags,
2001
                                int send)
2002
{
2003
    struct target_mmsghdr *mmsgp;
2004
    abi_long ret = 0;
2005
    int i;
2006

    
2007
    if (vlen > UIO_MAXIOV) {
2008
        vlen = UIO_MAXIOV;
2009
    }
2010

    
2011
    mmsgp = lock_user(VERIFY_WRITE, target_msgvec, sizeof(*mmsgp) * vlen, 1);
2012
    if (!mmsgp) {
2013
        return -TARGET_EFAULT;
2014
    }
2015

    
2016
    for (i = 0; i < vlen; i++) {
2017
        ret = do_sendrecvmsg_locked(fd, &mmsgp[i].msg_hdr, flags, send);
2018
        if (is_error(ret)) {
2019
            break;
2020
        }
2021
        mmsgp[i].msg_len = tswap32(ret);
2022
        /* MSG_WAITFORONE turns on MSG_DONTWAIT after one packet */
2023
        if (flags & MSG_WAITFORONE) {
2024
            flags |= MSG_DONTWAIT;
2025
        }
2026
    }
2027

    
2028
    unlock_user(mmsgp, target_msgvec, sizeof(*mmsgp) * i);
2029

    
2030
    /* Return number of datagrams sent if we sent any at all;
2031
     * otherwise return the error.
2032
     */
2033
    if (i) {
2034
        return i;
2035
    }
2036
    return ret;
2037
}
2038
#endif
2039

    
2040
/* If we don't have a system accept4() then just call accept.
2041
 * The callsites to do_accept4() will ensure that they don't
2042
 * pass a non-zero flags argument in this config.
2043
 */
2044
#ifndef CONFIG_ACCEPT4
2045
static inline int accept4(int sockfd, struct sockaddr *addr,
2046
                          socklen_t *addrlen, int flags)
2047
{
2048
    assert(flags == 0);
2049
    return accept(sockfd, addr, addrlen);
2050
}
2051
#endif
2052

    
2053
/* do_accept4() Must return target values and target errnos. */
2054
static abi_long do_accept4(int fd, abi_ulong target_addr,
2055
                           abi_ulong target_addrlen_addr, int flags)
2056
{
2057
    socklen_t addrlen;
2058
    void *addr;
2059
    abi_long ret;
2060

    
2061
    if (target_addr == 0) {
2062
        return get_errno(accept4(fd, NULL, NULL, flags));
2063
    }
2064

    
2065
    /* linux returns EINVAL if addrlen pointer is invalid */
2066
    if (get_user_u32(addrlen, target_addrlen_addr))
2067
        return -TARGET_EINVAL;
2068

    
2069
    if ((int)addrlen < 0) {
2070
        return -TARGET_EINVAL;
2071
    }
2072

    
2073
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
2074
        return -TARGET_EINVAL;
2075

    
2076
    addr = alloca(addrlen);
2077

    
2078
    ret = get_errno(accept4(fd, addr, &addrlen, flags));
2079
    if (!is_error(ret)) {
2080
        host_to_target_sockaddr(target_addr, addr, addrlen);
2081
        if (put_user_u32(addrlen, target_addrlen_addr))
2082
            ret = -TARGET_EFAULT;
2083
    }
2084
    return ret;
2085
}
2086

    
2087
/* do_getpeername() Must return target values and target errnos. */
2088
static abi_long do_getpeername(int fd, abi_ulong target_addr,
2089
                               abi_ulong target_addrlen_addr)
2090
{
2091
    socklen_t addrlen;
2092
    void *addr;
2093
    abi_long ret;
2094

    
2095
    if (get_user_u32(addrlen, target_addrlen_addr))
2096
        return -TARGET_EFAULT;
2097

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

    
2102
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
2103
        return -TARGET_EFAULT;
2104

    
2105
    addr = alloca(addrlen);
2106

    
2107
    ret = get_errno(getpeername(fd, addr, &addrlen));
2108
    if (!is_error(ret)) {
2109
        host_to_target_sockaddr(target_addr, addr, addrlen);
2110
        if (put_user_u32(addrlen, target_addrlen_addr))
2111
            ret = -TARGET_EFAULT;
2112
    }
2113
    return ret;
2114
}
2115

    
2116
/* do_getsockname() Must return target values and target errnos. */
2117
static abi_long do_getsockname(int fd, abi_ulong target_addr,
2118
                               abi_ulong target_addrlen_addr)
2119
{
2120
    socklen_t addrlen;
2121
    void *addr;
2122
    abi_long ret;
2123

    
2124
    if (get_user_u32(addrlen, target_addrlen_addr))
2125
        return -TARGET_EFAULT;
2126

    
2127
    if ((int)addrlen < 0) {
2128
        return -TARGET_EINVAL;
2129
    }
2130

    
2131
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
2132
        return -TARGET_EFAULT;
2133

    
2134
    addr = alloca(addrlen);
2135

    
2136
    ret = get_errno(getsockname(fd, addr, &addrlen));
2137
    if (!is_error(ret)) {
2138
        host_to_target_sockaddr(target_addr, addr, addrlen);
2139
        if (put_user_u32(addrlen, target_addrlen_addr))
2140
            ret = -TARGET_EFAULT;
2141
    }
2142
    return ret;
2143
}
2144

    
2145
/* do_socketpair() Must return target values and target errnos. */
2146
static abi_long do_socketpair(int domain, int type, int protocol,
2147
                              abi_ulong target_tab_addr)
2148
{
2149
    int tab[2];
2150
    abi_long ret;
2151

    
2152
    target_to_host_sock_type(&type);
2153

    
2154
    ret = get_errno(socketpair(domain, type, protocol, tab));
2155
    if (!is_error(ret)) {
2156
        if (put_user_s32(tab[0], target_tab_addr)
2157
            || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
2158
            ret = -TARGET_EFAULT;
2159
    }
2160
    return ret;
2161
}
2162

    
2163
/* do_sendto() Must return target values and target errnos. */
2164
static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
2165
                          abi_ulong target_addr, socklen_t addrlen)
2166
{
2167
    void *addr;
2168
    void *host_msg;
2169
    abi_long ret;
2170

    
2171
    if ((int)addrlen < 0) {
2172
        return -TARGET_EINVAL;
2173
    }
2174

    
2175
    host_msg = lock_user(VERIFY_READ, msg, len, 1);
2176
    if (!host_msg)
2177
        return -TARGET_EFAULT;
2178
    if (target_addr) {
2179
        addr = alloca(addrlen);
2180
        ret = target_to_host_sockaddr(addr, target_addr, addrlen);
2181
        if (ret) {
2182
            unlock_user(host_msg, msg, 0);
2183
            return ret;
2184
        }
2185
        ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
2186
    } else {
2187
        ret = get_errno(send(fd, host_msg, len, flags));
2188
    }
2189
    unlock_user(host_msg, msg, 0);
2190
    return ret;
2191
}
2192

    
2193
/* do_recvfrom() Must return target values and target errnos. */
2194
static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
2195
                            abi_ulong target_addr,
2196
                            abi_ulong target_addrlen)
2197
{
2198
    socklen_t addrlen;
2199
    void *addr;
2200
    void *host_msg;
2201
    abi_long ret;
2202

    
2203
    host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
2204
    if (!host_msg)
2205
        return -TARGET_EFAULT;
2206
    if (target_addr) {
2207
        if (get_user_u32(addrlen, target_addrlen)) {
2208
            ret = -TARGET_EFAULT;
2209
            goto fail;
2210
        }
2211
        if ((int)addrlen < 0) {
2212
            ret = -TARGET_EINVAL;
2213
            goto fail;
2214
        }
2215
        addr = alloca(addrlen);
2216
        ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
2217
    } else {
2218
        addr = NULL; /* To keep compiler quiet.  */
2219
        ret = get_errno(qemu_recv(fd, host_msg, len, flags));
2220
    }
2221
    if (!is_error(ret)) {
2222
        if (target_addr) {
2223
            host_to_target_sockaddr(target_addr, addr, addrlen);
2224
            if (put_user_u32(addrlen, target_addrlen)) {
2225
                ret = -TARGET_EFAULT;
2226
                goto fail;
2227
            }
2228
        }
2229
        unlock_user(host_msg, msg, len);
2230
    } else {
2231
fail:
2232
        unlock_user(host_msg, msg, 0);
2233
    }
2234
    return ret;
2235
}
2236

    
2237
#ifdef TARGET_NR_socketcall
2238
/* do_socketcall() Must return target values and target errnos. */
2239
static abi_long do_socketcall(int num, abi_ulong vptr)
2240
{
2241
    static const unsigned ac[] = { /* number of arguments per call */
2242
        [SOCKOP_socket] = 3,      /* domain, type, protocol */
2243
        [SOCKOP_bind] = 3,        /* sockfd, addr, addrlen */
2244
        [SOCKOP_connect] = 3,     /* sockfd, addr, addrlen */
2245
        [SOCKOP_listen] = 2,      /* sockfd, backlog */
2246
        [SOCKOP_accept] = 3,      /* sockfd, addr, addrlen */
2247
        [SOCKOP_accept4] = 4,     /* sockfd, addr, addrlen, flags */
2248
        [SOCKOP_getsockname] = 3, /* sockfd, addr, addrlen */
2249
        [SOCKOP_getpeername] = 3, /* sockfd, addr, addrlen */
2250
        [SOCKOP_socketpair] = 4,  /* domain, type, protocol, tab */
2251
        [SOCKOP_send] = 4,        /* sockfd, msg, len, flags */
2252
        [SOCKOP_recv] = 4,        /* sockfd, msg, len, flags */
2253
        [SOCKOP_sendto] = 6,      /* sockfd, msg, len, flags, addr, addrlen */
2254
        [SOCKOP_recvfrom] = 6,    /* sockfd, msg, len, flags, addr, addrlen */
2255
        [SOCKOP_shutdown] = 2,    /* sockfd, how */
2256
        [SOCKOP_sendmsg] = 3,     /* sockfd, msg, flags */
2257
        [SOCKOP_recvmsg] = 3,     /* sockfd, msg, flags */
2258
        [SOCKOP_setsockopt] = 5,  /* sockfd, level, optname, optval, optlen */
2259
        [SOCKOP_getsockopt] = 5,  /* sockfd, level, optname, optval, optlen */
2260
    };
2261
    abi_long a[6]; /* max 6 args */
2262

    
2263
    /* first, collect the arguments in a[] according to ac[] */
2264
    if (num >= 0 && num < ARRAY_SIZE(ac)) {
2265
        unsigned i;
2266
        assert(ARRAY_SIZE(a) >= ac[num]); /* ensure we have space for args */
2267
        for (i = 0; i < ac[num]; ++i) {
2268
            if (get_user_ual(a[i], vptr + i * sizeof(abi_long)) != 0) {
2269
                return -TARGET_EFAULT;
2270
            }
2271
        }
2272
    }
2273

    
2274
    /* now when we have the args, actually handle the call */
2275
    switch (num) {
2276
    case SOCKOP_socket: /* domain, type, protocol */
2277
        return do_socket(a[0], a[1], a[2]);
2278
    case SOCKOP_bind: /* sockfd, addr, addrlen */
2279
        return do_bind(a[0], a[1], a[2]);
2280
    case SOCKOP_connect: /* sockfd, addr, addrlen */
2281
        return do_connect(a[0], a[1], a[2]);
2282
    case SOCKOP_listen: /* sockfd, backlog */
2283
        return get_errno(listen(a[0], a[1]));
2284
    case SOCKOP_accept: /* sockfd, addr, addrlen */
2285
        return do_accept4(a[0], a[1], a[2], 0);
2286
    case SOCKOP_accept4: /* sockfd, addr, addrlen, flags */
2287
        return do_accept4(a[0], a[1], a[2], a[3]);
2288
    case SOCKOP_getsockname: /* sockfd, addr, addrlen */
2289
        return do_getsockname(a[0], a[1], a[2]);
2290
    case SOCKOP_getpeername: /* sockfd, addr, addrlen */
2291
        return do_getpeername(a[0], a[1], a[2]);
2292
    case SOCKOP_socketpair: /* domain, type, protocol, tab */
2293
        return do_socketpair(a[0], a[1], a[2], a[3]);
2294
    case SOCKOP_send: /* sockfd, msg, len, flags */
2295
        return do_sendto(a[0], a[1], a[2], a[3], 0, 0);
2296
    case SOCKOP_recv: /* sockfd, msg, len, flags */
2297
        return do_recvfrom(a[0], a[1], a[2], a[3], 0, 0);
2298
    case SOCKOP_sendto: /* sockfd, msg, len, flags, addr, addrlen */
2299
        return do_sendto(a[0], a[1], a[2], a[3], a[4], a[5]);
2300
    case SOCKOP_recvfrom: /* sockfd, msg, len, flags, addr, addrlen */
2301
        return do_recvfrom(a[0], a[1], a[2], a[3], a[4], a[5]);
2302
    case SOCKOP_shutdown: /* sockfd, how */
2303
        return get_errno(shutdown(a[0], a[1]));
2304
    case SOCKOP_sendmsg: /* sockfd, msg, flags */
2305
        return do_sendrecvmsg(a[0], a[1], a[2], 1);
2306
    case SOCKOP_recvmsg: /* sockfd, msg, flags */
2307
        return do_sendrecvmsg(a[0], a[1], a[2], 0);
2308
    case SOCKOP_setsockopt: /* sockfd, level, optname, optval, optlen */
2309
        return do_setsockopt(a[0], a[1], a[2], a[3], a[4]);
2310
    case SOCKOP_getsockopt: /* sockfd, level, optname, optval, optlen */
2311
        return do_getsockopt(a[0], a[1], a[2], a[3], a[4]);
2312
    default:
2313
        gemu_log("Unsupported socketcall: %d\n", num);
2314
        return -TARGET_ENOSYS;
2315
    }
2316
}
2317
#endif
2318

    
2319
#define N_SHM_REGIONS        32
2320

    
2321
static struct shm_region {
2322
    abi_ulong        start;
2323
    abi_ulong        size;
2324
} shm_regions[N_SHM_REGIONS];
2325

    
2326
struct target_semid_ds
2327
{
2328
  struct target_ipc_perm sem_perm;
2329
  abi_ulong sem_otime;
2330
  abi_ulong __unused1;
2331
  abi_ulong sem_ctime;
2332
  abi_ulong __unused2;
2333
  abi_ulong sem_nsems;
2334
  abi_ulong __unused3;
2335
  abi_ulong __unused4;
2336
};
2337

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

    
2344
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2345
        return -TARGET_EFAULT;
2346
    target_ip = &(target_sd->sem_perm);
2347
    host_ip->__key = tswap32(target_ip->__key);
2348
    host_ip->uid = tswap32(target_ip->uid);
2349
    host_ip->gid = tswap32(target_ip->gid);
2350
    host_ip->cuid = tswap32(target_ip->cuid);
2351
    host_ip->cgid = tswap32(target_ip->cgid);
2352
#if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_PPC)
2353
    host_ip->mode = tswap32(target_ip->mode);
2354
#else
2355
    host_ip->mode = tswap16(target_ip->mode);
2356
#endif
2357
#if defined(TARGET_PPC)
2358
    host_ip->__seq = tswap32(target_ip->__seq);
2359
#else
2360
    host_ip->__seq = tswap16(target_ip->__seq);
2361
#endif
2362
    unlock_user_struct(target_sd, target_addr, 0);
2363
    return 0;
2364
}
2365

    
2366
static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
2367
                                               struct ipc_perm *host_ip)
2368
{
2369
    struct target_ipc_perm *target_ip;
2370
    struct target_semid_ds *target_sd;
2371

    
2372
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2373
        return -TARGET_EFAULT;
2374
    target_ip = &(target_sd->sem_perm);
2375
    target_ip->__key = tswap32(host_ip->__key);
2376
    target_ip->uid = tswap32(host_ip->uid);
2377
    target_ip->gid = tswap32(host_ip->gid);
2378
    target_ip->cuid = tswap32(host_ip->cuid);
2379
    target_ip->cgid = tswap32(host_ip->cgid);
2380
#if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_PPC)
2381
    target_ip->mode = tswap32(host_ip->mode);
2382
#else
2383
    target_ip->mode = tswap16(host_ip->mode);
2384
#endif
2385
#if defined(TARGET_PPC)
2386
    target_ip->__seq = tswap32(host_ip->__seq);
2387
#else
2388
    target_ip->__seq = tswap16(host_ip->__seq);
2389
#endif
2390
    unlock_user_struct(target_sd, target_addr, 1);
2391
    return 0;
2392
}
2393

    
2394
static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
2395
                                               abi_ulong target_addr)
2396
{
2397
    struct target_semid_ds *target_sd;
2398

    
2399
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2400
        return -TARGET_EFAULT;
2401
    if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr))
2402
        return -TARGET_EFAULT;
2403
    host_sd->sem_nsems = tswapal(target_sd->sem_nsems);
2404
    host_sd->sem_otime = tswapal(target_sd->sem_otime);
2405
    host_sd->sem_ctime = tswapal(target_sd->sem_ctime);
2406
    unlock_user_struct(target_sd, target_addr, 0);
2407
    return 0;
2408
}
2409

    
2410
static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
2411
                                               struct semid_ds *host_sd)
2412
{
2413
    struct target_semid_ds *target_sd;
2414

    
2415
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2416
        return -TARGET_EFAULT;
2417
    if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
2418
        return -TARGET_EFAULT;
2419
    target_sd->sem_nsems = tswapal(host_sd->sem_nsems);
2420
    target_sd->sem_otime = tswapal(host_sd->sem_otime);
2421
    target_sd->sem_ctime = tswapal(host_sd->sem_ctime);
2422
    unlock_user_struct(target_sd, target_addr, 1);
2423
    return 0;
2424
}
2425

    
2426
struct target_seminfo {
2427
    int semmap;
2428
    int semmni;
2429
    int semmns;
2430
    int semmnu;
2431
    int semmsl;
2432
    int semopm;
2433
    int semume;
2434
    int semusz;
2435
    int semvmx;
2436
    int semaem;
2437
};
2438

    
2439
static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
2440
                                              struct seminfo *host_seminfo)
2441
{
2442
    struct target_seminfo *target_seminfo;
2443
    if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
2444
        return -TARGET_EFAULT;
2445
    __put_user(host_seminfo->semmap, &target_seminfo->semmap);
2446
    __put_user(host_seminfo->semmni, &target_seminfo->semmni);
2447
    __put_user(host_seminfo->semmns, &target_seminfo->semmns);
2448
    __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
2449
    __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
2450
    __put_user(host_seminfo->semopm, &target_seminfo->semopm);
2451
    __put_user(host_seminfo->semume, &target_seminfo->semume);
2452
    __put_user(host_seminfo->semusz, &target_seminfo->semusz);
2453
    __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
2454
    __put_user(host_seminfo->semaem, &target_seminfo->semaem);
2455
    unlock_user_struct(target_seminfo, target_addr, 1);
2456
    return 0;
2457
}
2458

    
2459
union semun {
2460
        int val;
2461
        struct semid_ds *buf;
2462
        unsigned short *array;
2463
        struct seminfo *__buf;
2464
};
2465

    
2466
union target_semun {
2467
        int val;
2468
        abi_ulong buf;
2469
        abi_ulong array;
2470
        abi_ulong __buf;
2471
};
2472

    
2473
static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
2474
                                               abi_ulong target_addr)
2475
{
2476
    int nsems;
2477
    unsigned short *array;
2478
    union semun semun;
2479
    struct semid_ds semid_ds;
2480
    int i, ret;
2481

    
2482
    semun.buf = &semid_ds;
2483

    
2484
    ret = semctl(semid, 0, IPC_STAT, semun);
2485
    if (ret == -1)
2486
        return get_errno(ret);
2487

    
2488
    nsems = semid_ds.sem_nsems;
2489

    
2490
    *host_array = malloc(nsems*sizeof(unsigned short));
2491
    if (!*host_array) {
2492
        return -TARGET_ENOMEM;
2493
    }
2494
    array = lock_user(VERIFY_READ, target_addr,
2495
                      nsems*sizeof(unsigned short), 1);
2496
    if (!array) {
2497
        free(*host_array);
2498
        return -TARGET_EFAULT;
2499
    }
2500

    
2501
    for(i=0; i<nsems; i++) {
2502
        __get_user((*host_array)[i], &array[i]);
2503
    }
2504
    unlock_user(array, target_addr, 0);
2505

    
2506
    return 0;
2507
}
2508

    
2509
static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
2510
                                               unsigned short **host_array)
2511
{
2512
    int nsems;
2513
    unsigned short *array;
2514
    union semun semun;
2515
    struct semid_ds semid_ds;
2516
    int i, ret;
2517

    
2518
    semun.buf = &semid_ds;
2519

    
2520
    ret = semctl(semid, 0, IPC_STAT, semun);
2521
    if (ret == -1)
2522
        return get_errno(ret);
2523

    
2524
    nsems = semid_ds.sem_nsems;
2525

    
2526
    array = lock_user(VERIFY_WRITE, target_addr,
2527
                      nsems*sizeof(unsigned short), 0);
2528
    if (!array)
2529
        return -TARGET_EFAULT;
2530

    
2531
    for(i=0; i<nsems; i++) {
2532
        __put_user((*host_array)[i], &array[i]);
2533
    }
2534
    free(*host_array);
2535
    unlock_user(array, target_addr, 1);
2536

    
2537
    return 0;
2538
}
2539

    
2540
static inline abi_long do_semctl(int semid, int semnum, int cmd,
2541
                                 union target_semun target_su)
2542
{
2543
    union semun arg;
2544
    struct semid_ds dsarg;
2545
    unsigned short *array = NULL;
2546
    struct seminfo seminfo;
2547
    abi_long ret = -TARGET_EINVAL;
2548
    abi_long err;
2549
    cmd &= 0xff;
2550

    
2551
    switch( cmd ) {
2552
        case GETVAL:
2553
        case SETVAL:
2554
            arg.val = tswap32(target_su.val);
2555
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2556
            target_su.val = tswap32(arg.val);
2557
            break;
2558
        case GETALL:
2559
        case SETALL:
2560
            err = target_to_host_semarray(semid, &array, target_su.array);
2561
            if (err)
2562
                return err;
2563
            arg.array = array;
2564
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2565
            err = host_to_target_semarray(semid, target_su.array, &array);
2566
            if (err)
2567
                return err;
2568
            break;
2569
        case IPC_STAT:
2570
        case IPC_SET:
2571
        case SEM_STAT:
2572
            err = target_to_host_semid_ds(&dsarg, target_su.buf);
2573
            if (err)
2574
                return err;
2575
            arg.buf = &dsarg;
2576
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2577
            err = host_to_target_semid_ds(target_su.buf, &dsarg);
2578
            if (err)
2579
                return err;
2580
            break;
2581
        case IPC_INFO:
2582
        case SEM_INFO:
2583
            arg.__buf = &seminfo;
2584
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2585
            err = host_to_target_seminfo(target_su.__buf, &seminfo);
2586
            if (err)
2587
                return err;
2588
            break;
2589
        case IPC_RMID:
2590
        case GETPID:
2591
        case GETNCNT:
2592
        case GETZCNT:
2593
            ret = get_errno(semctl(semid, semnum, cmd, NULL));
2594
            break;
2595
    }
2596

    
2597
    return ret;
2598
}
2599

    
2600
struct target_sembuf {
2601
    unsigned short sem_num;
2602
    short sem_op;
2603
    short sem_flg;
2604
};
2605

    
2606
static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
2607
                                             abi_ulong target_addr,
2608
                                             unsigned nsops)
2609
{
2610
    struct target_sembuf *target_sembuf;
2611
    int i;
2612

    
2613
    target_sembuf = lock_user(VERIFY_READ, target_addr,
2614
                              nsops*sizeof(struct target_sembuf), 1);
2615
    if (!target_sembuf)
2616
        return -TARGET_EFAULT;
2617

    
2618
    for(i=0; i<nsops; i++) {
2619
        __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
2620
        __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
2621
        __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
2622
    }
2623

    
2624
    unlock_user(target_sembuf, target_addr, 0);
2625

    
2626
    return 0;
2627
}
2628

    
2629
static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
2630
{
2631
    struct sembuf sops[nsops];
2632

    
2633
    if (target_to_host_sembuf(sops, ptr, nsops))
2634
        return -TARGET_EFAULT;
2635

    
2636
    return get_errno(semop(semid, sops, nsops));
2637
}
2638

    
2639
struct target_msqid_ds
2640
{
2641
    struct target_ipc_perm msg_perm;
2642
    abi_ulong msg_stime;
2643
#if TARGET_ABI_BITS == 32
2644
    abi_ulong __unused1;
2645
#endif
2646
    abi_ulong msg_rtime;
2647
#if TARGET_ABI_BITS == 32
2648
    abi_ulong __unused2;
2649
#endif
2650
    abi_ulong msg_ctime;
2651
#if TARGET_ABI_BITS == 32
2652
    abi_ulong __unused3;
2653
#endif
2654
    abi_ulong __msg_cbytes;
2655
    abi_ulong msg_qnum;
2656
    abi_ulong msg_qbytes;
2657
    abi_ulong msg_lspid;
2658
    abi_ulong msg_lrpid;
2659
    abi_ulong __unused4;
2660
    abi_ulong __unused5;
2661
};
2662

    
2663
static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
2664
                                               abi_ulong target_addr)
2665
{
2666
    struct target_msqid_ds *target_md;
2667

    
2668
    if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
2669
        return -TARGET_EFAULT;
2670
    if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
2671
        return -TARGET_EFAULT;
2672
    host_md->msg_stime = tswapal(target_md->msg_stime);
2673
    host_md->msg_rtime = tswapal(target_md->msg_rtime);
2674
    host_md->msg_ctime = tswapal(target_md->msg_ctime);
2675
    host_md->__msg_cbytes = tswapal(target_md->__msg_cbytes);
2676
    host_md->msg_qnum = tswapal(target_md->msg_qnum);
2677
    host_md->msg_qbytes = tswapal(target_md->msg_qbytes);
2678
    host_md->msg_lspid = tswapal(target_md->msg_lspid);
2679
    host_md->msg_lrpid = tswapal(target_md->msg_lrpid);
2680
    unlock_user_struct(target_md, target_addr, 0);
2681
    return 0;
2682
}
2683

    
2684
static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
2685
                                               struct msqid_ds *host_md)
2686
{
2687
    struct target_msqid_ds *target_md;
2688

    
2689
    if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
2690
        return -TARGET_EFAULT;
2691
    if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
2692
        return -TARGET_EFAULT;
2693
    target_md->msg_stime = tswapal(host_md->msg_stime);
2694
    target_md->msg_rtime = tswapal(host_md->msg_rtime);
2695
    target_md->msg_ctime = tswapal(host_md->msg_ctime);
2696
    target_md->__msg_cbytes = tswapal(host_md->__msg_cbytes);
2697
    target_md->msg_qnum = tswapal(host_md->msg_qnum);
2698
    target_md->msg_qbytes = tswapal(host_md->msg_qbytes);
2699
    target_md->msg_lspid = tswapal(host_md->msg_lspid);
2700
    target_md->msg_lrpid = tswapal(host_md->msg_lrpid);
2701
    unlock_user_struct(target_md, target_addr, 1);
2702
    return 0;
2703
}
2704

    
2705
struct target_msginfo {
2706
    int msgpool;
2707
    int msgmap;
2708
    int msgmax;
2709
    int msgmnb;
2710
    int msgmni;
2711
    int msgssz;
2712
    int msgtql;
2713
    unsigned short int msgseg;
2714
};
2715

    
2716
static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
2717
                                              struct msginfo *host_msginfo)
2718
{
2719
    struct target_msginfo *target_msginfo;
2720
    if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
2721
        return -TARGET_EFAULT;
2722
    __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
2723
    __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
2724
    __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
2725
    __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
2726
    __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
2727
    __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
2728
    __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
2729
    __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
2730
    unlock_user_struct(target_msginfo, target_addr, 1);
2731
    return 0;
2732
}
2733

    
2734
static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
2735
{
2736
    struct msqid_ds dsarg;
2737
    struct msginfo msginfo;
2738
    abi_long ret = -TARGET_EINVAL;
2739

    
2740
    cmd &= 0xff;
2741

    
2742
    switch (cmd) {
2743
    case IPC_STAT:
2744
    case IPC_SET:
2745
    case MSG_STAT:
2746
        if (target_to_host_msqid_ds(&dsarg,ptr))
2747
            return -TARGET_EFAULT;
2748
        ret = get_errno(msgctl(msgid, cmd, &dsarg));
2749
        if (host_to_target_msqid_ds(ptr,&dsarg))
2750
            return -TARGET_EFAULT;
2751
        break;
2752
    case IPC_RMID:
2753
        ret = get_errno(msgctl(msgid, cmd, NULL));
2754
        break;
2755
    case IPC_INFO:
2756
    case MSG_INFO:
2757
        ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
2758
        if (host_to_target_msginfo(ptr, &msginfo))
2759
            return -TARGET_EFAULT;
2760
        break;
2761
    }
2762

    
2763
    return ret;
2764
}
2765

    
2766
struct target_msgbuf {
2767
    abi_long mtype;
2768
    char        mtext[1];
2769
};
2770

    
2771
static inline abi_long do_msgsnd(int msqid, abi_long msgp,
2772
                                 unsigned int msgsz, int msgflg)
2773
{
2774
    struct target_msgbuf *target_mb;
2775
    struct msgbuf *host_mb;
2776
    abi_long ret = 0;
2777

    
2778
    if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
2779
        return -TARGET_EFAULT;
2780
    host_mb = malloc(msgsz+sizeof(long));
2781
    host_mb->mtype = (abi_long) tswapal(target_mb->mtype);
2782
    memcpy(host_mb->mtext, target_mb->mtext, msgsz);
2783
    ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
2784
    free(host_mb);
2785
    unlock_user_struct(target_mb, msgp, 0);
2786

    
2787
    return ret;
2788
}
2789

    
2790
static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2791
                                 unsigned int msgsz, abi_long msgtyp,
2792
                                 int msgflg)
2793
{
2794
    struct target_msgbuf *target_mb;
2795
    char *target_mtext;
2796
    struct msgbuf *host_mb;
2797
    abi_long ret = 0;
2798

    
2799
    if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2800
        return -TARGET_EFAULT;
2801

    
2802
    host_mb = g_malloc(msgsz+sizeof(long));
2803
    ret = get_errno(msgrcv(msqid, host_mb, msgsz, msgtyp, msgflg));
2804

    
2805
    if (ret > 0) {
2806
        abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2807
        target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2808
        if (!target_mtext) {
2809
            ret = -TARGET_EFAULT;
2810
            goto end;
2811
        }
2812
        memcpy(target_mb->mtext, host_mb->mtext, ret);
2813
        unlock_user(target_mtext, target_mtext_addr, ret);
2814
    }
2815

    
2816
    target_mb->mtype = tswapal(host_mb->mtype);
2817

    
2818
end:
2819
    if (target_mb)
2820
        unlock_user_struct(target_mb, msgp, 1);
2821
    g_free(host_mb);
2822
    return ret;
2823
}
2824

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

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

    
2845
static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
2846
                                               struct shmid_ds *host_sd)
2847
{
2848
    struct target_shmid_ds *target_sd;
2849

    
2850
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2851
        return -TARGET_EFAULT;
2852
    if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm)))
2853
        return -TARGET_EFAULT;
2854
    __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2855
    __put_user(host_sd->shm_atime, &target_sd->shm_atime);
2856
    __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2857
    __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2858
    __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2859
    __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2860
    __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2861
    unlock_user_struct(target_sd, target_addr, 1);
2862
    return 0;
2863
}
2864

    
2865
struct  target_shminfo {
2866
    abi_ulong shmmax;
2867
    abi_ulong shmmin;
2868
    abi_ulong shmmni;
2869
    abi_ulong shmseg;
2870
    abi_ulong shmall;
2871
};
2872

    
2873
static inline abi_long host_to_target_shminfo(abi_ulong target_addr,
2874
                                              struct shminfo *host_shminfo)
2875
{
2876
    struct target_shminfo *target_shminfo;
2877
    if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0))
2878
        return -TARGET_EFAULT;
2879
    __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
2880
    __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
2881
    __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
2882
    __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
2883
    __put_user(host_shminfo->shmall, &target_shminfo->shmall);
2884
    unlock_user_struct(target_shminfo, target_addr, 1);
2885
    return 0;
2886
}
2887

    
2888
struct target_shm_info {
2889
    int used_ids;
2890
    abi_ulong shm_tot;
2891
    abi_ulong shm_rss;
2892
    abi_ulong shm_swp;
2893
    abi_ulong swap_attempts;
2894
    abi_ulong swap_successes;
2895
};
2896

    
2897
static inline abi_long host_to_target_shm_info(abi_ulong target_addr,
2898
                                               struct shm_info *host_shm_info)
2899
{
2900
    struct target_shm_info *target_shm_info;
2901
    if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0))
2902
        return -TARGET_EFAULT;
2903
    __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
2904
    __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
2905
    __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
2906
    __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
2907
    __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts);
2908
    __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes);
2909
    unlock_user_struct(target_shm_info, target_addr, 1);
2910
    return 0;
2911
}
2912

    
2913
static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
2914
{
2915
    struct shmid_ds dsarg;
2916
    struct shminfo shminfo;
2917
    struct shm_info shm_info;
2918
    abi_long ret = -TARGET_EINVAL;
2919

    
2920
    cmd &= 0xff;
2921

    
2922
    switch(cmd) {
2923
    case IPC_STAT:
2924
    case IPC_SET:
2925
    case SHM_STAT:
2926
        if (target_to_host_shmid_ds(&dsarg, buf))
2927
            return -TARGET_EFAULT;
2928
        ret = get_errno(shmctl(shmid, cmd, &dsarg));
2929
        if (host_to_target_shmid_ds(buf, &dsarg))
2930
            return -TARGET_EFAULT;
2931
        break;
2932
    case IPC_INFO:
2933
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
2934
        if (host_to_target_shminfo(buf, &shminfo))
2935
            return -TARGET_EFAULT;
2936
        break;
2937
    case SHM_INFO:
2938
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
2939
        if (host_to_target_shm_info(buf, &shm_info))
2940
            return -TARGET_EFAULT;
2941
        break;
2942
    case IPC_RMID:
2943
    case SHM_LOCK:
2944
    case SHM_UNLOCK:
2945
        ret = get_errno(shmctl(shmid, cmd, NULL));
2946
        break;
2947
    }
2948

    
2949
    return ret;
2950
}
2951

    
2952
static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
2953
{
2954
    abi_long raddr;
2955
    void *host_raddr;
2956
    struct shmid_ds shm_info;
2957
    int i,ret;
2958

    
2959
    /* find out the length of the shared memory segment */
2960
    ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
2961
    if (is_error(ret)) {
2962
        /* can't get length, bail out */
2963
        return ret;
2964
    }
2965

    
2966
    mmap_lock();
2967

    
2968
    if (shmaddr)
2969
        host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
2970
    else {
2971
        abi_ulong mmap_start;
2972

    
2973
        mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
2974

    
2975
        if (mmap_start == -1) {
2976
            errno = ENOMEM;
2977
            host_raddr = (void *)-1;
2978
        } else
2979
            host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);
2980
    }
2981

    
2982
    if (host_raddr == (void *)-1) {
2983
        mmap_unlock();
2984
        return get_errno((long)host_raddr);
2985
    }
2986
    raddr=h2g((unsigned long)host_raddr);
2987

    
2988
    page_set_flags(raddr, raddr + shm_info.shm_segsz,
2989
                   PAGE_VALID | PAGE_READ |
2990
                   ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
2991

    
2992
    for (i = 0; i < N_SHM_REGIONS; i++) {
2993
        if (shm_regions[i].start == 0) {
2994
            shm_regions[i].start = raddr;
2995
            shm_regions[i].size = shm_info.shm_segsz;
2996
            break;
2997
        }
2998
    }
2999

    
3000
    mmap_unlock();
3001
    return raddr;
3002

    
3003
}
3004

    
3005
static inline abi_long do_shmdt(abi_ulong shmaddr)
3006
{
3007
    int i;
3008

    
3009
    for (i = 0; i < N_SHM_REGIONS; ++i) {
3010
        if (shm_regions[i].start == shmaddr) {
3011
            shm_regions[i].start = 0;
3012
            page_set_flags(shmaddr, shmaddr + shm_regions[i].size, 0);
3013
            break;
3014
        }
3015
    }
3016

    
3017
    return get_errno(shmdt(g2h(shmaddr)));
3018
}
3019

    
3020
#ifdef TARGET_NR_ipc
3021
/* ??? This only works with linear mappings.  */
3022
/* do_ipc() must return target values and target errnos. */
3023
static abi_long do_ipc(unsigned int call, int first,
3024
                       int second, int third,
3025
                       abi_long ptr, abi_long fifth)
3026
{
3027
    int version;
3028
    abi_long ret = 0;
3029

    
3030
    version = call >> 16;
3031
    call &= 0xffff;
3032

    
3033
    switch (call) {
3034
    case IPCOP_semop:
3035
        ret = do_semop(first, ptr, second);
3036
        break;
3037

    
3038
    case IPCOP_semget:
3039
        ret = get_errno(semget(first, second, third));
3040
        break;
3041

    
3042
    case IPCOP_semctl:
3043
        ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr);
3044
        break;
3045

    
3046
    case IPCOP_msgget:
3047
        ret = get_errno(msgget(first, second));
3048
        break;
3049

    
3050
    case IPCOP_msgsnd:
3051
        ret = do_msgsnd(first, ptr, second, third);
3052
        break;
3053

    
3054
    case IPCOP_msgctl:
3055
        ret = do_msgctl(first, second, ptr);
3056
        break;
3057

    
3058
    case IPCOP_msgrcv:
3059
        switch (version) {
3060
        case 0:
3061
            {
3062
                struct target_ipc_kludge {
3063
                    abi_long msgp;
3064
                    abi_long msgtyp;
3065
                } *tmp;
3066

    
3067
                if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
3068
                    ret = -TARGET_EFAULT;
3069
                    break;
3070
                }
3071

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

    
3074
                unlock_user_struct(tmp, ptr, 0);
3075
                break;
3076
            }
3077
        default:
3078
            ret = do_msgrcv(first, ptr, second, fifth, third);
3079
        }
3080
        break;
3081

    
3082
    case IPCOP_shmat:
3083
        switch (version) {
3084
        default:
3085
        {
3086
            abi_ulong raddr;
3087
            raddr = do_shmat(first, ptr, second);
3088
            if (is_error(raddr))
3089
                return get_errno(raddr);
3090
            if (put_user_ual(raddr, third))
3091
                return -TARGET_EFAULT;
3092
            break;
3093
        }
3094
        case 1:
3095
            ret = -TARGET_EINVAL;
3096
            break;
3097
        }
3098
        break;
3099
    case IPCOP_shmdt:
3100
        ret = do_shmdt(ptr);
3101
        break;
3102

    
3103
    case IPCOP_shmget:
3104
        /* IPC_* flag values are the same on all linux platforms */
3105
        ret = get_errno(shmget(first, second, third));
3106
        break;
3107

    
3108
        /* IPC_* and SHM_* command values are the same on all linux platforms */
3109
    case IPCOP_shmctl:
3110
        ret = do_shmctl(first, second, ptr);
3111
        break;
3112
    default:
3113
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
3114
        ret = -TARGET_ENOSYS;
3115
        break;
3116
    }
3117
    return ret;
3118
}
3119
#endif
3120

    
3121
/* kernel structure types definitions */
3122

    
3123
#define STRUCT(name, ...) STRUCT_ ## name,
3124
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
3125
enum {
3126
#include "syscall_types.h"
3127
};
3128
#undef STRUCT
3129
#undef STRUCT_SPECIAL
3130

    
3131
#define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = {  __VA_ARGS__, TYPE_NULL };
3132
#define STRUCT_SPECIAL(name)
3133
#include "syscall_types.h"
3134
#undef STRUCT
3135
#undef STRUCT_SPECIAL
3136

    
3137
typedef struct IOCTLEntry IOCTLEntry;
3138

    
3139
typedef abi_long do_ioctl_fn(const IOCTLEntry *ie, uint8_t *buf_temp,
3140
                             int fd, abi_long cmd, abi_long arg);
3141

    
3142
struct IOCTLEntry {
3143
    unsigned int target_cmd;
3144
    unsigned int host_cmd;
3145
    const char *name;
3146
    int access;
3147
    do_ioctl_fn *do_ioctl;
3148
    const argtype arg_type[5];
3149
};
3150

    
3151
#define IOC_R 0x0001
3152
#define IOC_W 0x0002
3153
#define IOC_RW (IOC_R | IOC_W)
3154

    
3155
#define MAX_STRUCT_SIZE 4096
3156

    
3157
#ifdef CONFIG_FIEMAP
3158
/* So fiemap access checks don't overflow on 32 bit systems.
3159
 * This is very slightly smaller than the limit imposed by
3160
 * the underlying kernel.
3161
 */
3162
#define FIEMAP_MAX_EXTENTS ((UINT_MAX - sizeof(struct fiemap))  \
3163
                            / sizeof(struct fiemap_extent))
3164

    
3165
static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp,
3166
                                       int fd, abi_long cmd, abi_long arg)
3167
{
3168
    /* The parameter for this ioctl is a struct fiemap followed
3169
     * by an array of struct fiemap_extent whose size is set
3170
     * in fiemap->fm_extent_count. The array is filled in by the
3171
     * ioctl.
3172
     */
3173
    int target_size_in, target_size_out;
3174
    struct fiemap *fm;
3175
    const argtype *arg_type = ie->arg_type;
3176
    const argtype extent_arg_type[] = { MK_STRUCT(STRUCT_fiemap_extent) };
3177
    void *argptr, *p;
3178
    abi_long ret;
3179
    int i, extent_size = thunk_type_size(extent_arg_type, 0);
3180
    uint32_t outbufsz;
3181
    int free_fm = 0;
3182

    
3183
    assert(arg_type[0] == TYPE_PTR);
3184
    assert(ie->access == IOC_RW);
3185
    arg_type++;
3186
    target_size_in = thunk_type_size(arg_type, 0);
3187
    argptr = lock_user(VERIFY_READ, arg, target_size_in, 1);
3188
    if (!argptr) {
3189
        return -TARGET_EFAULT;
3190
    }
3191
    thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3192
    unlock_user(argptr, arg, 0);
3193
    fm = (struct fiemap *)buf_temp;
3194
    if (fm->fm_extent_count > FIEMAP_MAX_EXTENTS) {
3195
        return -TARGET_EINVAL;
3196
    }
3197

    
3198
    outbufsz = sizeof (*fm) +
3199
        (sizeof(struct fiemap_extent) * fm->fm_extent_count);
3200

    
3201
    if (outbufsz > MAX_STRUCT_SIZE) {
3202
        /* We can't fit all the extents into the fixed size buffer.
3203
         * Allocate one that is large enough and use it instead.
3204
         */
3205
        fm = malloc(outbufsz);
3206
        if (!fm) {
3207
            return -TARGET_ENOMEM;
3208
        }
3209
        memcpy(fm, buf_temp, sizeof(struct fiemap));
3210
        free_fm = 1;
3211
    }
3212
    ret = get_errno(ioctl(fd, ie->host_cmd, fm));
3213
    if (!is_error(ret)) {
3214
        target_size_out = target_size_in;
3215
        /* An extent_count of 0 means we were only counting the extents
3216
         * so there are no structs to copy
3217
         */
3218
        if (fm->fm_extent_count != 0) {
3219
            target_size_out += fm->fm_mapped_extents * extent_size;
3220
        }
3221
        argptr = lock_user(VERIFY_WRITE, arg, target_size_out, 0);
3222
        if (!argptr) {
3223
            ret = -TARGET_EFAULT;
3224
        } else {
3225
            /* Convert the struct fiemap */
3226
            thunk_convert(argptr, fm, arg_type, THUNK_TARGET);
3227
            if (fm->fm_extent_count != 0) {
3228
                p = argptr + target_size_in;
3229
                /* ...and then all the struct fiemap_extents */
3230
                for (i = 0; i < fm->fm_mapped_extents; i++) {
3231
                    thunk_convert(p, &fm->fm_extents[i], extent_arg_type,
3232
                                  THUNK_TARGET);
3233
                    p += extent_size;
3234
                }
3235
            }
3236
            unlock_user(argptr, arg, target_size_out);
3237
        }
3238
    }
3239
    if (free_fm) {
3240
        free(fm);
3241
    }
3242
    return ret;
3243
}
3244
#endif
3245

    
3246
static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp,
3247
                                int fd, abi_long cmd, abi_long arg)
3248
{
3249
    const argtype *arg_type = ie->arg_type;
3250
    int target_size;
3251
    void *argptr;
3252
    int ret;
3253
    struct ifconf *host_ifconf;
3254
    uint32_t outbufsz;
3255
    const argtype ifreq_arg_type[] = { MK_STRUCT(STRUCT_sockaddr_ifreq) };
3256
    int target_ifreq_size;
3257
    int nb_ifreq;
3258
    int free_buf = 0;
3259
    int i;
3260
    int target_ifc_len;
3261
    abi_long target_ifc_buf;
3262
    int host_ifc_len;
3263
    char *host_ifc_buf;
3264

    
3265
    assert(arg_type[0] == TYPE_PTR);
3266
    assert(ie->access == IOC_RW);
3267

    
3268
    arg_type++;
3269
    target_size = thunk_type_size(arg_type, 0);
3270

    
3271
    argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3272
    if (!argptr)
3273
        return -TARGET_EFAULT;
3274
    thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3275
    unlock_user(argptr, arg, 0);
3276

    
3277
    host_ifconf = (struct ifconf *)(unsigned long)buf_temp;
3278
    target_ifc_len = host_ifconf->ifc_len;
3279
    target_ifc_buf = (abi_long)(unsigned long)host_ifconf->ifc_buf;
3280

    
3281
    target_ifreq_size = thunk_type_size(ifreq_arg_type, 0);
3282
    nb_ifreq = target_ifc_len / target_ifreq_size;
3283
    host_ifc_len = nb_ifreq * sizeof(struct ifreq);
3284

    
3285
    outbufsz = sizeof(*host_ifconf) + host_ifc_len;
3286
    if (outbufsz > MAX_STRUCT_SIZE) {
3287
        /* We can't fit all the extents into the fixed size buffer.
3288
         * Allocate one that is large enough and use it instead.
3289
         */
3290
        host_ifconf = malloc(outbufsz);
3291
        if (!host_ifconf) {
3292
            return -TARGET_ENOMEM;
3293
        }
3294
        memcpy(host_ifconf, buf_temp, sizeof(*host_ifconf));
3295
        free_buf = 1;
3296
    }
3297
    host_ifc_buf = (char*)host_ifconf + sizeof(*host_ifconf);
3298

    
3299
    host_ifconf->ifc_len = host_ifc_len;
3300
    host_ifconf->ifc_buf = host_ifc_buf;
3301

    
3302
    ret = get_errno(ioctl(fd, ie->host_cmd, host_ifconf));
3303
    if (!is_error(ret)) {
3304
        /* convert host ifc_len to target ifc_len */
3305

    
3306
        nb_ifreq = host_ifconf->ifc_len / sizeof(struct ifreq);
3307
        target_ifc_len = nb_ifreq * target_ifreq_size;
3308
        host_ifconf->ifc_len = target_ifc_len;
3309

    
3310
        /* restore target ifc_buf */
3311

    
3312
        host_ifconf->ifc_buf = (char *)(unsigned long)target_ifc_buf;
3313

    
3314
        /* copy struct ifconf to target user */
3315

    
3316
        argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3317
        if (!argptr)
3318
            return -TARGET_EFAULT;
3319
        thunk_convert(argptr, host_ifconf, arg_type, THUNK_TARGET);
3320
        unlock_user(argptr, arg, target_size);
3321

    
3322
        /* copy ifreq[] to target user */
3323

    
3324
        argptr = lock_user(VERIFY_WRITE, target_ifc_buf, target_ifc_len, 0);
3325
        for (i = 0; i < nb_ifreq ; i++) {
3326
            thunk_convert(argptr + i * target_ifreq_size,
3327
                          host_ifc_buf + i * sizeof(struct ifreq),
3328
                          ifreq_arg_type, THUNK_TARGET);
3329
        }
3330
        unlock_user(argptr, target_ifc_buf, target_ifc_len);
3331
    }
3332

    
3333
    if (free_buf) {
3334
        free(host_ifconf);
3335
    }
3336

    
3337
    return ret;
3338
}
3339

    
3340
static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
3341
                            abi_long cmd, abi_long arg)
3342
{
3343
    void *argptr;
3344
    struct dm_ioctl *host_dm;
3345
    abi_long guest_data;
3346
    uint32_t guest_data_size;
3347
    int target_size;
3348
    const argtype *arg_type = ie->arg_type;
3349
    abi_long ret;
3350
    void *big_buf = NULL;
3351
    char *host_data;
3352

    
3353
    arg_type++;
3354
    target_size = thunk_type_size(arg_type, 0);
3355
    argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3356
    if (!argptr) {
3357
        ret = -TARGET_EFAULT;
3358
        goto out;
3359
    }
3360
    thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3361
    unlock_user(argptr, arg, 0);
3362

    
3363
    /* buf_temp is too small, so fetch things into a bigger buffer */
3364
    big_buf = g_malloc0(((struct dm_ioctl*)buf_temp)->data_size * 2);
3365
    memcpy(big_buf, buf_temp, target_size);
3366
    buf_temp = big_buf;
3367
    host_dm = big_buf;
3368

    
3369
    guest_data = arg + host_dm->data_start;
3370
    if ((guest_data - arg) < 0) {
3371
        ret = -EINVAL;
3372
        goto out;
3373
    }
3374
    guest_data_size = host_dm->data_size - host_dm->data_start;
3375
    host_data = (char*)host_dm + host_dm->data_start;
3376

    
3377
    argptr = lock_user(VERIFY_READ, guest_data, guest_data_size, 1);
3378
    switch (ie->host_cmd) {
3379
    case DM_REMOVE_ALL:
3380
    case DM_LIST_DEVICES:
3381
    case DM_DEV_CREATE:
3382
    case DM_DEV_REMOVE:
3383
    case DM_DEV_SUSPEND:
3384
    case DM_DEV_STATUS:
3385
    case DM_DEV_WAIT:
3386
    case DM_TABLE_STATUS:
3387
    case DM_TABLE_CLEAR:
3388
    case DM_TABLE_DEPS:
3389
    case DM_LIST_VERSIONS:
3390
        /* no input data */
3391
        break;
3392
    case DM_DEV_RENAME:
3393
    case DM_DEV_SET_GEOMETRY:
3394
        /* data contains only strings */
3395
        memcpy(host_data, argptr, guest_data_size);
3396
        break;
3397
    case DM_TARGET_MSG:
3398
        memcpy(host_data, argptr, guest_data_size);
3399
        *(uint64_t*)host_data = tswap64(*(uint64_t*)argptr);
3400
        break;
3401
    case DM_TABLE_LOAD:
3402
    {
3403
        void *gspec = argptr;
3404
        void *cur_data = host_data;
3405
        const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };
3406
        int spec_size = thunk_type_size(arg_type, 0);
3407
        int i;
3408

    
3409
        for (i = 0; i < host_dm->target_count; i++) {
3410
            struct dm_target_spec *spec = cur_data;
3411
            uint32_t next;
3412
            int slen;
3413

    
3414
            thunk_convert(spec, gspec, arg_type, THUNK_HOST);
3415
            slen = strlen((char*)gspec + spec_size) + 1;
3416
            next = spec->next;
3417
            spec->next = sizeof(*spec) + slen;
3418
            strcpy((char*)&spec[1], gspec + spec_size);
3419
            gspec += next;
3420
            cur_data += spec->next;
3421
        }
3422
        break;
3423
    }
3424
    default:
3425
        ret = -TARGET_EINVAL;
3426
        goto out;
3427
    }
3428
    unlock_user(argptr, guest_data, 0);
3429

    
3430
    ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3431
    if (!is_error(ret)) {
3432
        guest_data = arg + host_dm->data_start;
3433
        guest_data_size = host_dm->data_size - host_dm->data_start;
3434
        argptr = lock_user(VERIFY_WRITE, guest_data, guest_data_size, 0);
3435
        switch (ie->host_cmd) {
3436
        case DM_REMOVE_ALL:
3437
        case DM_DEV_CREATE:
3438
        case DM_DEV_REMOVE:
3439
        case DM_DEV_RENAME:
3440
        case DM_DEV_SUSPEND:
3441
        case DM_DEV_STATUS:
3442
        case DM_TABLE_LOAD:
3443
        case DM_TABLE_CLEAR:
3444
        case DM_TARGET_MSG:
3445
        case DM_DEV_SET_GEOMETRY:
3446
            /* no return data */
3447
            break;
3448
        case DM_LIST_DEVICES:
3449
        {
3450
            struct dm_name_list *nl = (void*)host_dm + host_dm->data_start;
3451
            uint32_t remaining_data = guest_data_size;
3452
            void *cur_data = argptr;
3453
            const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_name_list) };
3454
            int nl_size = 12; /* can't use thunk_size due to alignment */
3455

    
3456
            while (1) {
3457
                uint32_t next = nl->next;
3458
                if (next) {
3459
                    nl->next = nl_size + (strlen(nl->name) + 1);
3460
                }
3461
                if (remaining_data < nl->next) {
3462
                    host_dm->flags |= DM_BUFFER_FULL_FLAG;
3463
                    break;
3464
                }
3465
                thunk_convert(cur_data, nl, arg_type, THUNK_TARGET);
3466
                strcpy(cur_data + nl_size, nl->name);
3467
                cur_data += nl->next;
3468
                remaining_data -= nl->next;
3469
                if (!next) {
3470
                    break;
3471
                }
3472
                nl = (void*)nl + next;
3473
            }
3474
            break;
3475
        }
3476
        case DM_DEV_WAIT:
3477
        case DM_TABLE_STATUS:
3478
        {
3479
            struct dm_target_spec *spec = (void*)host_dm + host_dm->data_start;
3480
            void *cur_data = argptr;
3481
            const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };
3482
            int spec_size = thunk_type_size(arg_type, 0);
3483
            int i;
3484

    
3485
            for (i = 0; i < host_dm->target_count; i++) {
3486
                uint32_t next = spec->next;
3487
                int slen = strlen((char*)&spec[1]) + 1;
3488
                spec->next = (cur_data - argptr) + spec_size + slen;
3489
                if (guest_data_size < spec->next) {
3490
                    host_dm->flags |= DM_BUFFER_FULL_FLAG;
3491
                    break;
3492
                }
3493
                thunk_convert(cur_data, spec, arg_type, THUNK_TARGET);
3494
                strcpy(cur_data + spec_size, (char*)&spec[1]);
3495
                cur_data = argptr + spec->next;
3496
                spec = (void*)host_dm + host_dm->data_start + next;
3497
            }
3498
            break;
3499
        }
3500
        case DM_TABLE_DEPS:
3501
        {
3502
            void *hdata = (void*)host_dm + host_dm->data_start;
3503
            int count = *(uint32_t*)hdata;
3504
            uint64_t *hdev = hdata + 8;
3505
            uint64_t *gdev = argptr + 8;
3506
            int i;
3507

    
3508
            *(uint32_t*)argptr = tswap32(count);
3509
            for (i = 0; i < count; i++) {
3510
                *gdev = tswap64(*hdev);
3511
                gdev++;
3512
                hdev++;
3513
            }
3514
            break;
3515
        }
3516
        case DM_LIST_VERSIONS:
3517
        {
3518
            struct dm_target_versions *vers = (void*)host_dm + host_dm->data_start;
3519
            uint32_t remaining_data = guest_data_size;
3520
            void *cur_data = argptr;
3521
            const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_versions) };
3522
            int vers_size = thunk_type_size(arg_type, 0);
3523

    
3524
            while (1) {
3525
                uint32_t next = vers->next;
3526
                if (next) {
3527
                    vers->next = vers_size + (strlen(vers->name) + 1);
3528
                }
3529
                if (remaining_data < vers->next) {
3530
                    host_dm->flags |= DM_BUFFER_FULL_FLAG;
3531
                    break;
3532
                }
3533
                thunk_convert(cur_data, vers, arg_type, THUNK_TARGET);
3534
                strcpy(cur_data + vers_size, vers->name);
3535
                cur_data += vers->next;
3536
                remaining_data -= vers->next;
3537
                if (!next) {
3538
                    break;
3539
                }
3540
                vers = (void*)vers + next;
3541
            }
3542
            break;
3543
        }
3544
        default:
3545
            ret = -TARGET_EINVAL;
3546
            goto out;
3547
        }
3548
        unlock_user(argptr, guest_data, guest_data_size);
3549

    
3550
        argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3551
        if (!argptr) {
3552
            ret = -TARGET_EFAULT;
3553
            goto out;
3554
        }
3555
        thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
3556
        unlock_user(argptr, arg, target_size);
3557
    }
3558
out:
3559
    g_free(big_buf);
3560
    return ret;
3561
}
3562

    
3563
static abi_long do_ioctl_rt(const IOCTLEntry *ie, uint8_t *buf_temp,
3564
                                int fd, abi_long cmd, abi_long arg)
3565
{
3566
    const argtype *arg_type = ie->arg_type;
3567
    const StructEntry *se;
3568
    const argtype *field_types;
3569
    const int *dst_offsets, *src_offsets;
3570
    int target_size;
3571
    void *argptr;
3572
    abi_ulong *target_rt_dev_ptr;
3573
    unsigned long *host_rt_dev_ptr;
3574
    abi_long ret;
3575
    int i;
3576

    
3577
    assert(ie->access == IOC_W);
3578
    assert(*arg_type == TYPE_PTR);
3579
    arg_type++;
3580
    assert(*arg_type == TYPE_STRUCT);
3581
    target_size = thunk_type_size(arg_type, 0);
3582
    argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3583
    if (!argptr) {
3584
        return -TARGET_EFAULT;
3585
    }
3586
    arg_type++;
3587
    assert(*arg_type == (int)STRUCT_rtentry);
3588
    se = struct_entries + *arg_type++;
3589
    assert(se->convert[0] == NULL);
3590
    /* convert struct here to be able to catch rt_dev string */
3591
    field_types = se->field_types;
3592
    dst_offsets = se->field_offsets[THUNK_HOST];
3593
    src_offsets = se->field_offsets[THUNK_TARGET];
3594
    for (i = 0; i < se->nb_fields; i++) {
3595
        if (dst_offsets[i] == offsetof(struct rtentry, rt_dev)) {
3596
            assert(*field_types == TYPE_PTRVOID);
3597
            target_rt_dev_ptr = (abi_ulong *)(argptr + src_offsets[i]);
3598
            host_rt_dev_ptr = (unsigned long *)(buf_temp + dst_offsets[i]);
3599
            if (*target_rt_dev_ptr != 0) {
3600
                *host_rt_dev_ptr = (unsigned long)lock_user_string(
3601
                                                  tswapal(*target_rt_dev_ptr));
3602
                if (!*host_rt_dev_ptr) {
3603
                    unlock_user(argptr, arg, 0);
3604
                    return -TARGET_EFAULT;
3605
                }
3606
            } else {
3607
                *host_rt_dev_ptr = 0;
3608
            }
3609
            field_types++;
3610
            continue;
3611
        }
3612
        field_types = thunk_convert(buf_temp + dst_offsets[i],
3613
                                    argptr + src_offsets[i],
3614
                                    field_types, THUNK_HOST);
3615
    }
3616
    unlock_user(argptr, arg, 0);
3617

    
3618
    ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3619
    if (*host_rt_dev_ptr != 0) {
3620
        unlock_user((void *)*host_rt_dev_ptr,
3621
                    *target_rt_dev_ptr, 0);
3622
    }
3623
    return ret;
3624
}
3625

    
3626
static IOCTLEntry ioctl_entries[] = {
3627
#define IOCTL(cmd, access, ...) \
3628
    { TARGET_ ## cmd, cmd, #cmd, access, 0, {  __VA_ARGS__ } },
3629
#define IOCTL_SPECIAL(cmd, access, dofn, ...)                      \
3630
    { TARGET_ ## cmd, cmd, #cmd, access, dofn, {  __VA_ARGS__ } },
3631
#include "ioctls.h"
3632
    { 0, 0, },
3633
};
3634

    
3635
/* ??? Implement proper locking for ioctls.  */
3636
/* do_ioctl() Must return target values and target errnos. */
3637
static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
3638
{
3639
    const IOCTLEntry *ie;
3640
    const argtype *arg_type;
3641
    abi_long ret;
3642
    uint8_t buf_temp[MAX_STRUCT_SIZE];
3643
    int target_size;
3644
    void *argptr;
3645

    
3646
    ie = ioctl_entries;
3647
    for(;;) {
3648
        if (ie->target_cmd == 0) {
3649
            gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
3650
            return -TARGET_ENOSYS;
3651
        }
3652
        if (ie->target_cmd == cmd)
3653
            break;
3654
        ie++;
3655
    }
3656
    arg_type = ie->arg_type;
3657
#if defined(DEBUG)
3658
    gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
3659
#endif
3660
    if (ie->do_ioctl) {
3661
        return ie->do_ioctl(ie, buf_temp, fd, cmd, arg);
3662
    }
3663

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

    
3723
static const bitmask_transtbl iflag_tbl[] = {
3724
        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
3725
        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
3726
        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
3727
        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
3728
        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
3729
        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
3730
        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
3731
        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
3732
        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
3733
        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
3734
        { TARGET_IXON, TARGET_IXON, IXON, IXON },
3735
        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
3736
        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
3737
        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
3738
        { 0, 0, 0, 0 }
3739
};
3740

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

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

    
3804
static const bitmask_transtbl lflag_tbl[] = {
3805
        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
3806
        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
3807
        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
3808
        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
3809
        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
3810
        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
3811
        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
3812
        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
3813
        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
3814
        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
3815
        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
3816
        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
3817
        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
3818
        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
3819
        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
3820
        { 0, 0, 0, 0 }
3821
};
3822

    
3823
static void target_to_host_termios (void *dst, const void *src)
3824
{
3825
    struct host_termios *host = dst;
3826
    const struct target_termios *target = src;
3827

    
3828
    host->c_iflag =
3829
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
3830
    host->c_oflag =
3831
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
3832
    host->c_cflag =
3833
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
3834
    host->c_lflag =
3835
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
3836
    host->c_line = target->c_line;
3837

    
3838
    memset(host->c_cc, 0, sizeof(host->c_cc));
3839
    host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
3840
    host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
3841
    host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
3842
    host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
3843
    host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
3844
    host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
3845
    host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
3846
    host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
3847
    host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
3848
    host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
3849
    host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
3850
    host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
3851
    host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
3852
    host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
3853
    host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
3854
    host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
3855
    host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
3856
}
3857

    
3858
static void host_to_target_termios (void *dst, const void *src)
3859
{
3860
    struct target_termios *target = dst;
3861
    const struct host_termios *host = src;
3862

    
3863
    target->c_iflag =
3864
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
3865
    target->c_oflag =
3866
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
3867
    target->c_cflag =
3868
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
3869
    target->c_lflag =
3870
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
3871
    target->c_line = host->c_line;
3872

    
3873
    memset(target->c_cc, 0, sizeof(target->c_cc));
3874
    target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
3875
    target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
3876
    target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
3877
    target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
3878
    target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
3879
    target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
3880
    target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
3881
    target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
3882
    target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
3883
    target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
3884
    target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
3885
    target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
3886
    target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
3887
    target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
3888
    target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
3889
    target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
3890
    target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
3891
}
3892

    
3893
static const StructEntry struct_termios_def = {
3894
    .convert = { host_to_target_termios, target_to_host_termios },
3895
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
3896
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
3897
};
3898

    
3899
static bitmask_transtbl mmap_flags_tbl[] = {
3900
        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
3901
        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
3902
        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
3903
        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
3904
        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
3905
        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
3906
        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
3907
        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
3908
        { 0, 0, 0, 0 }
3909
};
3910

    
3911
#if defined(TARGET_I386)
3912

    
3913
/* NOTE: there is really one LDT for all the threads */
3914
static uint8_t *ldt_table;
3915

    
3916
static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
3917
{
3918
    int size;
3919
    void *p;
3920

    
3921
    if (!ldt_table)
3922
        return 0;
3923
    size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
3924
    if (size > bytecount)
3925
        size = bytecount;
3926
    p = lock_user(VERIFY_WRITE, ptr, size, 0);
3927
    if (!p)
3928
        return -TARGET_EFAULT;
3929
    /* ??? Should this by byteswapped?  */
3930
    memcpy(p, ldt_table, size);
3931
    unlock_user(p, ptr, size);
3932
    return size;
3933
}
3934

    
3935
/* XXX: add locking support */
3936
static abi_long write_ldt(CPUX86State *env,
3937
                          abi_ulong ptr, unsigned long bytecount, int oldmode)
3938
{
3939
    struct target_modify_ldt_ldt_s ldt_info;
3940
    struct target_modify_ldt_ldt_s *target_ldt_info;
3941
    int seg_32bit, contents, read_exec_only, limit_in_pages;
3942
    int seg_not_present, useable, lm;
3943
    uint32_t *lp, entry_1, entry_2;
3944

    
3945
    if (bytecount != sizeof(ldt_info))
3946
        return -TARGET_EINVAL;
3947
    if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
3948
        return -TARGET_EFAULT;
3949
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3950
    ldt_info.base_addr = tswapal(target_ldt_info->base_addr);
3951
    ldt_info.limit = tswap32(target_ldt_info->limit);
3952
    ldt_info.flags = tswap32(target_ldt_info->flags);
3953
    unlock_user_struct(target_ldt_info, ptr, 0);
3954

    
3955
    if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
3956
        return -TARGET_EINVAL;
3957
    seg_32bit = ldt_info.flags & 1;
3958
    contents = (ldt_info.flags >> 1) & 3;
3959
    read_exec_only = (ldt_info.flags >> 3) & 1;
3960
    limit_in_pages = (ldt_info.flags >> 4) & 1;
3961
    seg_not_present = (ldt_info.flags >> 5) & 1;
3962
    useable = (ldt_info.flags >> 6) & 1;
3963
#ifdef TARGET_ABI32
3964
    lm = 0;
3965
#else
3966
    lm = (ldt_info.flags >> 7) & 1;
3967
#endif
3968
    if (contents == 3) {
3969
        if (oldmode)
3970
            return -TARGET_EINVAL;
3971
        if (seg_not_present == 0)
3972
            return -TARGET_EINVAL;
3973
    }
3974
    /* allocate the LDT */
3975
    if (!ldt_table) {
3976
        env->ldt.base = target_mmap(0,
3977
                                    TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
3978
                                    PROT_READ|PROT_WRITE,
3979
                                    MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
3980
        if (env->ldt.base == -1)
3981
            return -TARGET_ENOMEM;
3982
        memset(g2h(env->ldt.base), 0,
3983
               TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
3984
        env->ldt.limit = 0xffff;
3985
        ldt_table = g2h(env->ldt.base);
3986
    }
3987

    
3988
    /* NOTE: same code as Linux kernel */
3989
    /* Allow LDTs to be cleared by the user. */
3990
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3991
        if (oldmode ||
3992
            (contents == 0                &&
3993
             read_exec_only == 1        &&
3994
             seg_32bit == 0                &&
3995
             limit_in_pages == 0        &&
3996
             seg_not_present == 1        &&
3997
             useable == 0 )) {
3998
            entry_1 = 0;
3999
            entry_2 = 0;
4000
            goto install;
4001
        }
4002
    }
4003

    
4004
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
4005
        (ldt_info.limit & 0x0ffff);
4006
    entry_2 = (ldt_info.base_addr & 0xff000000) |
4007
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
4008
        (ldt_info.limit & 0xf0000) |
4009
        ((read_exec_only ^ 1) << 9) |
4010
        (contents << 10) |
4011
        ((seg_not_present ^ 1) << 15) |
4012
        (seg_32bit << 22) |
4013
        (limit_in_pages << 23) |
4014
        (lm << 21) |
4015
        0x7000;
4016
    if (!oldmode)
4017
        entry_2 |= (useable << 20);
4018

    
4019
    /* Install the new entry ...  */
4020
install:
4021
    lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
4022
    lp[0] = tswap32(entry_1);
4023
    lp[1] = tswap32(entry_2);
4024
    return 0;
4025
}
4026

    
4027
/* specific and weird i386 syscalls */
4028
static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
4029
                              unsigned long bytecount)
4030
{
4031
    abi_long ret;
4032

    
4033
    switch (func) {
4034
    case 0:
4035
        ret = read_ldt(ptr, bytecount);
4036
        break;
4037
    case 1:
4038
        ret = write_ldt(env, ptr, bytecount, 1);
4039
        break;
4040
    case 0x11:
4041
        ret = write_ldt(env, ptr, bytecount, 0);
4042
        break;
4043
    default:
4044
        ret = -TARGET_ENOSYS;
4045
        break;
4046
    }
4047
    return ret;
4048
}
4049

    
4050
#if defined(TARGET_I386) && defined(TARGET_ABI32)
4051
abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
4052
{
4053
    uint64_t *gdt_table = g2h(env->gdt.base);
4054
    struct target_modify_ldt_ldt_s ldt_info;
4055
    struct target_modify_ldt_ldt_s *target_ldt_info;
4056
    int seg_32bit, contents, read_exec_only, limit_in_pages;
4057
    int seg_not_present, useable, lm;
4058
    uint32_t *lp, entry_1, entry_2;
4059
    int i;
4060

    
4061
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
4062
    if (!target_ldt_info)
4063
        return -TARGET_EFAULT;
4064
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
4065
    ldt_info.base_addr = tswapal(target_ldt_info->base_addr);
4066
    ldt_info.limit = tswap32(target_ldt_info->limit);
4067
    ldt_info.flags = tswap32(target_ldt_info->flags);
4068
    if (ldt_info.entry_number == -1) {
4069
        for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
4070
            if (gdt_table[i] == 0) {
4071
                ldt_info.entry_number = i;
4072
                target_ldt_info->entry_number = tswap32(i);
4073
                break;
4074
            }
4075
        }
4076
    }
4077
    unlock_user_struct(target_ldt_info, ptr, 1);
4078

    
4079
    if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || 
4080
        ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
4081
           return -TARGET_EINVAL;
4082
    seg_32bit = ldt_info.flags & 1;
4083
    contents = (ldt_info.flags >> 1) & 3;
4084
    read_exec_only = (ldt_info.flags >> 3) & 1;
4085
    limit_in_pages = (ldt_info.flags >> 4) & 1;
4086
    seg_not_present = (ldt_info.flags >> 5) & 1;
4087
    useable = (ldt_info.flags >> 6) & 1;
4088
#ifdef TARGET_ABI32
4089
    lm = 0;
4090
#else
4091
    lm = (ldt_info.flags >> 7) & 1;
4092
#endif
4093

    
4094
    if (contents == 3) {
4095
        if (seg_not_present == 0)
4096
            return -TARGET_EINVAL;
4097
    }
4098

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

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

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

    
4136
static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
4137
{
4138
    struct target_modify_ldt_ldt_s *target_ldt_info;
4139
    uint64_t *gdt_table = g2h(env->gdt.base);
4140
    uint32_t base_addr, limit, flags;
4141
    int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
4142
    int seg_not_present, useable, lm;
4143
    uint32_t *lp, entry_1, entry_2;
4144

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

    
4184
#ifndef TARGET_ABI32
4185
abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
4186
{
4187
    abi_long ret = 0;
4188
    abi_ulong val;
4189
    int idx;
4190

    
4191
    switch(code) {
4192
    case TARGET_ARCH_SET_GS:
4193
    case TARGET_ARCH_SET_FS:
4194
        if (code == TARGET_ARCH_SET_GS)
4195
            idx = R_GS;
4196
        else
4197
            idx = R_FS;
4198
        cpu_x86_load_seg(env, idx, 0);
4199
        env->segs[idx].base = addr;
4200
        break;
4201
    case TARGET_ARCH_GET_GS:
4202
    case TARGET_ARCH_GET_FS:
4203
        if (code == TARGET_ARCH_GET_GS)
4204
            idx = R_GS;
4205
        else
4206
            idx = R_FS;
4207
        val = env->segs[idx].base;
4208
        if (put_user(val, addr, abi_ulong))
4209
            ret = -TARGET_EFAULT;
4210
        break;
4211
    default:
4212
        ret = -TARGET_EINVAL;
4213
        break;
4214
    }
4215
    return ret;
4216
}
4217
#endif
4218

    
4219
#endif /* defined(TARGET_I386) */
4220

    
4221
#define NEW_STACK_SIZE 0x40000
4222

    
4223

    
4224
static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
4225
typedef struct {
4226
    CPUArchState *env;
4227
    pthread_mutex_t mutex;
4228
    pthread_cond_t cond;
4229
    pthread_t thread;
4230
    uint32_t tid;
4231
    abi_ulong child_tidptr;
4232
    abi_ulong parent_tidptr;
4233
    sigset_t sigmask;
4234
} new_thread_info;
4235

    
4236
static void *clone_func(void *arg)
4237
{
4238
    new_thread_info *info = arg;
4239
    CPUArchState *env;
4240
    CPUState *cpu;
4241
    TaskState *ts;
4242

    
4243
    env = info->env;
4244
    cpu = ENV_GET_CPU(env);
4245
    thread_cpu = cpu;
4246
    ts = (TaskState *)env->opaque;
4247
    info->tid = gettid();
4248
    cpu->host_tid = info->tid;
4249
    task_settid(ts);
4250
    if (info->child_tidptr)
4251
        put_user_u32(info->tid, info->child_tidptr);
4252
    if (info->parent_tidptr)
4253
        put_user_u32(info->tid, info->parent_tidptr);
4254
    /* Enable signals.  */
4255
    sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
4256
    /* Signal to the parent that we're ready.  */
4257
    pthread_mutex_lock(&info->mutex);
4258
    pthread_cond_broadcast(&info->cond);
4259
    pthread_mutex_unlock(&info->mutex);
4260
    /* Wait until the parent has finshed initializing the tls state.  */
4261
    pthread_mutex_lock(&clone_lock);
4262
    pthread_mutex_unlock(&clone_lock);
4263
    cpu_loop(env);
4264
    /* never exits */
4265
    return NULL;
4266
}
4267

    
4268
/* do_fork() Must return host values and target errnos (unlike most
4269
   do_*() functions). */
4270
static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
4271
                   abi_ulong parent_tidptr, target_ulong newtls,
4272
                   abi_ulong child_tidptr)
4273
{
4274
    int ret;
4275
    TaskState *ts;
4276
    CPUArchState *new_env;
4277
    unsigned int nptl_flags;
4278
    sigset_t sigmask;
4279

    
4280
    /* Emulate vfork() with fork() */
4281
    if (flags & CLONE_VFORK)
4282
        flags &= ~(CLONE_VFORK | CLONE_VM);
4283

    
4284
    if (flags & CLONE_VM) {
4285
        TaskState *parent_ts = (TaskState *)env->opaque;
4286
        new_thread_info info;
4287
        pthread_attr_t attr;
4288

    
4289
        ts = g_malloc0(sizeof(TaskState));
4290
        init_task_state(ts);
4291
        /* we create a new CPU instance. */
4292
        new_env = cpu_copy(env);
4293
        /* Init regs that differ from the parent.  */
4294
        cpu_clone_regs(new_env, newsp);
4295
        new_env->opaque = ts;
4296
        ts->bprm = parent_ts->bprm;
4297
        ts->info = parent_ts->info;
4298
        nptl_flags = flags;
4299
        flags &= ~CLONE_NPTL_FLAGS2;
4300

    
4301
        if (nptl_flags & CLONE_CHILD_CLEARTID) {
4302
            ts->child_tidptr = child_tidptr;
4303
        }
4304

    
4305
        if (nptl_flags & CLONE_SETTLS)
4306
            cpu_set_tls (new_env, newtls);
4307

    
4308
        /* Grab a mutex so that thread setup appears atomic.  */
4309
        pthread_mutex_lock(&clone_lock);
4310

    
4311
        memset(&info, 0, sizeof(info));
4312
        pthread_mutex_init(&info.mutex, NULL);
4313
        pthread_mutex_lock(&info.mutex);
4314
        pthread_cond_init(&info.cond, NULL);
4315
        info.env = new_env;
4316
        if (nptl_flags & CLONE_CHILD_SETTID)
4317
            info.child_tidptr = child_tidptr;
4318
        if (nptl_flags & CLONE_PARENT_SETTID)
4319
            info.parent_tidptr = parent_tidptr;
4320

    
4321
        ret = pthread_attr_init(&attr);
4322
        ret = pthread_attr_setstacksize(&attr, NEW_STACK_SIZE);
4323
        ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
4324
        /* It is not safe to deliver signals until the child has finished
4325
           initializing, so temporarily block all signals.  */
4326
        sigfillset(&sigmask);
4327
        sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
4328

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

    
4332
        sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
4333
        pthread_attr_destroy(&attr);
4334
        if (ret == 0) {
4335
            /* Wait for the child to initialize.  */
4336
            pthread_cond_wait(&info.cond, &info.mutex);
4337
            ret = info.tid;
4338
            if (flags & CLONE_PARENT_SETTID)
4339
                put_user_u32(ret, parent_tidptr);
4340
        } else {
4341
            ret = -1;
4342
        }
4343
        pthread_mutex_unlock(&info.mutex);
4344
        pthread_cond_destroy(&info.cond);
4345
        pthread_mutex_destroy(&info.mutex);
4346
        pthread_mutex_unlock(&clone_lock);
4347
    } else {
4348
        /* if no CLONE_VM, we consider it is a fork */
4349
        if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
4350
            return -EINVAL;
4351
        fork_start();
4352
        ret = fork();
4353
        if (ret == 0) {
4354
            /* Child Process.  */
4355
            cpu_clone_regs(env, newsp);
4356
            fork_end(1);
4357
            /* There is a race condition here.  The parent process could
4358
               theoretically read the TID in the child process before the child
4359
               tid is set.  This would require using either ptrace
4360
               (not implemented) or having *_tidptr to point at a shared memory
4361
               mapping.  We can't repeat the spinlock hack used above because
4362
               the child process gets its own copy of the lock.  */
4363
            if (flags & CLONE_CHILD_SETTID)
4364
                put_user_u32(gettid(), child_tidptr);
4365
            if (flags & CLONE_PARENT_SETTID)
4366
                put_user_u32(gettid(), parent_tidptr);
4367
            ts = (TaskState *)env->opaque;
4368
            if (flags & CLONE_SETTLS)
4369
                cpu_set_tls (env, newtls);
4370
            if (flags & CLONE_CHILD_CLEARTID)
4371
                ts->child_tidptr = child_tidptr;
4372
        } else {
4373
            fork_end(0);
4374
        }
4375
    }
4376
    return ret;
4377
}
4378

    
4379
/* warning : doesn't handle linux specific flags... */
4380
static int target_to_host_fcntl_cmd(int cmd)
4381
{
4382
    switch(cmd) {
4383
        case TARGET_F_DUPFD:
4384
        case TARGET_F_GETFD:
4385
        case TARGET_F_SETFD:
4386
        case TARGET_F_GETFL:
4387
        case TARGET_F_SETFL:
4388
            return cmd;
4389
        case TARGET_F_GETLK:
4390
            return F_GETLK;
4391
        case TARGET_F_SETLK:
4392
            return F_SETLK;
4393
        case TARGET_F_SETLKW:
4394
            return F_SETLKW;
4395
        case TARGET_F_GETOWN:
4396
            return F_GETOWN;
4397
        case TARGET_F_SETOWN:
4398
            return F_SETOWN;
4399
        case TARGET_F_GETSIG:
4400
            return F_GETSIG;
4401
        case TARGET_F_SETSIG:
4402
            return F_SETSIG;
4403
#if TARGET_ABI_BITS == 32
4404
        case TARGET_F_GETLK64:
4405
            return F_GETLK64;
4406
        case TARGET_F_SETLK64:
4407
            return F_SETLK64;
4408
        case TARGET_F_SETLKW64:
4409
            return F_SETLKW64;
4410
#endif
4411
        case TARGET_F_SETLEASE:
4412
            return F_SETLEASE;
4413
        case TARGET_F_GETLEASE:
4414
            return F_GETLEASE;
4415
#ifdef F_DUPFD_CLOEXEC
4416
        case TARGET_F_DUPFD_CLOEXEC:
4417
            return F_DUPFD_CLOEXEC;
4418
#endif
4419
        case TARGET_F_NOTIFY:
4420
            return F_NOTIFY;
4421
        default:
4422
            return -TARGET_EINVAL;
4423
    }
4424
    return -TARGET_EINVAL;
4425
}
4426

    
4427
#define TRANSTBL_CONVERT(a) { -1, TARGET_##a, -1, a }
4428
static const bitmask_transtbl flock_tbl[] = {
4429
    TRANSTBL_CONVERT(F_RDLCK),
4430
    TRANSTBL_CONVERT(F_WRLCK),
4431
    TRANSTBL_CONVERT(F_UNLCK),
4432
    TRANSTBL_CONVERT(F_EXLCK),
4433
    TRANSTBL_CONVERT(F_SHLCK),
4434
    { 0, 0, 0, 0 }
4435
};
4436

    
4437
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
4438
{
4439
    struct flock fl;
4440
    struct target_flock *target_fl;
4441
    struct flock64 fl64;
4442
    struct target_flock64 *target_fl64;
4443
    abi_long ret;
4444
    int host_cmd = target_to_host_fcntl_cmd(cmd);
4445

    
4446
    if (host_cmd == -TARGET_EINVAL)
4447
            return host_cmd;
4448

    
4449
    switch(cmd) {
4450
    case TARGET_F_GETLK:
4451
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
4452
            return -TARGET_EFAULT;
4453
        fl.l_type =
4454
                  target_to_host_bitmask(tswap16(target_fl->l_type), flock_tbl);
4455
        fl.l_whence = tswap16(target_fl->l_whence);
4456
        fl.l_start = tswapal(target_fl->l_start);
4457
        fl.l_len = tswapal(target_fl->l_len);
4458
        fl.l_pid = tswap32(target_fl->l_pid);
4459
        unlock_user_struct(target_fl, arg, 0);
4460
        ret = get_errno(fcntl(fd, host_cmd, &fl));
4461
        if (ret == 0) {
4462
            if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
4463
                return -TARGET_EFAULT;
4464
            target_fl->l_type =
4465
                          host_to_target_bitmask(tswap16(fl.l_type), flock_tbl);
4466
            target_fl->l_whence = tswap16(fl.l_whence);
4467
            target_fl->l_start = tswapal(fl.l_start);
4468
            target_fl->l_len = tswapal(fl.l_len);
4469
            target_fl->l_pid = tswap32(fl.l_pid);
4470
            unlock_user_struct(target_fl, arg, 1);
4471
        }
4472
        break;
4473

    
4474
    case TARGET_F_SETLK:
4475
    case TARGET_F_SETLKW:
4476
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
4477
            return -TARGET_EFAULT;
4478
        fl.l_type =
4479
                  target_to_host_bitmask(tswap16(target_fl->l_type), flock_tbl);
4480
        fl.l_whence = tswap16(target_fl->l_whence);
4481
        fl.l_start = tswapal(target_fl->l_start);
4482
        fl.l_len = tswapal(target_fl->l_len);
4483
        fl.l_pid = tswap32(target_fl->l_pid);
4484
        unlock_user_struct(target_fl, arg, 0);
4485
        ret = get_errno(fcntl(fd, host_cmd, &fl));
4486
        break;
4487

    
4488
    case TARGET_F_GETLK64:
4489
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
4490
            return -TARGET_EFAULT;
4491
        fl64.l_type =
4492
           target_to_host_bitmask(tswap16(target_fl64->l_type), flock_tbl) >> 1;
4493
        fl64.l_whence = tswap16(target_fl64->l_whence);
4494
        fl64.l_start = tswap64(target_fl64->l_start);
4495
        fl64.l_len = tswap64(target_fl64->l_len);
4496
        fl64.l_pid = tswap32(target_fl64->l_pid);
4497
        unlock_user_struct(target_fl64, arg, 0);
4498
        ret = get_errno(fcntl(fd, host_cmd, &fl64));
4499
        if (ret == 0) {
4500
            if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
4501
                return -TARGET_EFAULT;
4502
            target_fl64->l_type =
4503
                   host_to_target_bitmask(tswap16(fl64.l_type), flock_tbl) >> 1;
4504
            target_fl64->l_whence = tswap16(fl64.l_whence);
4505
            target_fl64->l_start = tswap64(fl64.l_start);
4506
            target_fl64->l_len = tswap64(fl64.l_len);
4507
            target_fl64->l_pid = tswap32(fl64.l_pid);
4508
            unlock_user_struct(target_fl64, arg, 1);
4509
        }
4510
        break;
4511
    case TARGET_F_SETLK64:
4512
    case TARGET_F_SETLKW64:
4513
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
4514
            return -TARGET_EFAULT;
4515
        fl64.l_type =
4516
           target_to_host_bitmask(tswap16(target_fl64->l_type), flock_tbl) >> 1;
4517
        fl64.l_whence = tswap16(target_fl64->l_whence);
4518
        fl64.l_start = tswap64(target_fl64->l_start);
4519
        fl64.l_len = tswap64(target_fl64->l_len);
4520
        fl64.l_pid = tswap32(target_fl64->l_pid);
4521
        unlock_user_struct(target_fl64, arg, 0);
4522
        ret = get_errno(fcntl(fd, host_cmd, &fl64));
4523
        break;
4524

    
4525
    case TARGET_F_GETFL:
4526
        ret = get_errno(fcntl(fd, host_cmd, arg));
4527
        if (ret >= 0) {
4528
            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
4529
        }
4530
        break;
4531

    
4532
    case TARGET_F_SETFL:
4533
        ret = get_errno(fcntl(fd, host_cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
4534
        break;
4535

    
4536
    case TARGET_F_SETOWN:
4537
    case TARGET_F_GETOWN:
4538
    case TARGET_F_SETSIG:
4539
    case TARGET_F_GETSIG:
4540
    case TARGET_F_SETLEASE:
4541
    case TARGET_F_GETLEASE:
4542
        ret = get_errno(fcntl(fd, host_cmd, arg));
4543
        break;
4544

    
4545
    default:
4546
        ret = get_errno(fcntl(fd, cmd, arg));
4547
        break;
4548
    }
4549
    return ret;
4550
}
4551

    
4552
#ifdef USE_UID16
4553

    
4554
static inline int high2lowuid(int uid)
4555
{
4556
    if (uid > 65535)
4557
        return 65534;
4558
    else
4559
        return uid;
4560
}
4561

    
4562
static inline int high2lowgid(int gid)
4563
{
4564
    if (gid > 65535)
4565
        return 65534;
4566
    else
4567
        return gid;
4568
}
4569

    
4570
static inline int low2highuid(int uid)
4571
{
4572
    if ((int16_t)uid == -1)
4573
        return -1;
4574
    else
4575
        return uid;
4576
}
4577

    
4578
static inline int low2highgid(int gid)
4579
{
4580
    if ((int16_t)gid == -1)
4581
        return -1;
4582
    else
4583
        return gid;
4584
}
4585
static inline int tswapid(int id)
4586
{
4587
    return tswap16(id);
4588
}
4589

    
4590
#define put_user_id(x, gaddr) put_user_u16(x, gaddr)
4591

    
4592
#else /* !USE_UID16 */
4593
static inline int high2lowuid(int uid)
4594
{
4595
    return uid;
4596
}
4597
static inline int high2lowgid(int gid)
4598
{
4599
    return gid;
4600
}
4601
static inline int low2highuid(int uid)
4602
{
4603
    return uid;
4604
}
4605
static inline int low2highgid(int gid)
4606
{
4607
    return gid;
4608
}
4609
static inline int tswapid(int id)
4610
{
4611
    return tswap32(id);
4612
}
4613

    
4614
#define put_user_id(x, gaddr) put_user_u32(x, gaddr)
4615

    
4616
#endif /* USE_UID16 */
4617

    
4618
void syscall_init(void)
4619
{
4620
    IOCTLEntry *ie;
4621
    const argtype *arg_type;
4622
    int size;
4623
    int i;
4624

    
4625
#define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
4626
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
4627
#include "syscall_types.h"
4628
#undef STRUCT
4629
#undef STRUCT_SPECIAL
4630

    
4631
    /* Build target_to_host_errno_table[] table from
4632
     * host_to_target_errno_table[]. */
4633
    for (i = 0; i < ERRNO_TABLE_SIZE; i++) {
4634
        target_to_host_errno_table[host_to_target_errno_table[i]] = i;
4635
    }
4636

    
4637
    /* we patch the ioctl size if necessary. We rely on the fact that
4638
       no ioctl has all the bits at '1' in the size field */
4639
    ie = ioctl_entries;
4640
    while (ie->target_cmd != 0) {
4641
        if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
4642
            TARGET_IOC_SIZEMASK) {
4643
            arg_type = ie->arg_type;
4644
            if (arg_type[0] != TYPE_PTR) {
4645
                fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
4646
                        ie->target_cmd);
4647
                exit(1);
4648
            }
4649
            arg_type++;
4650
            size = thunk_type_size(arg_type, 0);
4651
            ie->target_cmd = (ie->target_cmd &
4652
                              ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
4653
                (size << TARGET_IOC_SIZESHIFT);
4654
        }
4655

    
4656
        /* automatic consistency check if same arch */
4657
#if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
4658
    (defined(__x86_64__) && defined(TARGET_X86_64))
4659
        if (unlikely(ie->target_cmd != ie->host_cmd)) {
4660
            fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
4661
                    ie->name, ie->target_cmd, ie->host_cmd);
4662
        }
4663
#endif
4664
        ie++;
4665
    }
4666
}
4667

    
4668
#if TARGET_ABI_BITS == 32
4669
static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
4670
{
4671
#ifdef TARGET_WORDS_BIGENDIAN
4672
    return ((uint64_t)word0 << 32) | word1;
4673
#else
4674
    return ((uint64_t)word1 << 32) | word0;
4675
#endif
4676
}
4677
#else /* TARGET_ABI_BITS == 32 */
4678
static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
4679
{
4680
    return word0;
4681
}
4682
#endif /* TARGET_ABI_BITS != 32 */
4683

    
4684
#ifdef TARGET_NR_truncate64
4685
static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
4686
                                         abi_long arg2,
4687
                                         abi_long arg3,
4688
                                         abi_long arg4)
4689
{
4690
    if (regpairs_aligned(cpu_env)) {
4691
        arg2 = arg3;
4692
        arg3 = arg4;
4693
    }
4694
    return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
4695
}
4696
#endif
4697

    
4698
#ifdef TARGET_NR_ftruncate64
4699
static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
4700
                                          abi_long arg2,
4701
                                          abi_long arg3,
4702
                                          abi_long arg4)
4703
{
4704
    if (regpairs_aligned(cpu_env)) {
4705
        arg2 = arg3;
4706
        arg3 = arg4;
4707
    }
4708
    return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
4709
}
4710
#endif
4711

    
4712
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
4713
                                               abi_ulong target_addr)
4714
{
4715
    struct target_timespec *target_ts;
4716

    
4717
    if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
4718
        return -TARGET_EFAULT;
4719
    host_ts->tv_sec = tswapal(target_ts->tv_sec);
4720
    host_ts->tv_nsec = tswapal(target_ts->tv_nsec);
4721
    unlock_user_struct(target_ts, target_addr, 0);
4722
    return 0;
4723
}
4724

    
4725
static inline abi_long host_to_target_timespec(abi_ulong target_addr,
4726
                                               struct timespec *host_ts)
4727
{
4728
    struct target_timespec *target_ts;
4729

    
4730
    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
4731
        return -TARGET_EFAULT;
4732
    target_ts->tv_sec = tswapal(host_ts->tv_sec);
4733
    target_ts->tv_nsec = tswapal(host_ts->tv_nsec);
4734
    unlock_user_struct(target_ts, target_addr, 1);
4735
    return 0;
4736
}
4737

    
4738
static inline abi_long target_to_host_itimerspec(struct itimerspec *host_itspec,
4739
                                                 abi_ulong target_addr)
4740
{
4741
    struct target_itimerspec *target_itspec;
4742

    
4743
    if (!lock_user_struct(VERIFY_READ, target_itspec, target_addr, 1)) {
4744
        return -TARGET_EFAULT;
4745
    }
4746

    
4747
    host_itspec->it_interval.tv_sec =
4748
                            tswapal(target_itspec->it_interval.tv_sec);
4749
    host_itspec->it_interval.tv_nsec =
4750
                            tswapal(target_itspec->it_interval.tv_nsec);
4751
    host_itspec->it_value.tv_sec = tswapal(target_itspec->it_value.tv_sec);
4752
    host_itspec->it_value.tv_nsec = tswapal(target_itspec->it_value.tv_nsec);
4753

    
4754
    unlock_user_struct(target_itspec, target_addr, 1);
4755
    return 0;
4756
}
4757

    
4758
static inline abi_long host_to_target_itimerspec(abi_ulong target_addr,
4759
                                               struct itimerspec *host_its)
4760
{
4761
    struct target_itimerspec *target_itspec;
4762

    
4763
    if (!lock_user_struct(VERIFY_WRITE, target_itspec, target_addr, 0)) {
4764
        return -TARGET_EFAULT;
4765
    }
4766

    
4767
    target_itspec->it_interval.tv_sec = tswapal(host_its->it_interval.tv_sec);
4768
    target_itspec->it_interval.tv_nsec = tswapal(host_its->it_interval.tv_nsec);
4769

    
4770
    target_itspec->it_value.tv_sec = tswapal(host_its->it_value.tv_sec);
4771
    target_itspec->it_value.tv_nsec = tswapal(host_its->it_value.tv_nsec);
4772

    
4773
    unlock_user_struct(target_itspec, target_addr, 0);
4774
    return 0;
4775
}
4776

    
4777
#if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
4778
static inline abi_long host_to_target_stat64(void *cpu_env,
4779
                                             abi_ulong target_addr,
4780
                                             struct stat *host_st)
4781
{
4782
#if defined(TARGET_ARM) && defined(TARGET_ABI32)
4783
    if (((CPUARMState *)cpu_env)->eabi) {
4784
        struct target_eabi_stat64 *target_st;
4785

    
4786
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
4787
            return -TARGET_EFAULT;
4788
        memset(target_st, 0, sizeof(struct target_eabi_stat64));
4789
        __put_user(host_st->st_dev, &target_st->st_dev);
4790
        __put_user(host_st->st_ino, &target_st->st_ino);
4791
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4792
        __put_user(host_st->st_ino, &target_st->__st_ino);
4793
#endif
4794
        __put_user(host_st->st_mode, &target_st->st_mode);
4795
        __put_user(host_st->st_nlink, &target_st->st_nlink);
4796
        __put_user(host_st->st_uid, &target_st->st_uid);
4797
        __put_user(host_st->st_gid, &target_st->st_gid);
4798
        __put_user(host_st->st_rdev, &target_st->st_rdev);
4799
        __put_user(host_st->st_size, &target_st->st_size);
4800
        __put_user(host_st->st_blksize, &target_st->st_blksize);
4801
        __put_user(host_st->st_blocks, &target_st->st_blocks);
4802
        __put_user(host_st->st_atime, &target_st->target_st_atime);
4803
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
4804
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
4805
        unlock_user_struct(target_st, target_addr, 1);
4806
    } else
4807
#endif
4808
    {
4809
#if defined(TARGET_HAS_STRUCT_STAT64)
4810
        struct target_stat64 *target_st;
4811
#else
4812
        struct target_stat *target_st;
4813
#endif
4814

    
4815
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
4816
            return -TARGET_EFAULT;
4817
        memset(target_st, 0, sizeof(*target_st));
4818
        __put_user(host_st->st_dev, &target_st->st_dev);
4819
        __put_user(host_st->st_ino, &target_st->st_ino);
4820
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4821
        __put_user(host_st->st_ino, &target_st->__st_ino);
4822
#endif
4823
        __put_user(host_st->st_mode, &target_st->st_mode);
4824
        __put_user(host_st->st_nlink, &target_st->st_nlink);
4825
        __put_user(host_st->st_uid, &target_st->st_uid);
4826
        __put_user(host_st->st_gid, &target_st->st_gid);
4827
        __put_user(host_st->st_rdev, &target_st->st_rdev);
4828
        /* XXX: better use of kernel struct */
4829
        __put_user(host_st->st_size, &target_st->st_size);
4830
        __put_user(host_st->st_blksize, &target_st->st_blksize);
4831
        __put_user(host_st->st_blocks, &target_st->st_blocks);
4832
        __put_user(host_st->st_atime, &target_st->target_st_atime);
4833
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
4834
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
4835
        unlock_user_struct(target_st, target_addr, 1);
4836
    }
4837

    
4838
    return 0;
4839
}
4840
#endif
4841

    
4842
/* ??? Using host futex calls even when target atomic operations
4843
   are not really atomic probably breaks things.  However implementing
4844
   futexes locally would make futexes shared between multiple processes
4845
   tricky.  However they're probably useless because guest atomic
4846
   operations won't work either.  */
4847
static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
4848
                    target_ulong uaddr2, int val3)
4849
{
4850
    struct timespec ts, *pts;
4851
    int base_op;
4852

    
4853
    /* ??? We assume FUTEX_* constants are the same on both host
4854
       and target.  */
4855
#ifdef FUTEX_CMD_MASK
4856
    base_op = op & FUTEX_CMD_MASK;
4857
#else
4858
    base_op = op;
4859
#endif
4860
    switch (base_op) {
4861
    case FUTEX_WAIT:
4862
    case FUTEX_WAIT_BITSET:
4863
        if (timeout) {
4864
            pts = &ts;
4865
            target_to_host_timespec(pts, timeout);
4866
        } else {
4867
            pts = NULL;
4868
        }
4869
        return get_errno(sys_futex(g2h(uaddr), op, tswap32(val),
4870
                         pts, NULL, val3));
4871
    case FUTEX_WAKE:
4872
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4873
    case FUTEX_FD:
4874
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4875
    case FUTEX_REQUEUE:
4876
    case FUTEX_CMP_REQUEUE:
4877
    case FUTEX_WAKE_OP:
4878
        /* For FUTEX_REQUEUE, FUTEX_CMP_REQUEUE, and FUTEX_WAKE_OP, the
4879
           TIMEOUT parameter is interpreted as a uint32_t by the kernel.
4880
           But the prototype takes a `struct timespec *'; insert casts
4881
           to satisfy the compiler.  We do not need to tswap TIMEOUT
4882
           since it's not compared to guest memory.  */
4883
        pts = (struct timespec *)(uintptr_t) timeout;
4884
        return get_errno(sys_futex(g2h(uaddr), op, val, pts,
4885
                                   g2h(uaddr2),
4886
                                   (base_op == FUTEX_CMP_REQUEUE
4887
                                    ? tswap32(val3)
4888
                                    : val3)));
4889
    default:
4890
        return -TARGET_ENOSYS;
4891
    }
4892
}
4893

    
4894
/* Map host to target signal numbers for the wait family of syscalls.
4895
   Assume all other status bits are the same.  */
4896
int host_to_target_waitstatus(int status)
4897
{
4898
    if (WIFSIGNALED(status)) {
4899
        return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f);
4900
    }
4901
    if (WIFSTOPPED(status)) {
4902
        return (host_to_target_signal(WSTOPSIG(status)) << 8)
4903
               | (status & 0xff);
4904
    }
4905
    return status;
4906
}
4907

    
4908
static int relstr_to_int(const char *s)
4909
{
4910
    /* Convert a uname release string like "2.6.18" to an integer
4911
     * of the form 0x020612. (Beware that 0x020612 is *not* 2.6.12.)
4912
     */
4913
    int i, n, tmp;
4914

    
4915
    tmp = 0;
4916
    for (i = 0; i < 3; i++) {
4917
        n = 0;
4918
        while (*s >= '0' && *s <= '9') {
4919
            n *= 10;
4920
            n += *s - '0';
4921
            s++;
4922
        }
4923
        tmp = (tmp << 8) + n;
4924
        if (*s == '.') {
4925
            s++;
4926
        }
4927
    }
4928
    return tmp;
4929
}
4930

    
4931
int get_osversion(void)
4932
{
4933
    static int osversion;
4934
    struct new_utsname buf;
4935
    const char *s;
4936

    
4937
    if (osversion)
4938
        return osversion;
4939
    if (qemu_uname_release && *qemu_uname_release) {
4940
        s = qemu_uname_release;
4941
    } else {
4942
        if (sys_uname(&buf))
4943
            return 0;
4944
        s = buf.release;
4945
    }
4946
    osversion = relstr_to_int(s);
4947
    return osversion;
4948
}
4949

    
4950
void init_qemu_uname_release(void)
4951
{
4952
    /* Initialize qemu_uname_release for later use.
4953
     * If the host kernel is too old and the user hasn't asked for
4954
     * a specific fake version number, we might want to fake a minimum
4955
     * target kernel version.
4956
     */
4957
#ifdef UNAME_MINIMUM_RELEASE
4958
    struct new_utsname buf;
4959

    
4960
    if (qemu_uname_release && *qemu_uname_release) {
4961
        return;
4962
    }
4963

    
4964
    if (sys_uname(&buf)) {
4965
        return;
4966
    }
4967

    
4968
    if (relstr_to_int(buf.release) < relstr_to_int(UNAME_MINIMUM_RELEASE)) {
4969
        qemu_uname_release = UNAME_MINIMUM_RELEASE;
4970
    }
4971
#endif
4972
}
4973

    
4974
static int open_self_maps(void *cpu_env, int fd)
4975
{
4976
#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
4977
    TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
4978
#endif
4979
    FILE *fp;
4980
    char *line = NULL;
4981
    size_t len = 0;
4982
    ssize_t read;
4983

    
4984
    fp = fopen("/proc/self/maps", "r");
4985
    if (fp == NULL) {
4986
        return -EACCES;
4987
    }
4988

    
4989
    while ((read = getline(&line, &len, fp)) != -1) {
4990
        int fields, dev_maj, dev_min, inode;
4991
        uint64_t min, max, offset;
4992
        char flag_r, flag_w, flag_x, flag_p;
4993
        char path[512] = "";
4994
        fields = sscanf(line, "%"PRIx64"-%"PRIx64" %c%c%c%c %"PRIx64" %x:%x %d"
4995
                        " %512s", &min, &max, &flag_r, &flag_w, &flag_x,
4996
                        &flag_p, &offset, &dev_maj, &dev_min, &inode, path);
4997

    
4998
        if ((fields < 10) || (fields > 11)) {
4999
            continue;
5000
        }
5001
        if (!strncmp(path, "[stack]", 7)) {
5002
            continue;
5003
        }
5004
        if (h2g_valid(min) && h2g_valid(max)) {
5005
            dprintf(fd, TARGET_ABI_FMT_lx "-" TARGET_ABI_FMT_lx
5006
                    " %c%c%c%c %08" PRIx64 " %02x:%02x %d %s%s\n",
5007
                    h2g(min), h2g(max), flag_r, flag_w,
5008
                    flag_x, flag_p, offset, dev_maj, dev_min, inode,
5009
                    path[0] ? "         " : "", path);
5010
        }
5011
    }
5012

    
5013
    free(line);
5014
    fclose(fp);
5015

    
5016
#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
5017
    dprintf(fd, "%08llx-%08llx rw-p %08llx 00:00 0          [stack]\n",
5018
                (unsigned long long)ts->info->stack_limit,
5019
                (unsigned long long)(ts->info->start_stack +
5020
                                     (TARGET_PAGE_SIZE - 1)) & TARGET_PAGE_MASK,
5021
                (unsigned long long)0);
5022
#endif
5023

    
5024
    return 0;
5025
}
5026

    
5027
static int open_self_stat(void *cpu_env, int fd)
5028
{
5029
    TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
5030
    abi_ulong start_stack = ts->info->start_stack;
5031
    int i;
5032

    
5033
    for (i = 0; i < 44; i++) {
5034
      char buf[128];
5035
      int len;
5036
      uint64_t val = 0;
5037

    
5038
      if (i == 0) {
5039
        /* pid */
5040
        val = getpid();
5041
        snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
5042
      } else if (i == 1) {
5043
        /* app name */
5044
        snprintf(buf, sizeof(buf), "(%s) ", ts->bprm->argv[0]);
5045
      } else if (i == 27) {
5046
        /* stack bottom */
5047
        val = start_stack;
5048
        snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
5049
      } else {
5050
        /* for the rest, there is MasterCard */
5051
        snprintf(buf, sizeof(buf), "0%c", i == 43 ? '\n' : ' ');
5052
      }
5053

    
5054
      len = strlen(buf);
5055
      if (write(fd, buf, len) != len) {
5056
          return -1;
5057
      }
5058
    }
5059

    
5060
    return 0;
5061
}
5062

    
5063
static int open_self_auxv(void *cpu_env, int fd)
5064
{
5065
    TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
5066
    abi_ulong auxv = ts->info->saved_auxv;
5067
    abi_ulong len = ts->info->auxv_len;
5068
    char *ptr;
5069

    
5070
    /*
5071
     * Auxiliary vector is stored in target process stack.
5072
     * read in whole auxv vector and copy it to file
5073
     */
5074
    ptr = lock_user(VERIFY_READ, auxv, len, 0);
5075
    if (ptr != NULL) {
5076
        while (len > 0) {
5077
            ssize_t r;
5078
            r = write(fd, ptr, len);
5079
            if (r <= 0) {
5080
                break;
5081
            }
5082
            len -= r;
5083
            ptr += r;
5084
        }
5085
        lseek(fd, 0, SEEK_SET);
5086
        unlock_user(ptr, auxv, len);
5087
    }
5088

    
5089
    return 0;
5090
}
5091

    
5092
static int is_proc_myself(const char *filename, const char *entry)
5093
{
5094
    if (!strncmp(filename, "/proc/", strlen("/proc/"))) {
5095
        filename += strlen("/proc/");
5096
        if (!strncmp(filename, "self/", strlen("self/"))) {
5097
            filename += strlen("self/");
5098
        } else if (*filename >= '1' && *filename <= '9') {
5099
            char myself[80];
5100
            snprintf(myself, sizeof(myself), "%d/", getpid());
5101
            if (!strncmp(filename, myself, strlen(myself))) {
5102
                filename += strlen(myself);
5103
            } else {
5104
                return 0;
5105
            }
5106
        } else {
5107
            return 0;
5108
        }
5109
        if (!strcmp(filename, entry)) {
5110
            return 1;
5111
        }
5112
    }
5113
    return 0;
5114
}
5115

    
5116
#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
5117
static int is_proc(const char *filename, const char *entry)
5118
{
5119
    return strcmp(filename, entry) == 0;
5120
}
5121

    
5122
static int open_net_route(void *cpu_env, int fd)
5123
{
5124
    FILE *fp;
5125
    char *line = NULL;
5126
    size_t len = 0;
5127
    ssize_t read;
5128

    
5129
    fp = fopen("/proc/net/route", "r");
5130
    if (fp == NULL) {
5131
        return -EACCES;
5132
    }
5133

    
5134
    /* read header */
5135

    
5136
    read = getline(&line, &len, fp);
5137
    dprintf(fd, "%s", line);
5138

    
5139
    /* read routes */
5140

    
5141
    while ((read = getline(&line, &len, fp)) != -1) {
5142
        char iface[16];
5143
        uint32_t dest, gw, mask;
5144
        unsigned int flags, refcnt, use, metric, mtu, window, irtt;
5145
        sscanf(line, "%s\t%08x\t%08x\t%04x\t%d\t%d\t%d\t%08x\t%d\t%u\t%u\n",
5146
                     iface, &dest, &gw, &flags, &refcnt, &use, &metric,
5147
                     &mask, &mtu, &window, &irtt);
5148
        dprintf(fd, "%s\t%08x\t%08x\t%04x\t%d\t%d\t%d\t%08x\t%d\t%u\t%u\n",
5149
                iface, tswap32(dest), tswap32(gw), flags, refcnt, use,
5150
                metric, tswap32(mask), mtu, window, irtt);
5151
    }
5152

    
5153
    free(line);
5154
    fclose(fp);
5155

    
5156
    return 0;
5157
}
5158
#endif
5159

    
5160
static int do_open(void *cpu_env, const char *pathname, int flags, mode_t mode)
5161
{
5162
    struct fake_open {
5163
        const char *filename;
5164
        int (*fill)(void *cpu_env, int fd);
5165
        int (*cmp)(const char *s1, const char *s2);
5166
    };
5167
    const struct fake_open *fake_open;
5168
    static const struct fake_open fakes[] = {
5169
        { "maps", open_self_maps, is_proc_myself },
5170
        { "stat", open_self_stat, is_proc_myself },
5171
        { "auxv", open_self_auxv, is_proc_myself },
5172
#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
5173
        { "/proc/net/route", open_net_route, is_proc },
5174
#endif
5175
        { NULL, NULL, NULL }
5176
    };
5177

    
5178
    for (fake_open = fakes; fake_open->filename; fake_open++) {
5179
        if (fake_open->cmp(pathname, fake_open->filename)) {
5180
            break;
5181
        }
5182
    }
5183

    
5184
    if (fake_open->filename) {
5185
        const char *tmpdir;
5186
        char filename[PATH_MAX];
5187
        int fd, r;
5188

    
5189
        /* create temporary file to map stat to */
5190
        tmpdir = getenv("TMPDIR");
5191
        if (!tmpdir)
5192
            tmpdir = "/tmp";
5193
        snprintf(filename, sizeof(filename), "%s/qemu-open.XXXXXX", tmpdir);
5194
        fd = mkstemp(filename);
5195
        if (fd < 0) {
5196
            return fd;
5197
        }
5198
        unlink(filename);
5199

    
5200
        if ((r = fake_open->fill(cpu_env, fd))) {
5201
            close(fd);
5202
            return r;
5203
        }
5204
        lseek(fd, 0, SEEK_SET);
5205

    
5206
        return fd;
5207
    }
5208

    
5209
    return get_errno(open(path(pathname), flags, mode));
5210
}
5211

    
5212
/* do_syscall() should always have a single exit point at the end so
5213
   that actions, such as logging of syscall results, can be performed.
5214
   All errnos that do_syscall() returns must be -TARGET_<errcode>. */
5215
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
5216
                    abi_long arg2, abi_long arg3, abi_long arg4,
5217
                    abi_long arg5, abi_long arg6, abi_long arg7,
5218
                    abi_long arg8)
5219
{
5220
    CPUState *cpu = ENV_GET_CPU(cpu_env);
5221
    abi_long ret;
5222
    struct stat st;
5223
    struct statfs stfs;
5224
    void *p;
5225

    
5226
#ifdef DEBUG
5227
    gemu_log("syscall %d", num);
5228
#endif
5229
    if(do_strace)
5230
        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
5231

    
5232
    switch(num) {
5233
    case TARGET_NR_exit:
5234
        /* In old applications this may be used to implement _exit(2).
5235
           However in threaded applictions it is used for thread termination,
5236
           and _exit_group is used for application termination.
5237
           Do thread termination if we have more then one thread.  */
5238
        /* FIXME: This probably breaks if a signal arrives.  We should probably
5239
           be disabling signals.  */
5240
        if (CPU_NEXT(first_cpu)) {
5241
            TaskState *ts;
5242

    
5243
            cpu_list_lock();
5244
            /* Remove the CPU from the list.  */
5245
            QTAILQ_REMOVE(&cpus, cpu, node);
5246
            cpu_list_unlock();
5247
            ts = ((CPUArchState *)cpu_env)->opaque;
5248
            if (ts->child_tidptr) {
5249
                put_user_u32(0, ts->child_tidptr);
5250
                sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
5251
                          NULL, NULL, 0);
5252
            }
5253
            thread_cpu = NULL;
5254
            object_unref(OBJECT(ENV_GET_CPU(cpu_env)));
5255
            g_free(ts);
5256
            pthread_exit(NULL);
5257
        }
5258
#ifdef TARGET_GPROF
5259
        _mcleanup();
5260
#endif
5261
        gdb_exit(cpu_env, arg1);
5262
        _exit(arg1);
5263
        ret = 0; /* avoid warning */
5264
        break;
5265
    case TARGET_NR_read:
5266
        if (arg3 == 0)
5267
            ret = 0;
5268
        else {
5269
            if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5270
                goto efault;
5271
            ret = get_errno(read(arg1, p, arg3));
5272
            unlock_user(p, arg2, ret);
5273
        }
5274
        break;
5275
    case TARGET_NR_write:
5276
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5277
            goto efault;
5278
        ret = get_errno(write(arg1, p, arg3));
5279
        unlock_user(p, arg2, 0);
5280
        break;
5281
    case TARGET_NR_open:
5282
        if (!(p = lock_user_string(arg1)))
5283
            goto efault;
5284
        ret = get_errno(do_open(cpu_env, p,
5285
                                target_to_host_bitmask(arg2, fcntl_flags_tbl),
5286
                                arg3));
5287
        unlock_user(p, arg1, 0);
5288
        break;
5289
#if defined(TARGET_NR_openat) && defined(__NR_openat)
5290
    case TARGET_NR_openat:
5291
        if (!(p = lock_user_string(arg2)))
5292
            goto efault;
5293
        ret = get_errno(sys_openat(arg1,
5294
                                   path(p),
5295
                                   target_to_host_bitmask(arg3, fcntl_flags_tbl),
5296
                                   arg4));
5297
        unlock_user(p, arg2, 0);
5298
        break;
5299
#endif
5300
    case TARGET_NR_close:
5301
        ret = get_errno(close(arg1));
5302
        break;
5303
    case TARGET_NR_brk:
5304
        ret = do_brk(arg1);
5305
        break;
5306
    case TARGET_NR_fork:
5307
        ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
5308
        break;
5309
#ifdef TARGET_NR_waitpid
5310
    case TARGET_NR_waitpid:
5311
        {
5312
            int status;
5313
            ret = get_errno(waitpid(arg1, &status, arg3));
5314
            if (!is_error(ret) && arg2 && ret
5315
                && put_user_s32(host_to_target_waitstatus(status), arg2))
5316
                goto efault;
5317
        }
5318
        break;
5319
#endif
5320
#ifdef TARGET_NR_waitid
5321
    case TARGET_NR_waitid:
5322
        {
5323
            siginfo_t info;
5324
            info.si_pid = 0;
5325
            ret = get_errno(waitid(arg1, arg2, &info, arg4));
5326
            if (!is_error(ret) && arg3 && info.si_pid != 0) {
5327
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
5328
                    goto efault;
5329
                host_to_target_siginfo(p, &info);
5330
                unlock_user(p, arg3, sizeof(target_siginfo_t));
5331
            }
5332
        }
5333
        break;
5334
#endif
5335
#ifdef TARGET_NR_creat /* not on alpha */
5336
    case TARGET_NR_creat:
5337
        if (!(p = lock_user_string(arg1)))
5338
            goto efault;
5339
        ret = get_errno(creat(p, arg2));
5340
        unlock_user(p, arg1, 0);
5341
        break;
5342
#endif
5343
    case TARGET_NR_link:
5344
        {
5345
            void * p2;
5346
            p = lock_user_string(arg1);
5347
            p2 = lock_user_string(arg2);
5348
            if (!p || !p2)
5349
                ret = -TARGET_EFAULT;
5350
            else
5351
                ret = get_errno(link(p, p2));
5352
            unlock_user(p2, arg2, 0);
5353
            unlock_user(p, arg1, 0);
5354
        }
5355
        break;
5356
#if defined(TARGET_NR_linkat)
5357
    case TARGET_NR_linkat:
5358
        {
5359
            void * p2 = NULL;
5360
            if (!arg2 || !arg4)
5361
                goto efault;
5362
            p  = lock_user_string(arg2);
5363
            p2 = lock_user_string(arg4);
5364
            if (!p || !p2)
5365
                ret = -TARGET_EFAULT;
5366
            else
5367
                ret = get_errno(linkat(arg1, p, arg3, p2, arg5));
5368
            unlock_user(p, arg2, 0);
5369
            unlock_user(p2, arg4, 0);
5370
        }
5371
        break;
5372
#endif
5373
    case TARGET_NR_unlink:
5374
        if (!(p = lock_user_string(arg1)))
5375
            goto efault;
5376
        ret = get_errno(unlink(p));
5377
        unlock_user(p, arg1, 0);
5378
        break;
5379
#if defined(TARGET_NR_unlinkat)
5380
    case TARGET_NR_unlinkat:
5381
        if (!(p = lock_user_string(arg2)))
5382
            goto efault;
5383
        ret = get_errno(unlinkat(arg1, p, arg3));
5384
        unlock_user(p, arg2, 0);
5385
        break;
5386
#endif
5387
    case TARGET_NR_execve:
5388
        {
5389
            char **argp, **envp;
5390
            int argc, envc;
5391
            abi_ulong gp;
5392
            abi_ulong guest_argp;
5393
            abi_ulong guest_envp;
5394
            abi_ulong addr;
5395
            char **q;
5396
            int total_size = 0;
5397

    
5398
            argc = 0;
5399
            guest_argp = arg2;
5400
            for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
5401
                if (get_user_ual(addr, gp))
5402
                    goto efault;
5403
                if (!addr)
5404
                    break;
5405
                argc++;
5406
            }
5407
            envc = 0;
5408
            guest_envp = arg3;
5409
            for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
5410
                if (get_user_ual(addr, gp))
5411
                    goto efault;
5412
                if (!addr)
5413
                    break;
5414
                envc++;
5415
            }
5416

    
5417
            argp = alloca((argc + 1) * sizeof(void *));
5418
            envp = alloca((envc + 1) * sizeof(void *));
5419

    
5420
            for (gp = guest_argp, q = argp; gp;
5421
                  gp += sizeof(abi_ulong), q++) {
5422
                if (get_user_ual(addr, gp))
5423
                    goto execve_efault;
5424
                if (!addr)
5425
                    break;
5426
                if (!(*q = lock_user_string(addr)))
5427
                    goto execve_efault;
5428
                total_size += strlen(*q) + 1;
5429
            }
5430
            *q = NULL;
5431

    
5432
            for (gp = guest_envp, q = envp; gp;
5433
                  gp += sizeof(abi_ulong), q++) {
5434
                if (get_user_ual(addr, gp))
5435
                    goto execve_efault;
5436
                if (!addr)
5437
                    break;
5438
                if (!(*q = lock_user_string(addr)))
5439
                    goto execve_efault;
5440
                total_size += strlen(*q) + 1;
5441
            }
5442
            *q = NULL;
5443

    
5444
            /* This case will not be caught by the host's execve() if its
5445
               page size is bigger than the target's. */
5446
            if (total_size > MAX_ARG_PAGES * TARGET_PAGE_SIZE) {
5447
                ret = -TARGET_E2BIG;
5448
                goto execve_end;
5449
            }
5450
            if (!(p = lock_user_string(arg1)))
5451
                goto execve_efault;
5452
            ret = get_errno(execve(p, argp, envp));
5453
            unlock_user(p, arg1, 0);
5454

    
5455
            goto execve_end;
5456

    
5457
        execve_efault:
5458
            ret = -TARGET_EFAULT;
5459

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

    
5881
            if (arg2) {
5882
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
5883
                    goto efault;
5884
                act._sa_handler = old_act->_sa_handler;
5885
                target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
5886
                act.sa_flags = old_act->sa_flags;
5887
                unlock_user_struct(old_act, arg2, 0);
5888
                pact = &act;
5889
            } else {
5890
                pact = NULL;
5891
            }
5892

    
5893
            ret = get_errno(do_sigaction(arg1, pact, &oact));
5894

    
5895
            if (!is_error(ret) && arg3) {
5896
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
5897
                    goto efault;
5898
                old_act->_sa_handler = oact._sa_handler;
5899
                old_act->sa_flags = oact.sa_flags;
5900
                old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
5901
                old_act->sa_mask.sig[1] = 0;
5902
                old_act->sa_mask.sig[2] = 0;
5903
                old_act->sa_mask.sig[3] = 0;
5904
                unlock_user_struct(old_act, arg3, 1);
5905
            }
5906
#else
5907
            struct target_old_sigaction *old_act;
5908
            struct target_sigaction act, oact, *pact;
5909
            if (arg2) {
5910
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
5911
                    goto efault;
5912
                act._sa_handler = old_act->_sa_handler;
5913
                target_siginitset(&act.sa_mask, old_act->sa_mask);
5914
                act.sa_flags = old_act->sa_flags;
5915
                act.sa_restorer = old_act->sa_restorer;
5916
                unlock_user_struct(old_act, arg2, 0);
5917
                pact = &act;
5918
            } else {
5919
                pact = NULL;
5920
            }
5921
            ret = get_errno(do_sigaction(arg1, pact, &oact));
5922
            if (!is_error(ret) && arg3) {
5923
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
5924
                    goto efault;
5925
                old_act->_sa_handler = oact._sa_handler;
5926
                old_act->sa_mask = oact.sa_mask.sig[0];
5927
                old_act->sa_flags = oact.sa_flags;
5928
                old_act->sa_restorer = oact.sa_restorer;
5929
                unlock_user_struct(old_act, arg3, 1);
5930
            }
5931
#endif
5932
        }
5933
        break;
5934
#endif
5935
    case TARGET_NR_rt_sigaction:
5936
        {
5937
#if defined(TARGET_ALPHA)
5938
            struct target_sigaction act, oact, *pact = 0;
5939
            struct target_rt_sigaction *rt_act;
5940
            /* ??? arg4 == sizeof(sigset_t).  */
5941
            if (arg2) {
5942
                if (!lock_user_struct(VERIFY_READ, rt_act, arg2, 1))
5943
                    goto efault;
5944
                act._sa_handler = rt_act->_sa_handler;
5945
                act.sa_mask = rt_act->sa_mask;
5946
                act.sa_flags = rt_act->sa_flags;
5947
                act.sa_restorer = arg5;
5948
                unlock_user_struct(rt_act, arg2, 0);
5949
                pact = &act;
5950
            }
5951
            ret = get_errno(do_sigaction(arg1, pact, &oact));
5952
            if (!is_error(ret) && arg3) {
5953
                if (!lock_user_struct(VERIFY_WRITE, rt_act, arg3, 0))
5954
                    goto efault;
5955
                rt_act->_sa_handler = oact._sa_handler;
5956
                rt_act->sa_mask = oact.sa_mask;
5957
                rt_act->sa_flags = oact.sa_flags;
5958
                unlock_user_struct(rt_act, arg3, 1);
5959
            }
5960
#else
5961
            struct target_sigaction *act;
5962
            struct target_sigaction *oact;
5963

    
5964
            if (arg2) {
5965
                if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
5966
                    goto efault;
5967
            } else
5968
                act = NULL;
5969
            if (arg3) {
5970
                if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
5971
                    ret = -TARGET_EFAULT;
5972
                    goto rt_sigaction_fail;
5973
                }
5974
            } else
5975
                oact = NULL;
5976
            ret = get_errno(do_sigaction(arg1, act, oact));
5977
        rt_sigaction_fail:
5978
            if (act)
5979
                unlock_user_struct(act, arg2, 0);
5980
            if (oact)
5981
                unlock_user_struct(oact, arg3, 1);
5982
#endif
5983
        }
5984
        break;
5985
#ifdef TARGET_NR_sgetmask /* not on alpha */
5986
    case TARGET_NR_sgetmask:
5987
        {
5988
            sigset_t cur_set;
5989
            abi_ulong target_set;
5990
            sigprocmask(0, NULL, &cur_set);
5991
            host_to_target_old_sigset(&target_set, &cur_set);
5992
            ret = target_set;
5993
        }
5994
        break;
5995
#endif
5996
#ifdef TARGET_NR_ssetmask /* not on alpha */
5997
    case TARGET_NR_ssetmask:
5998
        {
5999
            sigset_t set, oset, cur_set;
6000
            abi_ulong target_set = arg1;
6001
            sigprocmask(0, NULL, &cur_set);
6002
            target_to_host_old_sigset(&set, &target_set);
6003
            sigorset(&set, &set, &cur_set);
6004
            sigprocmask(SIG_SETMASK, &set, &oset);
6005
            host_to_target_old_sigset(&target_set, &oset);
6006
            ret = target_set;
6007
        }
6008
        break;
6009
#endif
6010
#ifdef TARGET_NR_sigprocmask
6011
    case TARGET_NR_sigprocmask:
6012
        {
6013
#if defined(TARGET_ALPHA)
6014
            sigset_t set, oldset;
6015
            abi_ulong mask;
6016
            int how;
6017

    
6018
            switch (arg1) {
6019
            case TARGET_SIG_BLOCK:
6020
                how = SIG_BLOCK;
6021
                break;
6022
            case TARGET_SIG_UNBLOCK:
6023
                how = SIG_UNBLOCK;
6024
                break;
6025
            case TARGET_SIG_SETMASK:
6026
                how = SIG_SETMASK;
6027
                break;
6028
            default:
6029
                ret = -TARGET_EINVAL;
6030
                goto fail;
6031
            }
6032
            mask = arg2;
6033
            target_to_host_old_sigset(&set, &mask);
6034

    
6035
            ret = get_errno(sigprocmask(how, &set, &oldset));
6036
            if (!is_error(ret)) {
6037
                host_to_target_old_sigset(&mask, &oldset);
6038
                ret = mask;
6039
                ((CPUAlphaState *)cpu_env)->ir[IR_V0] = 0; /* force no error */
6040
            }
6041
#else
6042
            sigset_t set, oldset, *set_ptr;
6043
            int how;
6044

    
6045
            if (arg2) {
6046
                switch (arg1) {
6047
                case TARGET_SIG_BLOCK:
6048
                    how = SIG_BLOCK;
6049
                    break;
6050
                case TARGET_SIG_UNBLOCK:
6051
                    how = SIG_UNBLOCK;
6052
                    break;
6053
                case TARGET_SIG_SETMASK:
6054
                    how = SIG_SETMASK;
6055
                    break;
6056
                default:
6057
                    ret = -TARGET_EINVAL;
6058
                    goto fail;
6059
                }
6060
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
6061
                    goto efault;
6062
                target_to_host_old_sigset(&set, p);
6063
                unlock_user(p, arg2, 0);
6064
                set_ptr = &set;
6065
            } else {
6066
                how = 0;
6067
                set_ptr = NULL;
6068
            }
6069
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
6070
            if (!is_error(ret) && arg3) {
6071
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
6072
                    goto efault;
6073
                host_to_target_old_sigset(p, &oldset);
6074
                unlock_user(p, arg3, sizeof(target_sigset_t));
6075
            }
6076
#endif
6077
        }
6078
        break;
6079
#endif
6080
    case TARGET_NR_rt_sigprocmask:
6081
        {
6082
            int how = arg1;
6083
            sigset_t set, oldset, *set_ptr;
6084

    
6085
            if (arg2) {
6086
                switch(how) {
6087
                case TARGET_SIG_BLOCK:
6088
                    how = SIG_BLOCK;
6089
                    break;
6090
                case TARGET_SIG_UNBLOCK:
6091
                    how = SIG_UNBLOCK;
6092
                    break;
6093
                case TARGET_SIG_SETMASK:
6094
                    how = SIG_SETMASK;
6095
                    break;
6096
                default:
6097
                    ret = -TARGET_EINVAL;
6098
                    goto fail;
6099
                }
6100
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
6101
                    goto efault;
6102
                target_to_host_sigset(&set, p);
6103
                unlock_user(p, arg2, 0);
6104
                set_ptr = &set;
6105
            } else {
6106
                how = 0;
6107
                set_ptr = NULL;
6108
            }
6109
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
6110
            if (!is_error(ret) && arg3) {
6111
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
6112
                    goto efault;
6113
                host_to_target_sigset(p, &oldset);
6114
                unlock_user(p, arg3, sizeof(target_sigset_t));
6115
            }
6116
        }
6117
        break;
6118
#ifdef TARGET_NR_sigpending
6119
    case TARGET_NR_sigpending:
6120
        {
6121
            sigset_t set;
6122
            ret = get_errno(sigpending(&set));
6123
            if (!is_error(ret)) {
6124
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
6125
                    goto efault;
6126
                host_to_target_old_sigset(p, &set);
6127
                unlock_user(p, arg1, sizeof(target_sigset_t));
6128
            }
6129
        }
6130
        break;
6131
#endif
6132
    case TARGET_NR_rt_sigpending:
6133
        {
6134
            sigset_t set;
6135
            ret = get_errno(sigpending(&set));
6136
            if (!is_error(ret)) {
6137
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
6138
                    goto efault;
6139
                host_to_target_sigset(p, &set);
6140
                unlock_user(p, arg1, sizeof(target_sigset_t));
6141
            }
6142
        }
6143
        break;
6144
#ifdef TARGET_NR_sigsuspend
6145
    case TARGET_NR_sigsuspend:
6146
        {
6147
            sigset_t set;
6148
#if defined(TARGET_ALPHA)
6149
            abi_ulong mask = arg1;
6150
            target_to_host_old_sigset(&set, &mask);
6151
#else
6152
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
6153
                goto efault;
6154
            target_to_host_old_sigset(&set, p);
6155
            unlock_user(p, arg1, 0);
6156
#endif
6157
            ret = get_errno(sigsuspend(&set));
6158
        }
6159
        break;
6160
#endif
6161
    case TARGET_NR_rt_sigsuspend:
6162
        {
6163
            sigset_t set;
6164
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
6165
                goto efault;
6166
            target_to_host_sigset(&set, p);
6167
            unlock_user(p, arg1, 0);
6168
            ret = get_errno(sigsuspend(&set));
6169
        }
6170
        break;
6171
    case TARGET_NR_rt_sigtimedwait:
6172
        {
6173
            sigset_t set;
6174
            struct timespec uts, *puts;
6175
            siginfo_t uinfo;
6176

    
6177
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
6178
                goto efault;
6179
            target_to_host_sigset(&set, p);
6180
            unlock_user(p, arg1, 0);
6181
            if (arg3) {
6182
                puts = &uts;
6183
                target_to_host_timespec(puts, arg3);
6184
            } else {
6185
                puts = NULL;
6186
            }
6187
            ret = get_errno(sigtimedwait(&set, &uinfo, puts));
6188
            if (!is_error(ret) && arg2) {
6189
                if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
6190
                    goto efault;
6191
                host_to_target_siginfo(p, &uinfo);
6192
                unlock_user(p, arg2, sizeof(target_siginfo_t));
6193
            }
6194
        }
6195
        break;
6196
    case TARGET_NR_rt_sigqueueinfo:
6197
        {
6198
            siginfo_t uinfo;
6199
            if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
6200
                goto efault;
6201
            target_to_host_siginfo(&uinfo, p);
6202
            unlock_user(p, arg1, 0);
6203
            ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
6204
        }
6205
        break;
6206
#ifdef TARGET_NR_sigreturn
6207
    case TARGET_NR_sigreturn:
6208
        /* NOTE: ret is eax, so not transcoding must be done */
6209
        ret = do_sigreturn(cpu_env);
6210
        break;
6211
#endif
6212
    case TARGET_NR_rt_sigreturn:
6213
        /* NOTE: ret is eax, so not transcoding must be done */
6214
        ret = do_rt_sigreturn(cpu_env);
6215
        break;
6216
    case TARGET_NR_sethostname:
6217
        if (!(p = lock_user_string(arg1)))
6218
            goto efault;
6219
        ret = get_errno(sethostname(p, arg2));
6220
        unlock_user(p, arg1, 0);
6221
        break;
6222
    case TARGET_NR_setrlimit:
6223
        {
6224
            int resource = target_to_host_resource(arg1);
6225
            struct target_rlimit *target_rlim;
6226
            struct rlimit rlim;
6227
            if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
6228
                goto efault;
6229
            rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur);
6230
            rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max);
6231
            unlock_user_struct(target_rlim, arg2, 0);
6232
            ret = get_errno(setrlimit(resource, &rlim));
6233
        }
6234
        break;
6235
    case TARGET_NR_getrlimit:
6236
        {
6237
            int resource = target_to_host_resource(arg1);
6238
            struct target_rlimit *target_rlim;
6239
            struct rlimit rlim;
6240

    
6241
            ret = get_errno(getrlimit(resource, &rlim));
6242
            if (!is_error(ret)) {
6243
                if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
6244
                    goto efault;
6245
                target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
6246
                target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
6247
                unlock_user_struct(target_rlim, arg2, 1);
6248
            }
6249
        }
6250
        break;
6251
    case TARGET_NR_getrusage:
6252
        {
6253
            struct rusage rusage;
6254
            ret = get_errno(getrusage(arg1, &rusage));
6255
            if (!is_error(ret)) {
6256
                host_to_target_rusage(arg2, &rusage);
6257
            }
6258
        }
6259
        break;
6260
    case TARGET_NR_gettimeofday:
6261
        {
6262
            struct timeval tv;
6263
            ret = get_errno(gettimeofday(&tv, NULL));
6264
            if (!is_error(ret)) {
6265
                if (copy_to_user_timeval(arg1, &tv))
6266
                    goto efault;
6267
            }
6268
        }
6269
        break;
6270
    case TARGET_NR_settimeofday:
6271
        {
6272
            struct timeval tv;
6273
            if (copy_from_user_timeval(&tv, arg1))
6274
                goto efault;
6275
            ret = get_errno(settimeofday(&tv, NULL));
6276
        }
6277
        break;
6278
#if defined(TARGET_NR_select)
6279
    case TARGET_NR_select:
6280
#if defined(TARGET_S390X) || defined(TARGET_ALPHA)
6281
        ret = do_select(arg1, arg2, arg3, arg4, arg5);
6282
#else
6283
        {
6284
            struct target_sel_arg_struct *sel;
6285
            abi_ulong inp, outp, exp, tvp;
6286
            long nsel;
6287

    
6288
            if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
6289
                goto efault;
6290
            nsel = tswapal(sel->n);
6291
            inp = tswapal(sel->inp);
6292
            outp = tswapal(sel->outp);
6293
            exp = tswapal(sel->exp);
6294
            tvp = tswapal(sel->tvp);
6295
            unlock_user_struct(sel, arg1, 0);
6296
            ret = do_select(nsel, inp, outp, exp, tvp);
6297
        }
6298
#endif
6299
        break;
6300
#endif
6301
#ifdef TARGET_NR_pselect6
6302
    case TARGET_NR_pselect6:
6303
        {
6304
            abi_long rfd_addr, wfd_addr, efd_addr, n, ts_addr;
6305
            fd_set rfds, wfds, efds;
6306
            fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
6307
            struct timespec ts, *ts_ptr;
6308

    
6309
            /*
6310
             * The 6th arg is actually two args smashed together,
6311
             * so we cannot use the C library.
6312
             */
6313
            sigset_t set;
6314
            struct {
6315
                sigset_t *set;
6316
                size_t size;
6317
            } sig, *sig_ptr;
6318

    
6319
            abi_ulong arg_sigset, arg_sigsize, *arg7;
6320
            target_sigset_t *target_sigset;
6321

    
6322
            n = arg1;
6323
            rfd_addr = arg2;
6324
            wfd_addr = arg3;
6325
            efd_addr = arg4;
6326
            ts_addr = arg5;
6327

    
6328
            ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
6329
            if (ret) {
6330
                goto fail;
6331
            }
6332
            ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
6333
            if (ret) {
6334
                goto fail;
6335
            }
6336
            ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
6337
            if (ret) {
6338
                goto fail;
6339
            }
6340

    
6341
            /*
6342
             * This takes a timespec, and not a timeval, so we cannot
6343
             * use the do_select() helper ...
6344
             */
6345
            if (ts_addr) {
6346
                if (target_to_host_timespec(&ts, ts_addr)) {
6347
                    goto efault;
6348
                }
6349
                ts_ptr = &ts;
6350
            } else {
6351
                ts_ptr = NULL;
6352
            }
6353

    
6354
            /* Extract the two packed args for the sigset */
6355
            if (arg6) {
6356
                sig_ptr = &sig;
6357
                sig.size = _NSIG / 8;
6358

    
6359
                arg7 = lock_user(VERIFY_READ, arg6, sizeof(*arg7) * 2, 1);
6360
                if (!arg7) {
6361
                    goto efault;
6362
                }
6363
                arg_sigset = tswapal(arg7[0]);
6364
                arg_sigsize = tswapal(arg7[1]);
6365
                unlock_user(arg7, arg6, 0);
6366

    
6367
                if (arg_sigset) {
6368
                    sig.set = &set;
6369
                    if (arg_sigsize != sizeof(*target_sigset)) {
6370
                        /* Like the kernel, we enforce correct size sigsets */
6371
                        ret = -TARGET_EINVAL;
6372
                        goto fail;
6373
                    }
6374
                    target_sigset = lock_user(VERIFY_READ, arg_sigset,
6375
                                              sizeof(*target_sigset), 1);
6376
                    if (!target_sigset) {
6377
                        goto efault;
6378
                    }
6379
                    target_to_host_sigset(&set, target_sigset);
6380
                    unlock_user(target_sigset, arg_sigset, 0);
6381
                } else {
6382
                    sig.set = NULL;
6383
                }
6384
            } else {
6385
                sig_ptr = NULL;
6386
            }
6387

    
6388
            ret = get_errno(sys_pselect6(n, rfds_ptr, wfds_ptr, efds_ptr,
6389
                                         ts_ptr, sig_ptr));
6390

    
6391
            if (!is_error(ret)) {
6392
                if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
6393
                    goto efault;
6394
                if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
6395
                    goto efault;
6396
                if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
6397
                    goto efault;
6398

    
6399
                if (ts_addr && host_to_target_timespec(ts_addr, &ts))
6400
                    goto efault;
6401
            }
6402
        }
6403
        break;
6404
#endif
6405
    case TARGET_NR_symlink:
6406
        {
6407
            void *p2;
6408
            p = lock_user_string(arg1);
6409
            p2 = lock_user_string(arg2);
6410
            if (!p || !p2)
6411
                ret = -TARGET_EFAULT;
6412
            else
6413
                ret = get_errno(symlink(p, p2));
6414
            unlock_user(p2, arg2, 0);
6415
            unlock_user(p, arg1, 0);
6416
        }
6417
        break;
6418
#if defined(TARGET_NR_symlinkat)
6419
    case TARGET_NR_symlinkat:
6420
        {
6421
            void *p2;
6422
            p  = lock_user_string(arg1);
6423
            p2 = lock_user_string(arg3);
6424
            if (!p || !p2)
6425
                ret = -TARGET_EFAULT;
6426
            else
6427
                ret = get_errno(symlinkat(p, arg2, p2));
6428
            unlock_user(p2, arg3, 0);
6429
            unlock_user(p, arg1, 0);
6430
        }
6431
        break;
6432
#endif
6433
#ifdef TARGET_NR_oldlstat
6434
    case TARGET_NR_oldlstat:
6435
        goto unimplemented;
6436
#endif
6437
    case TARGET_NR_readlink:
6438
        {
6439
            void *p2;
6440
            p = lock_user_string(arg1);
6441
            p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
6442
            if (!p || !p2) {
6443
                ret = -TARGET_EFAULT;
6444
            } else if (is_proc_myself((const char *)p, "exe")) {
6445
                char real[PATH_MAX], *temp;
6446
                temp = realpath(exec_path, real);
6447
                ret = temp == NULL ? get_errno(-1) : strlen(real) ;
6448
                snprintf((char *)p2, arg3, "%s", real);
6449
            } else {
6450
                ret = get_errno(readlink(path(p), p2, arg3));
6451
            }
6452
            unlock_user(p2, arg2, ret);
6453
            unlock_user(p, arg1, 0);
6454
        }
6455
        break;
6456
#if defined(TARGET_NR_readlinkat)
6457
    case TARGET_NR_readlinkat:
6458
        {
6459
            void *p2;
6460
            p  = lock_user_string(arg2);
6461
            p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
6462
            if (!p || !p2) {
6463
                ret = -TARGET_EFAULT;
6464
            } else if (is_proc_myself((const char *)p, "exe")) {
6465
                char real[PATH_MAX], *temp;
6466
                temp = realpath(exec_path, real);
6467
                ret = temp == NULL ? get_errno(-1) : strlen(real) ;
6468
                snprintf((char *)p2, arg4, "%s", real);
6469
            } else {
6470
                ret = get_errno(readlinkat(arg1, path(p), p2, arg4));
6471
            }
6472
            unlock_user(p2, arg3, ret);
6473
            unlock_user(p, arg2, 0);
6474
        }
6475
        break;
6476
#endif
6477
#ifdef TARGET_NR_uselib
6478
    case TARGET_NR_uselib:
6479
        goto unimplemented;
6480
#endif
6481
#ifdef TARGET_NR_swapon
6482
    case TARGET_NR_swapon:
6483
        if (!(p = lock_user_string(arg1)))
6484
            goto efault;
6485
        ret = get_errno(swapon(p, arg2));
6486
        unlock_user(p, arg1, 0);
6487
        break;
6488
#endif
6489
    case TARGET_NR_reboot:
6490
        if (arg3 == LINUX_REBOOT_CMD_RESTART2) {
6491
           /* arg4 must be ignored in all other cases */
6492
           p = lock_user_string(arg4);
6493
           if (!p) {
6494
              goto efault;
6495
           }
6496
           ret = get_errno(reboot(arg1, arg2, arg3, p));
6497
           unlock_user(p, arg4, 0);
6498
        } else {
6499
           ret = get_errno(reboot(arg1, arg2, arg3, NULL));
6500
        }
6501
        break;
6502
#ifdef TARGET_NR_readdir
6503
    case TARGET_NR_readdir:
6504
        goto unimplemented;
6505
#endif
6506
#ifdef TARGET_NR_mmap
6507
    case TARGET_NR_mmap:
6508
#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || \
6509
    (defined(TARGET_ARM) && defined(TARGET_ABI32)) || \
6510
    defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) \
6511
    || defined(TARGET_S390X)
6512
        {
6513
            abi_ulong *v;
6514
            abi_ulong v1, v2, v3, v4, v5, v6;
6515
            if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
6516
                goto efault;
6517
            v1 = tswapal(v[0]);
6518
            v2 = tswapal(v[1]);
6519
            v3 = tswapal(v[2]);
6520
            v4 = tswapal(v[3]);
6521
            v5 = tswapal(v[4]);
6522
            v6 = tswapal(v[5]);
6523
            unlock_user(v, arg1, 0);
6524
            ret = get_errno(target_mmap(v1, v2, v3,
6525
                                        target_to_host_bitmask(v4, mmap_flags_tbl),
6526
                                        v5, v6));
6527
        }
6528
#else
6529
        ret = get_errno(target_mmap(arg1, arg2, arg3,
6530
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
6531
                                    arg5,
6532
                                    arg6));
6533
#endif
6534
        break;
6535
#endif
6536
#ifdef TARGET_NR_mmap2
6537
    case TARGET_NR_mmap2:
6538
#ifndef MMAP_SHIFT
6539
#define MMAP_SHIFT 12
6540
#endif
6541
        ret = get_errno(target_mmap(arg1, arg2, arg3,
6542
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
6543
                                    arg5,
6544
                                    arg6 << MMAP_SHIFT));
6545
        break;
6546
#endif
6547
    case TARGET_NR_munmap:
6548
        ret = get_errno(target_munmap(arg1, arg2));
6549
        break;
6550
    case TARGET_NR_mprotect:
6551
        {
6552
            TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
6553
            /* Special hack to detect libc making the stack executable.  */
6554
            if ((arg3 & PROT_GROWSDOWN)
6555
                && arg1 >= ts->info->stack_limit
6556
                && arg1 <= ts->info->start_stack) {
6557
                arg3 &= ~PROT_GROWSDOWN;
6558
                arg2 = arg2 + arg1 - ts->info->stack_limit;
6559
                arg1 = ts->info->stack_limit;
6560
            }
6561
        }
6562
        ret = get_errno(target_mprotect(arg1, arg2, arg3));
6563
        break;
6564
#ifdef TARGET_NR_mremap
6565
    case TARGET_NR_mremap:
6566
        ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
6567
        break;
6568
#endif
6569
        /* ??? msync/mlock/munlock are broken for softmmu.  */
6570
#ifdef TARGET_NR_msync
6571
    case TARGET_NR_msync:
6572
        ret = get_errno(msync(g2h(arg1), arg2, arg3));
6573
        break;
6574
#endif
6575
#ifdef TARGET_NR_mlock
6576
    case TARGET_NR_mlock:
6577
        ret = get_errno(mlock(g2h(arg1), arg2));
6578
        break;
6579
#endif
6580
#ifdef TARGET_NR_munlock
6581
    case TARGET_NR_munlock:
6582
        ret = get_errno(munlock(g2h(arg1), arg2));
6583
        break;
6584
#endif
6585
#ifdef TARGET_NR_mlockall
6586
    case TARGET_NR_mlockall:
6587
        ret = get_errno(mlockall(arg1));
6588
        break;
6589
#endif
6590
#ifdef TARGET_NR_munlockall
6591
    case TARGET_NR_munlockall:
6592
        ret = get_errno(munlockall());
6593
        break;
6594
#endif
6595
    case TARGET_NR_truncate:
6596
        if (!(p = lock_user_string(arg1)))
6597
            goto efault;
6598
        ret = get_errno(truncate(p, arg2));
6599
        unlock_user(p, arg1, 0);
6600
        break;
6601
    case TARGET_NR_ftruncate:
6602
        ret = get_errno(ftruncate(arg1, arg2));
6603
        break;
6604
    case TARGET_NR_fchmod:
6605
        ret = get_errno(fchmod(arg1, arg2));
6606
        break;
6607
#if defined(TARGET_NR_fchmodat)
6608
    case TARGET_NR_fchmodat:
6609
        if (!(p = lock_user_string(arg2)))
6610
            goto efault;
6611
        ret = get_errno(fchmodat(arg1, p, arg3, 0));
6612
        unlock_user(p, arg2, 0);
6613
        break;
6614
#endif
6615
    case TARGET_NR_getpriority:
6616
        /* Note that negative values are valid for getpriority, so we must
6617
           differentiate based on errno settings.  */
6618
        errno = 0;
6619
        ret = getpriority(arg1, arg2);
6620
        if (ret == -1 && errno != 0) {
6621
            ret = -host_to_target_errno(errno);
6622
            break;
6623
        }
6624
#ifdef TARGET_ALPHA
6625
        /* Return value is the unbiased priority.  Signal no error.  */
6626
        ((CPUAlphaState *)cpu_env)->ir[IR_V0] = 0;
6627
#else
6628
        /* Return value is a biased priority to avoid negative numbers.  */
6629
        ret = 20 - ret;
6630
#endif
6631
        break;
6632
    case TARGET_NR_setpriority:
6633
        ret = get_errno(setpriority(arg1, arg2, arg3));
6634
        break;
6635
#ifdef TARGET_NR_profil
6636
    case TARGET_NR_profil:
6637
        goto unimplemented;
6638
#endif
6639
    case TARGET_NR_statfs:
6640
        if (!(p = lock_user_string(arg1)))
6641
            goto efault;
6642
        ret = get_errno(statfs(path(p), &stfs));
6643
        unlock_user(p, arg1, 0);
6644
    convert_statfs:
6645
        if (!is_error(ret)) {
6646
            struct target_statfs *target_stfs;
6647

    
6648
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
6649
                goto efault;
6650
            __put_user(stfs.f_type, &target_stfs->f_type);
6651
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
6652
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
6653
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
6654
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
6655
            __put_user(stfs.f_files, &target_stfs->f_files);
6656
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
6657
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
6658
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
6659
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
6660
            __put_user(stfs.f_frsize, &target_stfs->f_frsize);
6661
            memset(target_stfs->f_spare, 0, sizeof(target_stfs->f_spare));
6662
            unlock_user_struct(target_stfs, arg2, 1);
6663
        }
6664
        break;
6665
    case TARGET_NR_fstatfs:
6666
        ret = get_errno(fstatfs(arg1, &stfs));
6667
        goto convert_statfs;
6668
#ifdef TARGET_NR_statfs64
6669
    case TARGET_NR_statfs64:
6670
        if (!(p = lock_user_string(arg1)))
6671
            goto efault;
6672
        ret = get_errno(statfs(path(p), &stfs));
6673
        unlock_user(p, arg1, 0);
6674
    convert_statfs64:
6675
        if (!is_error(ret)) {
6676
            struct target_statfs64 *target_stfs;
6677

    
6678
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
6679
                goto efault;
6680
            __put_user(stfs.f_type, &target_stfs->f_type);
6681
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
6682
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
6683
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
6684
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
6685
            __put_user(stfs.f_files, &target_stfs->f_files);
6686
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
6687
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
6688
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
6689
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
6690
            __put_user(stfs.f_frsize, &target_stfs->f_frsize);
6691
            memset(target_stfs->f_spare, 0, sizeof(target_stfs->f_spare));
6692
            unlock_user_struct(target_stfs, arg3, 1);
6693
        }
6694
        break;
6695
    case TARGET_NR_fstatfs64:
6696
        ret = get_errno(fstatfs(arg1, &stfs));
6697
        goto convert_statfs64;
6698
#endif
6699
#ifdef TARGET_NR_ioperm
6700
    case TARGET_NR_ioperm:
6701
        goto unimplemented;
6702
#endif
6703
#ifdef TARGET_NR_socketcall
6704
    case TARGET_NR_socketcall:
6705
        ret = do_socketcall(arg1, arg2);
6706
        break;
6707
#endif
6708
#ifdef TARGET_NR_accept
6709
    case TARGET_NR_accept:
6710
        ret = do_accept4(arg1, arg2, arg3, 0);
6711
        break;
6712
#endif
6713
#ifdef TARGET_NR_accept4
6714
    case TARGET_NR_accept4:
6715
#ifdef CONFIG_ACCEPT4
6716
        ret = do_accept4(arg1, arg2, arg3, arg4);
6717
#else
6718
        goto unimplemented;
6719
#endif
6720
        break;
6721
#endif
6722
#ifdef TARGET_NR_bind
6723
    case TARGET_NR_bind:
6724
        ret = do_bind(arg1, arg2, arg3);
6725
        break;
6726
#endif
6727
#ifdef TARGET_NR_connect
6728
    case TARGET_NR_connect:
6729
        ret = do_connect(arg1, arg2, arg3);
6730
        break;
6731
#endif
6732
#ifdef TARGET_NR_getpeername
6733
    case TARGET_NR_getpeername:
6734
        ret = do_getpeername(arg1, arg2, arg3);
6735
        break;
6736
#endif
6737
#ifdef TARGET_NR_getsockname
6738
    case TARGET_NR_getsockname:
6739
        ret = do_getsockname(arg1, arg2, arg3);
6740
        break;
6741
#endif
6742
#ifdef TARGET_NR_getsockopt
6743
    case TARGET_NR_getsockopt:
6744
        ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
6745
        break;
6746
#endif
6747
#ifdef TARGET_NR_listen
6748
    case TARGET_NR_listen:
6749
        ret = get_errno(listen(arg1, arg2));
6750
        break;
6751
#endif
6752
#ifdef TARGET_NR_recv
6753
    case TARGET_NR_recv:
6754
        ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
6755
        break;
6756
#endif
6757
#ifdef TARGET_NR_recvfrom
6758
    case TARGET_NR_recvfrom:
6759
        ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
6760
        break;
6761
#endif
6762
#ifdef TARGET_NR_recvmsg
6763
    case TARGET_NR_recvmsg:
6764
        ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
6765
        break;
6766
#endif
6767
#ifdef TARGET_NR_send
6768
    case TARGET_NR_send:
6769
        ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
6770
        break;
6771
#endif
6772
#ifdef TARGET_NR_sendmsg
6773
    case TARGET_NR_sendmsg:
6774
        ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
6775
        break;
6776
#endif
6777
#ifdef TARGET_NR_sendmmsg
6778
    case TARGET_NR_sendmmsg:
6779
        ret = do_sendrecvmmsg(arg1, arg2, arg3, arg4, 1);
6780
        break;
6781
    case TARGET_NR_recvmmsg:
6782
        ret = do_sendrecvmmsg(arg1, arg2, arg3, arg4, 0);
6783
        break;
6784
#endif
6785
#ifdef TARGET_NR_sendto
6786
    case TARGET_NR_sendto:
6787
        ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
6788
        break;
6789
#endif
6790
#ifdef TARGET_NR_shutdown
6791
    case TARGET_NR_shutdown:
6792
        ret = get_errno(shutdown(arg1, arg2));
6793
        break;
6794
#endif
6795
#ifdef TARGET_NR_socket
6796
    case TARGET_NR_socket:
6797
        ret = do_socket(arg1, arg2, arg3);
6798
        break;
6799
#endif
6800
#ifdef TARGET_NR_socketpair
6801
    case TARGET_NR_socketpair:
6802
        ret = do_socketpair(arg1, arg2, arg3, arg4);
6803
        break;
6804
#endif
6805
#ifdef TARGET_NR_setsockopt
6806
    case TARGET_NR_setsockopt:
6807
        ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
6808
        break;
6809
#endif
6810

    
6811
    case TARGET_NR_syslog:
6812
        if (!(p = lock_user_string(arg2)))
6813
            goto efault;
6814
        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
6815
        unlock_user(p, arg2, 0);
6816
        break;
6817

    
6818
    case TARGET_NR_setitimer:
6819
        {
6820
            struct itimerval value, ovalue, *pvalue;
6821

    
6822
            if (arg2) {
6823
                pvalue = &value;
6824
                if (copy_from_user_timeval(&pvalue->it_interval, arg2)
6825
                    || copy_from_user_timeval(&pvalue->it_value,
6826
                                              arg2 + sizeof(struct target_timeval)))
6827
                    goto efault;
6828
            } else {
6829
                pvalue = NULL;
6830
            }
6831
            ret = get_errno(setitimer(arg1, pvalue, &ovalue));
6832
            if (!is_error(ret) && arg3) {
6833
                if (copy_to_user_timeval(arg3,
6834
                                         &ovalue.it_interval)
6835
                    || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
6836
                                            &ovalue.it_value))
6837
                    goto efault;
6838
            }
6839
        }
6840
        break;
6841
    case TARGET_NR_getitimer:
6842
        {
6843
            struct itimerval value;
6844

    
6845
            ret = get_errno(getitimer(arg1, &value));
6846
            if (!is_error(ret) && arg2) {
6847
                if (copy_to_user_timeval(arg2,
6848
                                         &value.it_interval)
6849
                    || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
6850
                                            &value.it_value))
6851
                    goto efault;
6852
            }
6853
        }
6854
        break;
6855
    case TARGET_NR_stat:
6856
        if (!(p = lock_user_string(arg1)))
6857
            goto efault;
6858
        ret = get_errno(stat(path(p), &st));
6859
        unlock_user(p, arg1, 0);
6860
        goto do_stat;
6861
    case TARGET_NR_lstat:
6862
        if (!(p = lock_user_string(arg1)))
6863
            goto efault;
6864
        ret = get_errno(lstat(path(p), &st));
6865
        unlock_user(p, arg1, 0);
6866
        goto do_stat;
6867
    case TARGET_NR_fstat:
6868
        {
6869
            ret = get_errno(fstat(arg1, &st));
6870
        do_stat:
6871
            if (!is_error(ret)) {
6872
                struct target_stat *target_st;
6873

    
6874
                if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
6875
                    goto efault;
6876
                memset(target_st, 0, sizeof(*target_st));
6877
                __put_user(st.st_dev, &target_st->st_dev);
6878
                __put_user(st.st_ino, &target_st->st_ino);
6879
                __put_user(st.st_mode, &target_st->st_mode);
6880
                __put_user(st.st_uid, &target_st->st_uid);
6881
                __put_user(st.st_gid, &target_st->st_gid);
6882
                __put_user(st.st_nlink, &target_st->st_nlink);
6883
                __put_user(st.st_rdev, &target_st->st_rdev);
6884
                __put_user(st.st_size, &target_st->st_size);
6885
                __put_user(st.st_blksize, &target_st->st_blksize);
6886
                __put_user(st.st_blocks, &target_st->st_blocks);
6887
                __put_user(st.st_atime, &target_st->target_st_atime);
6888
                __put_user(st.st_mtime, &target_st->target_st_mtime);
6889
                __put_user(st.st_ctime, &target_st->target_st_ctime);
6890
                unlock_user_struct(target_st, arg2, 1);
6891
            }
6892
        }
6893
        break;
6894
#ifdef TARGET_NR_olduname
6895
    case TARGET_NR_olduname:
6896
        goto unimplemented;
6897
#endif
6898
#ifdef TARGET_NR_iopl
6899
    case TARGET_NR_iopl:
6900
        goto unimplemented;
6901
#endif
6902
    case TARGET_NR_vhangup:
6903
        ret = get_errno(vhangup());
6904
        break;
6905
#ifdef TARGET_NR_idle
6906
    case TARGET_NR_idle:
6907
        goto unimplemented;
6908
#endif
6909
#ifdef TARGET_NR_syscall
6910
    case TARGET_NR_syscall:
6911
        ret = do_syscall(cpu_env, arg1 & 0xffff, arg2, arg3, arg4, arg5,
6912
                         arg6, arg7, arg8, 0);
6913
        break;
6914
#endif
6915
    case TARGET_NR_wait4:
6916
        {
6917
            int status;
6918
            abi_long status_ptr = arg2;
6919
            struct rusage rusage, *rusage_ptr;
6920
            abi_ulong target_rusage = arg4;
6921
            if (target_rusage)
6922
                rusage_ptr = &rusage;
6923
            else
6924
                rusage_ptr = NULL;
6925
            ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
6926
            if (!is_error(ret)) {
6927
                if (status_ptr && ret) {
6928
                    status = host_to_target_waitstatus(status);
6929
                    if (put_user_s32(status, status_ptr))
6930
                        goto efault;
6931
                }
6932
                if (target_rusage)
6933
                    host_to_target_rusage(target_rusage, &rusage);
6934
            }
6935
        }
6936
        break;
6937
#ifdef TARGET_NR_swapoff
6938
    case TARGET_NR_swapoff:
6939
        if (!(p = lock_user_string(arg1)))
6940
            goto efault;
6941
        ret = get_errno(swapoff(p));
6942
        unlock_user(p, arg1, 0);
6943
        break;
6944
#endif
6945
    case TARGET_NR_sysinfo:
6946
        {
6947
            struct target_sysinfo *target_value;
6948
            struct sysinfo value;
6949
            ret = get_errno(sysinfo(&value));
6950
            if (!is_error(ret) && arg1)
6951
            {
6952
                if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
6953
                    goto efault;
6954
                __put_user(value.uptime, &target_value->uptime);
6955
                __put_user(value.loads[0], &target_value->loads[0]);
6956
                __put_user(value.loads[1], &target_value->loads[1]);
6957
                __put_user(value.loads[2], &target_value->loads[2]);
6958
                __put_user(value.totalram, &target_value->totalram);
6959
                __put_user(value.freeram, &target_value->freeram);
6960
                __put_user(value.sharedram, &target_value->sharedram);
6961
                __put_user(value.bufferram, &target_value->bufferram);
6962
                __put_user(value.totalswap, &target_value->totalswap);
6963
                __put_user(value.freeswap, &target_value->freeswap);
6964
                __put_user(value.procs, &target_value->procs);
6965
                __put_user(value.totalhigh, &target_value->totalhigh);
6966
                __put_user(value.freehigh, &target_value->freehigh);
6967
                __put_user(value.mem_unit, &target_value->mem_unit);
6968
                unlock_user_struct(target_value, arg1, 1);
6969
            }
6970
        }
6971
        break;
6972
#ifdef TARGET_NR_ipc
6973
    case TARGET_NR_ipc:
6974
        ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
6975
        break;
6976
#endif
6977
#ifdef TARGET_NR_semget
6978
    case TARGET_NR_semget:
6979
        ret = get_errno(semget(arg1, arg2, arg3));
6980
        break;
6981
#endif
6982
#ifdef TARGET_NR_semop
6983
    case TARGET_NR_semop:
6984
        ret = do_semop(arg1, arg2, arg3);
6985
        break;
6986
#endif
6987
#ifdef TARGET_NR_semctl
6988
    case TARGET_NR_semctl:
6989
        ret = do_semctl(arg1, arg2, arg3, (union target_semun)(abi_ulong)arg4);
6990
        break;
6991
#endif
6992
#ifdef TARGET_NR_msgctl
6993
    case TARGET_NR_msgctl:
6994
        ret = do_msgctl(arg1, arg2, arg3);
6995
        break;
6996
#endif
6997
#ifdef TARGET_NR_msgget
6998
    case TARGET_NR_msgget:
6999
        ret = get_errno(msgget(arg1, arg2));
7000
        break;
7001
#endif
7002
#ifdef TARGET_NR_msgrcv
7003
    case TARGET_NR_msgrcv:
7004
        ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
7005
        break;
7006
#endif
7007
#ifdef TARGET_NR_msgsnd
7008
    case TARGET_NR_msgsnd:
7009
        ret = do_msgsnd(arg1, arg2, arg3, arg4);
7010
        break;
7011
#endif
7012
#ifdef TARGET_NR_shmget
7013
    case TARGET_NR_shmget:
7014
        ret = get_errno(shmget(arg1, arg2, arg3));
7015
        break;
7016
#endif
7017
#ifdef TARGET_NR_shmctl
7018
    case TARGET_NR_shmctl:
7019
        ret = do_shmctl(arg1, arg2, arg3);
7020
        break;
7021
#endif
7022
#ifdef TARGET_NR_shmat
7023
    case TARGET_NR_shmat:
7024
        ret = do_shmat(arg1, arg2, arg3);
7025
        break;
7026
#endif
7027
#ifdef TARGET_NR_shmdt
7028
    case TARGET_NR_shmdt:
7029
        ret = do_shmdt(arg1);
7030
        break;
7031
#endif
7032
    case TARGET_NR_fsync:
7033
        ret = get_errno(fsync(arg1));
7034
        break;
7035
    case TARGET_NR_clone:
7036
        /* Linux manages to have three different orderings for its
7037
         * arguments to clone(); the BACKWARDS and BACKWARDS2 defines
7038
         * match the kernel's CONFIG_CLONE_* settings.
7039
         * Microblaze is further special in that it uses a sixth
7040
         * implicit argument to clone for the TLS pointer.
7041
         */
7042
#if defined(TARGET_MICROBLAZE)
7043
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg4, arg6, arg5));
7044
#elif defined(TARGET_CLONE_BACKWARDS)
7045
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
7046
#elif defined(TARGET_CLONE_BACKWARDS2)
7047
        ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg5, arg4));
7048
#else
7049
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
7050
#endif
7051
        break;
7052
#ifdef __NR_exit_group
7053
        /* new thread calls */
7054
    case TARGET_NR_exit_group:
7055
#ifdef TARGET_GPROF
7056
        _mcleanup();
7057
#endif
7058
        gdb_exit(cpu_env, arg1);
7059
        ret = get_errno(exit_group(arg1));
7060
        break;
7061
#endif
7062
    case TARGET_NR_setdomainname:
7063
        if (!(p = lock_user_string(arg1)))
7064
            goto efault;
7065
        ret = get_errno(setdomainname(p, arg2));
7066
        unlock_user(p, arg1, 0);
7067
        break;
7068
    case TARGET_NR_uname:
7069
        /* no need to transcode because we use the linux syscall */
7070
        {
7071
            struct new_utsname * buf;
7072

    
7073
            if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
7074
                goto efault;
7075
            ret = get_errno(sys_uname(buf));
7076
            if (!is_error(ret)) {
7077
                /* Overrite the native machine name with whatever is being
7078
                   emulated. */
7079
                strcpy (buf->machine, cpu_to_uname_machine(cpu_env));
7080
                /* Allow the user to override the reported release.  */
7081
                if (qemu_uname_release && *qemu_uname_release)
7082
                  strcpy (buf->release, qemu_uname_release);
7083
            }
7084
            unlock_user_struct(buf, arg1, 1);
7085
        }
7086
        break;
7087
#ifdef TARGET_I386
7088
    case TARGET_NR_modify_ldt:
7089
        ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
7090
        break;
7091
#if !defined(TARGET_X86_64)
7092
    case TARGET_NR_vm86old:
7093
        goto unimplemented;
7094
    case TARGET_NR_vm86:
7095
        ret = do_vm86(cpu_env, arg1, arg2);
7096
        break;
7097
#endif
7098
#endif
7099
    case TARGET_NR_adjtimex:
7100
        goto unimplemented;
7101
#ifdef TARGET_NR_create_module
7102
    case TARGET_NR_create_module:
7103
#endif
7104
    case TARGET_NR_init_module:
7105
    case TARGET_NR_delete_module:
7106
#ifdef TARGET_NR_get_kernel_syms
7107
    case TARGET_NR_get_kernel_syms:
7108
#endif
7109
        goto unimplemented;
7110
    case TARGET_NR_quotactl:
7111
        goto unimplemented;
7112
    case TARGET_NR_getpgid:
7113
        ret = get_errno(getpgid(arg1));
7114
        break;
7115
    case TARGET_NR_fchdir:
7116
        ret = get_errno(fchdir(arg1));
7117
        break;
7118
#ifdef TARGET_NR_bdflush /* not on x86_64 */
7119
    case TARGET_NR_bdflush:
7120
        goto unimplemented;
7121
#endif
7122
#ifdef TARGET_NR_sysfs
7123
    case TARGET_NR_sysfs:
7124
        goto unimplemented;
7125
#endif
7126
    case TARGET_NR_personality:
7127
        ret = get_errno(personality(arg1));
7128
        break;
7129
#ifdef TARGET_NR_afs_syscall
7130
    case TARGET_NR_afs_syscall:
7131
        goto unimplemented;
7132
#endif
7133
#ifdef TARGET_NR__llseek /* Not on alpha */
7134
    case TARGET_NR__llseek:
7135
        {
7136
            int64_t res;
7137
#if !defined(__NR_llseek)
7138
            res = lseek(arg1, ((uint64_t)arg2 << 32) | arg3, arg5);
7139
            if (res == -1) {
7140
                ret = get_errno(res);
7141
            } else {
7142
                ret = 0;
7143
            }
7144
#else
7145
            ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
7146
#endif
7147
            if ((ret == 0) && put_user_s64(res, arg4)) {
7148
                goto efault;
7149
            }
7150
        }
7151
        break;
7152
#endif
7153
    case TARGET_NR_getdents:
7154
#ifdef __NR_getdents
7155
#if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
7156
        {
7157
            struct target_dirent *target_dirp;
7158
            struct linux_dirent *dirp;
7159
            abi_long count = arg3;
7160

    
7161
            dirp = malloc(count);
7162
            if (!dirp) {
7163
                ret = -TARGET_ENOMEM;
7164
                goto fail;
7165
            }
7166

    
7167
            ret = get_errno(sys_getdents(arg1, dirp, count));
7168
            if (!is_error(ret)) {
7169
                struct linux_dirent *de;
7170
                struct target_dirent *tde;
7171
                int len = ret;
7172
                int reclen, treclen;
7173
                int count1, tnamelen;
7174

    
7175
                count1 = 0;
7176
                de = dirp;
7177
                if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
7178
                    goto efault;
7179
                tde = target_dirp;
7180
                while (len > 0) {
7181
                    reclen = de->d_reclen;
7182
                    tnamelen = reclen - offsetof(struct linux_dirent, d_name);
7183
                    assert(tnamelen >= 0);
7184
                    treclen = tnamelen + offsetof(struct target_dirent, d_name);
7185
                    assert(count1 + treclen <= count);
7186
                    tde->d_reclen = tswap16(treclen);
7187
                    tde->d_ino = tswapal(de->d_ino);
7188
                    tde->d_off = tswapal(de->d_off);
7189
                    memcpy(tde->d_name, de->d_name, tnamelen);
7190
                    de = (struct linux_dirent *)((char *)de + reclen);
7191
                    len -= reclen;
7192
                    tde = (struct target_dirent *)((char *)tde + treclen);
7193
                    count1 += treclen;
7194
                }
7195
                ret = count1;
7196
                unlock_user(target_dirp, arg2, ret);
7197
            }
7198
            free(dirp);
7199
        }
7200
#else
7201
        {
7202
            struct linux_dirent *dirp;
7203
            abi_long count = arg3;
7204

    
7205
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
7206
                goto efault;
7207
            ret = get_errno(sys_getdents(arg1, dirp, count));
7208
            if (!is_error(ret)) {
7209
                struct linux_dirent *de;
7210
                int len = ret;
7211
                int reclen;
7212
                de = dirp;
7213
                while (len > 0) {
7214
                    reclen = de->d_reclen;
7215
                    if (reclen > len)
7216
                        break;
7217
                    de->d_reclen = tswap16(reclen);
7218
                    tswapls(&de->d_ino);
7219
                    tswapls(&de->d_off);
7220
                    de = (struct linux_dirent *)((char *)de + reclen);
7221
                    len -= reclen;
7222
                }
7223
            }
7224
            unlock_user(dirp, arg2, ret);
7225
        }
7226
#endif
7227
#else
7228
        /* Implement getdents in terms of getdents64 */
7229
        {
7230
            struct linux_dirent64 *dirp;
7231
            abi_long count = arg3;
7232

    
7233
            dirp = lock_user(VERIFY_WRITE, arg2, count, 0);
7234
            if (!dirp) {
7235
                goto efault;
7236
            }
7237
            ret = get_errno(sys_getdents64(arg1, dirp, count));
7238
            if (!is_error(ret)) {
7239
                /* Convert the dirent64 structs to target dirent.  We do this
7240
                 * in-place, since we can guarantee that a target_dirent is no
7241
                 * larger than a dirent64; however this means we have to be
7242
                 * careful to read everything before writing in the new format.
7243
                 */
7244
                struct linux_dirent64 *de;
7245
                struct target_dirent *tde;
7246
                int len = ret;
7247
                int tlen = 0;
7248

    
7249
                de = dirp;
7250
                tde = (struct target_dirent *)dirp;
7251
                while (len > 0) {
7252
                    int namelen, treclen;
7253
                    int reclen = de->d_reclen;
7254
                    uint64_t ino = de->d_ino;
7255
                    int64_t off = de->d_off;
7256
                    uint8_t type = de->d_type;
7257

    
7258
                    namelen = strlen(de->d_name);
7259
                    treclen = offsetof(struct target_dirent, d_name)
7260
                        + namelen + 2;
7261
                    treclen = QEMU_ALIGN_UP(treclen, sizeof(abi_long));
7262

    
7263
                    memmove(tde->d_name, de->d_name, namelen + 1);
7264
                    tde->d_ino = tswapal(ino);
7265
                    tde->d_off = tswapal(off);
7266
                    tde->d_reclen = tswap16(treclen);
7267
                    /* The target_dirent type is in what was formerly a padding
7268
                     * byte at the end of the structure:
7269
                     */
7270
                    *(((char *)tde) + treclen - 1) = type;
7271

    
7272
                    de = (struct linux_dirent64 *)((char *)de + reclen);
7273
                    tde = (struct target_dirent *)((char *)tde + treclen);
7274
                    len -= reclen;
7275
                    tlen += treclen;
7276
                }
7277
                ret = tlen;
7278
            }
7279
            unlock_user(dirp, arg2, ret);
7280
        }
7281
#endif
7282
        break;
7283
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
7284
    case TARGET_NR_getdents64:
7285
        {
7286
            struct linux_dirent64 *dirp;
7287
            abi_long count = arg3;
7288
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
7289
                goto efault;
7290
            ret = get_errno(sys_getdents64(arg1, dirp, count));
7291
            if (!is_error(ret)) {
7292
                struct linux_dirent64 *de;
7293
                int len = ret;
7294
                int reclen;
7295
                de = dirp;
7296
                while (len > 0) {
7297
                    reclen = de->d_reclen;
7298
                    if (reclen > len)
7299
                        break;
7300
                    de->d_reclen = tswap16(reclen);
7301
                    tswap64s((uint64_t *)&de->d_ino);
7302
                    tswap64s((uint64_t *)&de->d_off);
7303
                    de = (struct linux_dirent64 *)((char *)de + reclen);
7304
                    len -= reclen;
7305
                }
7306
            }
7307
            unlock_user(dirp, arg2, ret);
7308
        }
7309
        break;
7310
#endif /* TARGET_NR_getdents64 */
7311
#if defined(TARGET_NR__newselect)
7312
    case TARGET_NR__newselect:
7313
        ret = do_select(arg1, arg2, arg3, arg4, arg5);
7314
        break;
7315
#endif
7316
#if defined(TARGET_NR_poll) || defined(TARGET_NR_ppoll)
7317
# ifdef TARGET_NR_poll
7318
    case TARGET_NR_poll:
7319
# endif
7320
# ifdef TARGET_NR_ppoll
7321
    case TARGET_NR_ppoll:
7322
# endif
7323
        {
7324
            struct target_pollfd *target_pfd;
7325
            unsigned int nfds = arg2;
7326
            int timeout = arg3;
7327
            struct pollfd *pfd;
7328
            unsigned int i;
7329

    
7330
            target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
7331
            if (!target_pfd)
7332
                goto efault;
7333

    
7334
            pfd = alloca(sizeof(struct pollfd) * nfds);
7335
            for(i = 0; i < nfds; i++) {
7336
                pfd[i].fd = tswap32(target_pfd[i].fd);
7337
                pfd[i].events = tswap16(target_pfd[i].events);
7338
            }
7339

    
7340
# ifdef TARGET_NR_ppoll
7341
            if (num == TARGET_NR_ppoll) {
7342
                struct timespec _timeout_ts, *timeout_ts = &_timeout_ts;
7343
                target_sigset_t *target_set;
7344
                sigset_t _set, *set = &_set;
7345

    
7346
                if (arg3) {
7347
                    if (target_to_host_timespec(timeout_ts, arg3)) {
7348
                        unlock_user(target_pfd, arg1, 0);
7349
                        goto efault;
7350
                    }
7351
                } else {
7352
                    timeout_ts = NULL;
7353
                }
7354

    
7355
                if (arg4) {
7356
                    target_set = lock_user(VERIFY_READ, arg4, sizeof(target_sigset_t), 1);
7357
                    if (!target_set) {
7358
                        unlock_user(target_pfd, arg1, 0);
7359
                        goto efault;
7360
                    }
7361
                    target_to_host_sigset(set, target_set);
7362
                } else {
7363
                    set = NULL;
7364
                }
7365

    
7366
                ret = get_errno(sys_ppoll(pfd, nfds, timeout_ts, set, _NSIG/8));
7367

    
7368
                if (!is_error(ret) && arg3) {
7369
                    host_to_target_timespec(arg3, timeout_ts);
7370
                }
7371
                if (arg4) {
7372
                    unlock_user(target_set, arg4, 0);
7373
                }
7374
            } else
7375
# endif
7376
                ret = get_errno(poll(pfd, nfds, timeout));
7377

    
7378
            if (!is_error(ret)) {
7379
                for(i = 0; i < nfds; i++) {
7380
                    target_pfd[i].revents = tswap16(pfd[i].revents);
7381
                }
7382
            }
7383
            unlock_user(target_pfd, arg1, sizeof(struct target_pollfd) * nfds);
7384
        }
7385
        break;
7386
#endif
7387
    case TARGET_NR_flock:
7388
        /* NOTE: the flock constant seems to be the same for every
7389
           Linux platform */
7390
        ret = get_errno(flock(arg1, arg2));
7391
        break;
7392
    case TARGET_NR_readv:
7393
        {
7394
            struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 0);
7395
            if (vec != NULL) {
7396
                ret = get_errno(readv(arg1, vec, arg3));
7397
                unlock_iovec(vec, arg2, arg3, 1);
7398
            } else {
7399
                ret = -host_to_target_errno(errno);
7400
            }
7401
        }
7402
        break;
7403
    case TARGET_NR_writev:
7404
        {
7405
            struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
7406
            if (vec != NULL) {
7407
                ret = get_errno(writev(arg1, vec, arg3));
7408
                unlock_iovec(vec, arg2, arg3, 0);
7409
            } else {
7410
                ret = -host_to_target_errno(errno);
7411
            }
7412
        }
7413
        break;
7414
    case TARGET_NR_getsid:
7415
        ret = get_errno(getsid(arg1));
7416
        break;
7417
#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
7418
    case TARGET_NR_fdatasync:
7419
        ret = get_errno(fdatasync(arg1));
7420
        break;
7421
#endif
7422
    case TARGET_NR__sysctl:
7423
        /* We don't implement this, but ENOTDIR is always a safe
7424
           return value. */
7425
        ret = -TARGET_ENOTDIR;
7426
        break;
7427
    case TARGET_NR_sched_getaffinity:
7428
        {
7429
            unsigned int mask_size;
7430
            unsigned long *mask;
7431

    
7432
            /*
7433
             * sched_getaffinity needs multiples of ulong, so need to take
7434
             * care of mismatches between target ulong and host ulong sizes.
7435
             */
7436
            if (arg2 & (sizeof(abi_ulong) - 1)) {
7437
                ret = -TARGET_EINVAL;
7438
                break;
7439
            }
7440
            mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
7441

    
7442
            mask = alloca(mask_size);
7443
            ret = get_errno(sys_sched_getaffinity(arg1, mask_size, mask));
7444

    
7445
            if (!is_error(ret)) {
7446
                if (copy_to_user(arg3, mask, ret)) {
7447
                    goto efault;
7448
                }
7449
            }
7450
        }
7451
        break;
7452
    case TARGET_NR_sched_setaffinity:
7453
        {
7454
            unsigned int mask_size;
7455
            unsigned long *mask;
7456

    
7457
            /*
7458
             * sched_setaffinity needs multiples of ulong, so need to take
7459
             * care of mismatches between target ulong and host ulong sizes.
7460
             */
7461
            if (arg2 & (sizeof(abi_ulong) - 1)) {
7462
                ret = -TARGET_EINVAL;
7463
                break;
7464
            }
7465
            mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
7466

    
7467
            mask = alloca(mask_size);
7468
            if (!lock_user_struct(VERIFY_READ, p, arg3, 1)) {
7469
                goto efault;
7470
            }
7471
            memcpy(mask, p, arg2);
7472
            unlock_user_struct(p, arg2, 0);
7473

    
7474
            ret = get_errno(sys_sched_setaffinity(arg1, mask_size, mask));
7475
        }
7476
        break;
7477
    case TARGET_NR_sched_setparam:
7478
        {
7479
            struct sched_param *target_schp;
7480
            struct sched_param schp;
7481

    
7482
            if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
7483
                goto efault;
7484
            schp.sched_priority = tswap32(target_schp->sched_priority);
7485
            unlock_user_struct(target_schp, arg2, 0);
7486
            ret = get_errno(sched_setparam(arg1, &schp));
7487
        }
7488
        break;
7489
    case TARGET_NR_sched_getparam:
7490
        {
7491
            struct sched_param *target_schp;
7492
            struct sched_param schp;
7493
            ret = get_errno(sched_getparam(arg1, &schp));
7494
            if (!is_error(ret)) {
7495
                if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
7496
                    goto efault;
7497
                target_schp->sched_priority = tswap32(schp.sched_priority);
7498
                unlock_user_struct(target_schp, arg2, 1);
7499
            }
7500
        }
7501
        break;
7502
    case TARGET_NR_sched_setscheduler:
7503
        {
7504
            struct sched_param *target_schp;
7505
            struct sched_param schp;
7506
            if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
7507
                goto efault;
7508
            schp.sched_priority = tswap32(target_schp->sched_priority);
7509
            unlock_user_struct(target_schp, arg3, 0);
7510
            ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
7511
        }
7512
        break;
7513
    case TARGET_NR_sched_getscheduler:
7514
        ret = get_errno(sched_getscheduler(arg1));
7515
        break;
7516
    case TARGET_NR_sched_yield:
7517
        ret = get_errno(sched_yield());
7518
        break;
7519
    case TARGET_NR_sched_get_priority_max:
7520
        ret = get_errno(sched_get_priority_max(arg1));
7521
        break;
7522
    case TARGET_NR_sched_get_priority_min:
7523
        ret = get_errno(sched_get_priority_min(arg1));
7524
        break;
7525
    case TARGET_NR_sched_rr_get_interval:
7526
        {
7527
            struct timespec ts;
7528
            ret = get_errno(sched_rr_get_interval(arg1, &ts));
7529
            if (!is_error(ret)) {
7530
                host_to_target_timespec(arg2, &ts);
7531
            }
7532
        }
7533
        break;
7534
    case TARGET_NR_nanosleep:
7535
        {
7536
            struct timespec req, rem;
7537
            target_to_host_timespec(&req, arg1);
7538
            ret = get_errno(nanosleep(&req, &rem));
7539
            if (is_error(ret) && arg2) {
7540
                host_to_target_timespec(arg2, &rem);
7541
            }
7542
        }
7543
        break;
7544
#ifdef TARGET_NR_query_module
7545
    case TARGET_NR_query_module:
7546
        goto unimplemented;
7547
#endif
7548
#ifdef TARGET_NR_nfsservctl
7549
    case TARGET_NR_nfsservctl:
7550
        goto unimplemented;
7551
#endif
7552
    case TARGET_NR_prctl:
7553
        switch (arg1) {
7554
        case PR_GET_PDEATHSIG:
7555
        {
7556
            int deathsig;
7557
            ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
7558
            if (!is_error(ret) && arg2
7559
                && put_user_ual(deathsig, arg2)) {
7560
                goto efault;
7561
            }
7562
            break;
7563
        }
7564
#ifdef PR_GET_NAME
7565
        case PR_GET_NAME:
7566
        {
7567
            void *name = lock_user(VERIFY_WRITE, arg2, 16, 1);
7568
            if (!name) {
7569
                goto efault;
7570
            }
7571
            ret = get_errno(prctl(arg1, (unsigned long)name,
7572
                                  arg3, arg4, arg5));
7573
            unlock_user(name, arg2, 16);
7574
            break;
7575
        }
7576
        case PR_SET_NAME:
7577
        {
7578
            void *name = lock_user(VERIFY_READ, arg2, 16, 1);
7579
            if (!name) {
7580
                goto efault;
7581
            }
7582
            ret = get_errno(prctl(arg1, (unsigned long)name,
7583
                                  arg3, arg4, arg5));
7584
            unlock_user(name, arg2, 0);
7585
            break;
7586
        }
7587
#endif
7588
        default:
7589
            /* Most prctl options have no pointer arguments */
7590
            ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
7591
            break;
7592
        }
7593
        break;
7594
#ifdef TARGET_NR_arch_prctl
7595
    case TARGET_NR_arch_prctl:
7596
#if defined(TARGET_I386) && !defined(TARGET_ABI32)
7597
        ret = do_arch_prctl(cpu_env, arg1, arg2);
7598
        break;
7599
#else
7600
        goto unimplemented;
7601
#endif
7602
#endif
7603
#ifdef TARGET_NR_pread64
7604
    case TARGET_NR_pread64:
7605
        if (regpairs_aligned(cpu_env)) {
7606
            arg4 = arg5;
7607
            arg5 = arg6;
7608
        }
7609
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
7610
            goto efault;
7611
        ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
7612
        unlock_user(p, arg2, ret);
7613
        break;
7614
    case TARGET_NR_pwrite64:
7615
        if (regpairs_aligned(cpu_env)) {
7616
            arg4 = arg5;
7617
            arg5 = arg6;
7618
        }
7619
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
7620
            goto efault;
7621
        ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
7622
        unlock_user(p, arg2, 0);
7623
        break;
7624
#endif
7625
    case TARGET_NR_getcwd:
7626
        if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
7627
            goto efault;
7628
        ret = get_errno(sys_getcwd1(p, arg2));
7629
        unlock_user(p, arg1, ret);
7630
        break;
7631
    case TARGET_NR_capget:
7632
        goto unimplemented;
7633
    case TARGET_NR_capset:
7634
        goto unimplemented;
7635
    case TARGET_NR_sigaltstack:
7636
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
7637
    defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA) || \
7638
    defined(TARGET_M68K) || defined(TARGET_S390X) || defined(TARGET_OPENRISC)
7639
        ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUArchState *)cpu_env));
7640
        break;
7641
#else
7642
        goto unimplemented;
7643
#endif
7644

    
7645
#ifdef CONFIG_SENDFILE
7646
    case TARGET_NR_sendfile:
7647
    {
7648
        off_t *offp = NULL;
7649
        off_t off;
7650
        if (arg3) {
7651
            ret = get_user_sal(off, arg3);
7652
            if (is_error(ret)) {
7653
                break;
7654
            }
7655
            offp = &off;
7656
        }
7657
        ret = get_errno(sendfile(arg1, arg2, offp, arg4));
7658
        if (!is_error(ret) && arg3) {
7659
            abi_long ret2 = put_user_sal(off, arg3);
7660
            if (is_error(ret2)) {
7661
                ret = ret2;
7662
            }
7663
        }
7664
        break;
7665
    }
7666
#ifdef TARGET_NR_sendfile64
7667
    case TARGET_NR_sendfile64:
7668
    {
7669
        off_t *offp = NULL;
7670
        off_t off;
7671
        if (arg3) {
7672
            ret = get_user_s64(off, arg3);
7673
            if (is_error(ret)) {
7674
                break;
7675
            }
7676
            offp = &off;
7677
        }
7678
        ret = get_errno(sendfile(arg1, arg2, offp, arg4));
7679
        if (!is_error(ret) && arg3) {
7680
            abi_long ret2 = put_user_s64(off, arg3);
7681
            if (is_error(ret2)) {
7682
                ret = ret2;
7683
            }
7684
        }
7685
        break;
7686
    }
7687
#endif
7688
#else
7689
    case TARGET_NR_sendfile:
7690
#ifdef TARGET_NR_sendfile64
7691
    case TARGET_NR_sendfile64:
7692
#endif
7693
        goto unimplemented;
7694
#endif
7695

    
7696
#ifdef TARGET_NR_getpmsg
7697
    case TARGET_NR_getpmsg:
7698
        goto unimplemented;
7699
#endif
7700
#ifdef TARGET_NR_putpmsg
7701
    case TARGET_NR_putpmsg:
7702
        goto unimplemented;
7703
#endif
7704
#ifdef TARGET_NR_vfork
7705
    case TARGET_NR_vfork:
7706
        ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
7707
                        0, 0, 0, 0));
7708
        break;
7709
#endif
7710
#ifdef TARGET_NR_ugetrlimit
7711
    case TARGET_NR_ugetrlimit:
7712
    {
7713
        struct rlimit rlim;
7714
        int resource = target_to_host_resource(arg1);
7715
        ret = get_errno(getrlimit(resource, &rlim));
7716
        if (!is_error(ret)) {
7717
            struct target_rlimit *target_rlim;
7718
            if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
7719
                goto efault;
7720
            target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
7721
            target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
7722
            unlock_user_struct(target_rlim, arg2, 1);
7723
        }
7724
        break;
7725
    }
7726
#endif
7727
#ifdef TARGET_NR_truncate64
7728
    case TARGET_NR_truncate64:
7729
        if (!(p = lock_user_string(arg1)))
7730
            goto efault;
7731
        ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
7732
        unlock_user(p, arg1, 0);
7733
        break;
7734
#endif
7735
#ifdef TARGET_NR_ftruncate64
7736
    case TARGET_NR_ftruncate64:
7737
        ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
7738
        break;
7739
#endif
7740
#ifdef TARGET_NR_stat64
7741
    case TARGET_NR_stat64:
7742
        if (!(p = lock_user_string(arg1)))
7743
            goto efault;
7744
        ret = get_errno(stat(path(p), &st));
7745
        unlock_user(p, arg1, 0);
7746
        if (!is_error(ret))
7747
            ret = host_to_target_stat64(cpu_env, arg2, &st);
7748
        break;
7749
#endif
7750
#ifdef TARGET_NR_lstat64
7751
    case TARGET_NR_lstat64:
7752
        if (!(p = lock_user_string(arg1)))
7753
            goto efault;
7754
        ret = get_errno(lstat(path(p), &st));
7755
        unlock_user(p, arg1, 0);
7756
        if (!is_error(ret))
7757
            ret = host_to_target_stat64(cpu_env, arg2, &st);
7758
        break;
7759
#endif
7760
#ifdef TARGET_NR_fstat64
7761
    case TARGET_NR_fstat64:
7762
        ret = get_errno(fstat(arg1, &st));
7763
        if (!is_error(ret))
7764
            ret = host_to_target_stat64(cpu_env, arg2, &st);
7765
        break;
7766
#endif
7767
#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat))
7768
#ifdef TARGET_NR_fstatat64
7769
    case TARGET_NR_fstatat64:
7770
#endif
7771
#ifdef TARGET_NR_newfstatat
7772
    case TARGET_NR_newfstatat:
7773
#endif
7774
        if (!(p = lock_user_string(arg2)))
7775
            goto efault;
7776
        ret = get_errno(fstatat(arg1, path(p), &st, arg4));
7777
        if (!is_error(ret))
7778
            ret = host_to_target_stat64(cpu_env, arg3, &st);
7779
        break;
7780
#endif
7781
    case TARGET_NR_lchown:
7782
        if (!(p = lock_user_string(arg1)))
7783
            goto efault;
7784
        ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
7785
        unlock_user(p, arg1, 0);
7786
        break;
7787
#ifdef TARGET_NR_getuid
7788
    case TARGET_NR_getuid:
7789
        ret = get_errno(high2lowuid(getuid()));
7790
        break;
7791
#endif
7792
#ifdef TARGET_NR_getgid
7793
    case TARGET_NR_getgid:
7794
        ret = get_errno(high2lowgid(getgid()));
7795
        break;
7796
#endif
7797
#ifdef TARGET_NR_geteuid
7798
    case TARGET_NR_geteuid:
7799
        ret = get_errno(high2lowuid(geteuid()));
7800
        break;
7801
#endif
7802
#ifdef TARGET_NR_getegid
7803
    case TARGET_NR_getegid:
7804
        ret = get_errno(high2lowgid(getegid()));
7805
        break;
7806
#endif
7807
    case TARGET_NR_setreuid:
7808
        ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
7809
        break;
7810
    case TARGET_NR_setregid:
7811
        ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
7812
        break;
7813
    case TARGET_NR_getgroups:
7814
        {
7815
            int gidsetsize = arg1;
7816
            target_id *target_grouplist;
7817
            gid_t *grouplist;
7818
            int i;
7819

    
7820
            grouplist = alloca(gidsetsize * sizeof(gid_t));
7821
            ret = get_errno(getgroups(gidsetsize, grouplist));
7822
            if (gidsetsize == 0)
7823
                break;
7824
            if (!is_error(ret)) {
7825
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * sizeof(target_id), 0);
7826
                if (!target_grouplist)
7827
                    goto efault;
7828
                for(i = 0;i < ret; i++)
7829
                    target_grouplist[i] = tswapid(high2lowgid(grouplist[i]));
7830
                unlock_user(target_grouplist, arg2, gidsetsize * sizeof(target_id));
7831
            }
7832
        }
7833
        break;
7834
    case TARGET_NR_setgroups:
7835
        {
7836
            int gidsetsize = arg1;
7837
            target_id *target_grouplist;
7838
            gid_t *grouplist = NULL;
7839
            int i;
7840
            if (gidsetsize) {
7841
                grouplist = alloca(gidsetsize * sizeof(gid_t));
7842
                target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * sizeof(target_id), 1);
7843
                if (!target_grouplist) {
7844
                    ret = -TARGET_EFAULT;
7845
                    goto fail;
7846
                }
7847
                for (i = 0; i < gidsetsize; i++) {
7848
                    grouplist[i] = low2highgid(tswapid(target_grouplist[i]));
7849
                }
7850
                unlock_user(target_grouplist, arg2, 0);
7851
            }
7852
            ret = get_errno(setgroups(gidsetsize, grouplist));
7853
        }
7854
        break;
7855
    case TARGET_NR_fchown:
7856
        ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
7857
        break;
7858
#if defined(TARGET_NR_fchownat)
7859
    case TARGET_NR_fchownat:
7860
        if (!(p = lock_user_string(arg2))) 
7861
            goto efault;
7862
        ret = get_errno(fchownat(arg1, p, low2highuid(arg3),
7863
                                 low2highgid(arg4), arg5));
7864
        unlock_user(p, arg2, 0);
7865
        break;
7866
#endif
7867
#ifdef TARGET_NR_setresuid
7868
    case TARGET_NR_setresuid:
7869
        ret = get_errno(setresuid(low2highuid(arg1),
7870
                                  low2highuid(arg2),
7871
                                  low2highuid(arg3)));
7872
        break;
7873
#endif
7874
#ifdef TARGET_NR_getresuid
7875
    case TARGET_NR_getresuid:
7876
        {
7877
            uid_t ruid, euid, suid;
7878
            ret = get_errno(getresuid(&ruid, &euid, &suid));
7879
            if (!is_error(ret)) {
7880
                if (put_user_id(high2lowuid(ruid), arg1)
7881
                    || put_user_id(high2lowuid(euid), arg2)
7882
                    || put_user_id(high2lowuid(suid), arg3))
7883
                    goto efault;
7884
            }
7885
        }
7886
        break;
7887
#endif
7888
#ifdef TARGET_NR_getresgid
7889
    case TARGET_NR_setresgid:
7890
        ret = get_errno(setresgid(low2highgid(arg1),
7891
                                  low2highgid(arg2),
7892
                                  low2highgid(arg3)));
7893
        break;
7894
#endif
7895
#ifdef TARGET_NR_getresgid
7896
    case TARGET_NR_getresgid:
7897
        {
7898
            gid_t rgid, egid, sgid;
7899
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
7900
            if (!is_error(ret)) {
7901
                if (put_user_id(high2lowgid(rgid), arg1)
7902
                    || put_user_id(high2lowgid(egid), arg2)
7903
                    || put_user_id(high2lowgid(sgid), arg3))
7904
                    goto efault;
7905
            }
7906
        }
7907
        break;
7908
#endif
7909
    case TARGET_NR_chown:
7910
        if (!(p = lock_user_string(arg1)))
7911
            goto efault;
7912
        ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
7913
        unlock_user(p, arg1, 0);
7914
        break;
7915
    case TARGET_NR_setuid:
7916
        ret = get_errno(setuid(low2highuid(arg1)));
7917
        break;
7918
    case TARGET_NR_setgid:
7919
        ret = get_errno(setgid(low2highgid(arg1)));
7920
        break;
7921
    case TARGET_NR_setfsuid:
7922
        ret = get_errno(setfsuid(arg1));
7923
        break;
7924
    case TARGET_NR_setfsgid:
7925
        ret = get_errno(setfsgid(arg1));
7926
        break;
7927

    
7928
#ifdef TARGET_NR_lchown32
7929
    case TARGET_NR_lchown32:
7930
        if (!(p = lock_user_string(arg1)))
7931
            goto efault;
7932
        ret = get_errno(lchown(p, arg2, arg3));
7933
        unlock_user(p, arg1, 0);
7934
        break;
7935
#endif
7936
#ifdef TARGET_NR_getuid32
7937
    case TARGET_NR_getuid32:
7938
        ret = get_errno(getuid());
7939
        break;
7940
#endif
7941

    
7942
#if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
7943
   /* Alpha specific */
7944
    case TARGET_NR_getxuid:
7945
         {
7946
            uid_t euid;
7947
            euid=geteuid();
7948
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
7949
         }
7950
        ret = get_errno(getuid());
7951
        break;
7952
#endif
7953
#if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
7954
   /* Alpha specific */
7955
    case TARGET_NR_getxgid:
7956
         {
7957
            uid_t egid;
7958
            egid=getegid();
7959
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
7960
         }
7961
        ret = get_errno(getgid());
7962
        break;
7963
#endif
7964
#if defined(TARGET_NR_osf_getsysinfo) && defined(TARGET_ALPHA)
7965
    /* Alpha specific */
7966
    case TARGET_NR_osf_getsysinfo:
7967
        ret = -TARGET_EOPNOTSUPP;
7968
        switch (arg1) {
7969
          case TARGET_GSI_IEEE_FP_CONTROL:
7970
            {
7971
                uint64_t swcr, fpcr = cpu_alpha_load_fpcr (cpu_env);
7972

    
7973
                /* Copied from linux ieee_fpcr_to_swcr.  */
7974
                swcr = (fpcr >> 35) & SWCR_STATUS_MASK;
7975
                swcr |= (fpcr >> 36) & SWCR_MAP_DMZ;
7976
                swcr |= (~fpcr >> 48) & (SWCR_TRAP_ENABLE_INV
7977
                                        | SWCR_TRAP_ENABLE_DZE
7978
                                        | SWCR_TRAP_ENABLE_OVF);
7979
                swcr |= (~fpcr >> 57) & (SWCR_TRAP_ENABLE_UNF
7980
                                        | SWCR_TRAP_ENABLE_INE);
7981
                swcr |= (fpcr >> 47) & SWCR_MAP_UMZ;
7982
                swcr |= (~fpcr >> 41) & SWCR_TRAP_ENABLE_DNO;
7983

    
7984
                if (put_user_u64 (swcr, arg2))
7985
                        goto efault;
7986
                ret = 0;
7987
            }
7988
            break;
7989

    
7990
          /* case GSI_IEEE_STATE_AT_SIGNAL:
7991
             -- Not implemented in linux kernel.
7992
             case GSI_UACPROC:
7993
             -- Retrieves current unaligned access state; not much used.
7994
             case GSI_PROC_TYPE:
7995
             -- Retrieves implver information; surely not used.
7996
             case GSI_GET_HWRPB:
7997
             -- Grabs a copy of the HWRPB; surely not used.
7998
          */
7999
        }
8000
        break;
8001
#endif
8002
#if defined(TARGET_NR_osf_setsysinfo) && defined(TARGET_ALPHA)
8003
    /* Alpha specific */
8004
    case TARGET_NR_osf_setsysinfo:
8005
        ret = -TARGET_EOPNOTSUPP;
8006
        switch (arg1) {
8007
          case TARGET_SSI_IEEE_FP_CONTROL:
8008
            {
8009
                uint64_t swcr, fpcr, orig_fpcr;
8010

    
8011
                if (get_user_u64 (swcr, arg2)) {
8012
                    goto efault;
8013
                }
8014
                orig_fpcr = cpu_alpha_load_fpcr(cpu_env);
8015
                fpcr = orig_fpcr & FPCR_DYN_MASK;
8016

    
8017
                /* Copied from linux ieee_swcr_to_fpcr.  */
8018
                fpcr |= (swcr & SWCR_STATUS_MASK) << 35;
8019
                fpcr |= (swcr & SWCR_MAP_DMZ) << 36;
8020
                fpcr |= (~swcr & (SWCR_TRAP_ENABLE_INV
8021
                                  | SWCR_TRAP_ENABLE_DZE
8022
                                  | SWCR_TRAP_ENABLE_OVF)) << 48;
8023
                fpcr |= (~swcr & (SWCR_TRAP_ENABLE_UNF
8024
                                  | SWCR_TRAP_ENABLE_INE)) << 57;
8025
                fpcr |= (swcr & SWCR_MAP_UMZ ? FPCR_UNDZ | FPCR_UNFD : 0);
8026
                fpcr |= (~swcr & SWCR_TRAP_ENABLE_DNO) << 41;
8027

    
8028
                cpu_alpha_store_fpcr(cpu_env, fpcr);
8029
                ret = 0;
8030
            }
8031
            break;
8032

    
8033
          case TARGET_SSI_IEEE_RAISE_EXCEPTION:
8034
            {
8035
                uint64_t exc, fpcr, orig_fpcr;
8036
                int si_code;
8037

    
8038
                if (get_user_u64(exc, arg2)) {
8039
                    goto efault;
8040
                }
8041

    
8042
                orig_fpcr = cpu_alpha_load_fpcr(cpu_env);
8043

    
8044
                /* We only add to the exception status here.  */
8045
                fpcr = orig_fpcr | ((exc & SWCR_STATUS_MASK) << 35);
8046

    
8047
                cpu_alpha_store_fpcr(cpu_env, fpcr);
8048
                ret = 0;
8049

    
8050
                /* Old exceptions are not signaled.  */
8051
                fpcr &= ~(orig_fpcr & FPCR_STATUS_MASK);
8052

    
8053
                /* If any exceptions set by this call,
8054
                   and are unmasked, send a signal.  */
8055
                si_code = 0;
8056
                if ((fpcr & (FPCR_INE | FPCR_INED)) == FPCR_INE) {
8057
                    si_code = TARGET_FPE_FLTRES;
8058
                }
8059
                if ((fpcr & (FPCR_UNF | FPCR_UNFD)) == FPCR_UNF) {
8060
                    si_code = TARGET_FPE_FLTUND;
8061
                }
8062
                if ((fpcr & (FPCR_OVF | FPCR_OVFD)) == FPCR_OVF) {
8063
                    si_code = TARGET_FPE_FLTOVF;
8064
                }
8065
                if ((fpcr & (FPCR_DZE | FPCR_DZED)) == FPCR_DZE) {
8066
                    si_code = TARGET_FPE_FLTDIV;
8067
                }
8068
                if ((fpcr & (FPCR_INV | FPCR_INVD)) == FPCR_INV) {
8069
                    si_code = TARGET_FPE_FLTINV;
8070
                }
8071
                if (si_code != 0) {
8072
                    target_siginfo_t info;
8073
                    info.si_signo = SIGFPE;
8074
                    info.si_errno = 0;
8075
                    info.si_code = si_code;
8076
                    info._sifields._sigfault._addr
8077
                        = ((CPUArchState *)cpu_env)->pc;
8078
                    queue_signal((CPUArchState *)cpu_env, info.si_signo, &info);
8079
                }
8080
            }
8081
            break;
8082

    
8083
          /* case SSI_NVPAIRS:
8084
             -- Used with SSIN_UACPROC to enable unaligned accesses.
8085
             case SSI_IEEE_STATE_AT_SIGNAL:
8086
             case SSI_IEEE_IGNORE_STATE_AT_SIGNAL:
8087
             -- Not implemented in linux kernel
8088
          */
8089
        }
8090
        break;
8091
#endif
8092
#ifdef TARGET_NR_osf_sigprocmask
8093
    /* Alpha specific.  */
8094
    case TARGET_NR_osf_sigprocmask:
8095
        {
8096
            abi_ulong mask;
8097
            int how;
8098
            sigset_t set, oldset;
8099

    
8100
            switch(arg1) {
8101
            case TARGET_SIG_BLOCK:
8102
                how = SIG_BLOCK;
8103
                break;
8104
            case TARGET_SIG_UNBLOCK:
8105
                how = SIG_UNBLOCK;
8106
                break;
8107
            case TARGET_SIG_SETMASK:
8108
                how = SIG_SETMASK;
8109
                break;
8110
            default:
8111
                ret = -TARGET_EINVAL;
8112
                goto fail;
8113
            }
8114
            mask = arg2;
8115
            target_to_host_old_sigset(&set, &mask);
8116
            sigprocmask(how, &set, &oldset);
8117
            host_to_target_old_sigset(&mask, &oldset);
8118
            ret = mask;
8119
        }
8120
        break;
8121
#endif
8122

    
8123
#ifdef TARGET_NR_getgid32
8124
    case TARGET_NR_getgid32:
8125
        ret = get_errno(getgid());
8126
        break;
8127
#endif
8128
#ifdef TARGET_NR_geteuid32
8129
    case TARGET_NR_geteuid32:
8130
        ret = get_errno(geteuid());
8131
        break;
8132
#endif
8133
#ifdef TARGET_NR_getegid32
8134
    case TARGET_NR_getegid32:
8135
        ret = get_errno(getegid());
8136
        break;
8137
#endif
8138
#ifdef TARGET_NR_setreuid32
8139
    case TARGET_NR_setreuid32:
8140
        ret = get_errno(setreuid(arg1, arg2));
8141
        break;
8142
#endif
8143
#ifdef TARGET_NR_setregid32
8144
    case TARGET_NR_setregid32:
8145
        ret = get_errno(setregid(arg1, arg2));
8146
        break;
8147
#endif
8148
#ifdef TARGET_NR_getgroups32
8149
    case TARGET_NR_getgroups32:
8150
        {
8151
            int gidsetsize = arg1;
8152
            uint32_t *target_grouplist;
8153
            gid_t *grouplist;
8154
            int i;
8155

    
8156
            grouplist = alloca(gidsetsize * sizeof(gid_t));
8157
            ret = get_errno(getgroups(gidsetsize, grouplist));
8158
            if (gidsetsize == 0)
8159
                break;
8160
            if (!is_error(ret)) {
8161
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
8162
                if (!target_grouplist) {
8163
                    ret = -TARGET_EFAULT;
8164
                    goto fail;
8165
                }
8166
                for(i = 0;i < ret; i++)
8167
                    target_grouplist[i] = tswap32(grouplist[i]);
8168
                unlock_user(target_grouplist, arg2, gidsetsize * 4);
8169
            }
8170
        }
8171
        break;
8172
#endif
8173
#ifdef TARGET_NR_setgroups32
8174
    case TARGET_NR_setgroups32:
8175
        {
8176
            int gidsetsize = arg1;
8177
            uint32_t *target_grouplist;
8178
            gid_t *grouplist;
8179
            int i;
8180

    
8181
            grouplist = alloca(gidsetsize * sizeof(gid_t));
8182
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
8183
            if (!target_grouplist) {
8184
                ret = -TARGET_EFAULT;
8185
                goto fail;
8186
            }
8187
            for(i = 0;i < gidsetsize; i++)
8188
                grouplist[i] = tswap32(target_grouplist[i]);
8189
            unlock_user(target_grouplist, arg2, 0);
8190
            ret = get_errno(setgroups(gidsetsize, grouplist));
8191
        }
8192
        break;
8193
#endif
8194
#ifdef TARGET_NR_fchown32
8195
    case TARGET_NR_fchown32:
8196
        ret = get_errno(fchown(arg1, arg2, arg3));
8197
        break;
8198
#endif
8199
#ifdef TARGET_NR_setresuid32
8200
    case TARGET_NR_setresuid32:
8201
        ret = get_errno(setresuid(arg1, arg2, arg3));
8202
        break;
8203
#endif
8204
#ifdef TARGET_NR_getresuid32
8205
    case TARGET_NR_getresuid32:
8206
        {
8207
            uid_t ruid, euid, suid;
8208
            ret = get_errno(getresuid(&ruid, &euid, &suid));
8209
            if (!is_error(ret)) {
8210
                if (put_user_u32(ruid, arg1)
8211
                    || put_user_u32(euid, arg2)
8212
                    || put_user_u32(suid, arg3))
8213
                    goto efault;
8214
            }
8215
        }
8216
        break;
8217
#endif
8218
#ifdef TARGET_NR_setresgid32
8219
    case TARGET_NR_setresgid32:
8220
        ret = get_errno(setresgid(arg1, arg2, arg3));
8221
        break;
8222
#endif
8223
#ifdef TARGET_NR_getresgid32
8224
    case TARGET_NR_getresgid32:
8225
        {
8226
            gid_t rgid, egid, sgid;
8227
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
8228
            if (!is_error(ret)) {
8229
                if (put_user_u32(rgid, arg1)
8230
                    || put_user_u32(egid, arg2)
8231
                    || put_user_u32(sgid, arg3))
8232
                    goto efault;
8233
            }
8234
        }
8235
        break;
8236
#endif
8237
#ifdef TARGET_NR_chown32
8238
    case TARGET_NR_chown32:
8239
        if (!(p = lock_user_string(arg1)))
8240
            goto efault;
8241
        ret = get_errno(chown(p, arg2, arg3));
8242
        unlock_user(p, arg1, 0);
8243
        break;
8244
#endif
8245
#ifdef TARGET_NR_setuid32
8246
    case TARGET_NR_setuid32:
8247
        ret = get_errno(setuid(arg1));
8248
        break;
8249
#endif
8250
#ifdef TARGET_NR_setgid32
8251
    case TARGET_NR_setgid32:
8252
        ret = get_errno(setgid(arg1));
8253
        break;
8254
#endif
8255
#ifdef TARGET_NR_setfsuid32
8256
    case TARGET_NR_setfsuid32:
8257
        ret = get_errno(setfsuid(arg1));
8258
        break;
8259
#endif
8260
#ifdef TARGET_NR_setfsgid32
8261
    case TARGET_NR_setfsgid32:
8262
        ret = get_errno(setfsgid(arg1));
8263
        break;
8264
#endif
8265

    
8266
    case TARGET_NR_pivot_root:
8267
        goto unimplemented;
8268
#ifdef TARGET_NR_mincore
8269
    case TARGET_NR_mincore:
8270
        {
8271
            void *a;
8272
            ret = -TARGET_EFAULT;
8273
            if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
8274
                goto efault;
8275
            if (!(p = lock_user_string(arg3)))
8276
                goto mincore_fail;
8277
            ret = get_errno(mincore(a, arg2, p));
8278
            unlock_user(p, arg3, ret);
8279
            mincore_fail:
8280
            unlock_user(a, arg1, 0);
8281
        }
8282
        break;
8283
#endif
8284
#ifdef TARGET_NR_arm_fadvise64_64
8285
    case TARGET_NR_arm_fadvise64_64:
8286
        {
8287
                /*
8288
                 * arm_fadvise64_64 looks like fadvise64_64 but
8289
                 * with different argument order
8290
                 */
8291
                abi_long temp;
8292
                temp = arg3;
8293
                arg3 = arg4;
8294
                arg4 = temp;
8295
        }
8296
#endif
8297
#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64) || defined(TARGET_NR_fadvise64)
8298
#ifdef TARGET_NR_fadvise64_64
8299
    case TARGET_NR_fadvise64_64:
8300
#endif
8301
#ifdef TARGET_NR_fadvise64
8302
    case TARGET_NR_fadvise64:
8303
#endif
8304
#ifdef TARGET_S390X
8305
        switch (arg4) {
8306
        case 4: arg4 = POSIX_FADV_NOREUSE + 1; break; /* make sure it's an invalid value */
8307
        case 5: arg4 = POSIX_FADV_NOREUSE + 2; break; /* ditto */
8308
        case 6: arg4 = POSIX_FADV_DONTNEED; break;
8309
        case 7: arg4 = POSIX_FADV_NOREUSE; break;
8310
        default: break;
8311
        }
8312
#endif
8313
        ret = -posix_fadvise(arg1, arg2, arg3, arg4);
8314
        break;
8315
#endif
8316
#ifdef TARGET_NR_madvise
8317
    case TARGET_NR_madvise:
8318
        /* A straight passthrough may not be safe because qemu sometimes
8319
           turns private file-backed mappings into anonymous mappings.
8320
           This will break MADV_DONTNEED.
8321
           This is a hint, so ignoring and returning success is ok.  */
8322
        ret = get_errno(0);
8323
        break;
8324
#endif
8325
#if TARGET_ABI_BITS == 32
8326
    case TARGET_NR_fcntl64:
8327
    {
8328
        int cmd;
8329
        struct flock64 fl;
8330
        struct target_flock64 *target_fl;
8331
#ifdef TARGET_ARM
8332
        struct target_eabi_flock64 *target_efl;
8333
#endif
8334

    
8335
        cmd = target_to_host_fcntl_cmd(arg2);
8336
        if (cmd == -TARGET_EINVAL) {
8337
            ret = cmd;
8338
            break;
8339
        }
8340

    
8341
        switch(arg2) {
8342
        case TARGET_F_GETLK64:
8343
#ifdef TARGET_ARM
8344
            if (((CPUARMState *)cpu_env)->eabi) {
8345
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
8346
                    goto efault;
8347
                fl.l_type = tswap16(target_efl->l_type);
8348
                fl.l_whence = tswap16(target_efl->l_whence);
8349
                fl.l_start = tswap64(target_efl->l_start);
8350
                fl.l_len = tswap64(target_efl->l_len);
8351
                fl.l_pid = tswap32(target_efl->l_pid);
8352
                unlock_user_struct(target_efl, arg3, 0);
8353
            } else
8354
#endif
8355
            {
8356
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
8357
                    goto efault;
8358
                fl.l_type = tswap16(target_fl->l_type);
8359
                fl.l_whence = tswap16(target_fl->l_whence);
8360
                fl.l_start = tswap64(target_fl->l_start);
8361
                fl.l_len = tswap64(target_fl->l_len);
8362
                fl.l_pid = tswap32(target_fl->l_pid);
8363
                unlock_user_struct(target_fl, arg3, 0);
8364
            }
8365
            ret = get_errno(fcntl(arg1, cmd, &fl));
8366
            if (ret == 0) {
8367
#ifdef TARGET_ARM
8368
                if (((CPUARMState *)cpu_env)->eabi) {
8369
                    if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) 
8370
                        goto efault;
8371
                    target_efl->l_type = tswap16(fl.l_type);
8372
                    target_efl->l_whence = tswap16(fl.l_whence);
8373
                    target_efl->l_start = tswap64(fl.l_start);
8374
                    target_efl->l_len = tswap64(fl.l_len);
8375
                    target_efl->l_pid = tswap32(fl.l_pid);
8376
                    unlock_user_struct(target_efl, arg3, 1);
8377
                } else
8378
#endif
8379
                {
8380
                    if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) 
8381
                        goto efault;
8382
                    target_fl->l_type = tswap16(fl.l_type);
8383
                    target_fl->l_whence = tswap16(fl.l_whence);
8384
                    target_fl->l_start = tswap64(fl.l_start);
8385
                    target_fl->l_len = tswap64(fl.l_len);
8386
                    target_fl->l_pid = tswap32(fl.l_pid);
8387
                    unlock_user_struct(target_fl, arg3, 1);
8388
                }
8389
            }
8390
            break;
8391

    
8392
        case TARGET_F_SETLK64:
8393
        case TARGET_F_SETLKW64:
8394
#ifdef TARGET_ARM
8395
            if (((CPUARMState *)cpu_env)->eabi) {
8396
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
8397
                    goto efault;
8398
                fl.l_type = tswap16(target_efl->l_type);
8399
                fl.l_whence = tswap16(target_efl->l_whence);
8400
                fl.l_start = tswap64(target_efl->l_start);
8401
                fl.l_len = tswap64(target_efl->l_len);
8402
                fl.l_pid = tswap32(target_efl->l_pid);
8403
                unlock_user_struct(target_efl, arg3, 0);
8404
            } else
8405
#endif
8406
            {
8407
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
8408
                    goto efault;
8409
                fl.l_type = tswap16(target_fl->l_type);
8410
                fl.l_whence = tswap16(target_fl->l_whence);
8411
                fl.l_start = tswap64(target_fl->l_start);
8412
                fl.l_len = tswap64(target_fl->l_len);
8413
                fl.l_pid = tswap32(target_fl->l_pid);
8414
                unlock_user_struct(target_fl, arg3, 0);
8415
            }
8416
            ret = get_errno(fcntl(arg1, cmd, &fl));
8417
            break;
8418
        default:
8419
            ret = do_fcntl(arg1, arg2, arg3);
8420
            break;
8421
        }
8422
        break;
8423
    }
8424
#endif
8425
#ifdef TARGET_NR_cacheflush
8426
    case TARGET_NR_cacheflush:
8427
        /* self-modifying code is handled automatically, so nothing needed */
8428
        ret = 0;
8429
        break;
8430
#endif
8431
#ifdef TARGET_NR_security
8432
    case TARGET_NR_security:
8433
        goto unimplemented;
8434
#endif
8435
#ifdef TARGET_NR_getpagesize
8436
    case TARGET_NR_getpagesize:
8437
        ret = TARGET_PAGE_SIZE;
8438
        break;
8439
#endif
8440
    case TARGET_NR_gettid:
8441
        ret = get_errno(gettid());
8442
        break;
8443
#ifdef TARGET_NR_readahead
8444
    case TARGET_NR_readahead:
8445
#if TARGET_ABI_BITS == 32
8446
        if (regpairs_aligned(cpu_env)) {
8447
            arg2 = arg3;
8448
            arg3 = arg4;
8449
            arg4 = arg5;
8450
        }
8451
        ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
8452
#else
8453
        ret = get_errno(readahead(arg1, arg2, arg3));
8454
#endif
8455
        break;
8456
#endif
8457
#ifdef CONFIG_ATTR
8458
#ifdef TARGET_NR_setxattr
8459
    case TARGET_NR_listxattr:
8460
    case TARGET_NR_llistxattr:
8461
    {
8462
        void *p, *b = 0;
8463
        if (arg2) {
8464
            b = lock_user(VERIFY_WRITE, arg2, arg3, 0);
8465
            if (!b) {
8466
                ret = -TARGET_EFAULT;
8467
                break;
8468
            }
8469
        }
8470
        p = lock_user_string(arg1);
8471
        if (p) {
8472
            if (num == TARGET_NR_listxattr) {
8473
                ret = get_errno(listxattr(p, b, arg3));
8474
            } else {
8475
                ret = get_errno(llistxattr(p, b, arg3));
8476
            }
8477
        } else {
8478
            ret = -TARGET_EFAULT;
8479
        }
8480
        unlock_user(p, arg1, 0);
8481
        unlock_user(b, arg2, arg3);
8482
        break;
8483
    }
8484
    case TARGET_NR_flistxattr:
8485
    {
8486
        void *b = 0;
8487
        if (arg2) {
8488
            b = lock_user(VERIFY_WRITE, arg2, arg3, 0);
8489
            if (!b) {
8490
                ret = -TARGET_EFAULT;
8491
                break;
8492
            }
8493
        }
8494
        ret = get_errno(flistxattr(arg1, b, arg3));
8495
        unlock_user(b, arg2, arg3);
8496
        break;
8497
    }
8498
    case TARGET_NR_setxattr:
8499
    case TARGET_NR_lsetxattr:
8500
        {
8501
            void *p, *n, *v = 0;
8502
            if (arg3) {
8503
                v = lock_user(VERIFY_READ, arg3, arg4, 1);
8504
                if (!v) {
8505
                    ret = -TARGET_EFAULT;
8506
                    break;
8507
                }
8508
            }
8509
            p = lock_user_string(arg1);
8510
            n = lock_user_string(arg2);
8511
            if (p && n) {
8512
                if (num == TARGET_NR_setxattr) {
8513
                    ret = get_errno(setxattr(p, n, v, arg4, arg5));
8514
                } else {
8515
                    ret = get_errno(lsetxattr(p, n, v, arg4, arg5));
8516
                }
8517
            } else {
8518
                ret = -TARGET_EFAULT;
8519
            }
8520
            unlock_user(p, arg1, 0);
8521
            unlock_user(n, arg2, 0);
8522
            unlock_user(v, arg3, 0);
8523
        }
8524
        break;
8525
    case TARGET_NR_fsetxattr:
8526
        {
8527
            void *n, *v = 0;
8528
            if (arg3) {
8529
                v = lock_user(VERIFY_READ, arg3, arg4, 1);
8530
                if (!v) {
8531
                    ret = -TARGET_EFAULT;
8532
                    break;
8533
                }
8534
            }
8535
            n = lock_user_string(arg2);
8536
            if (n) {
8537
                ret = get_errno(fsetxattr(arg1, n, v, arg4, arg5));
8538
            } else {
8539
                ret = -TARGET_EFAULT;
8540
            }
8541
            unlock_user(n, arg2, 0);
8542
            unlock_user(v, arg3, 0);
8543
        }
8544
        break;
8545
    case TARGET_NR_getxattr:
8546
    case TARGET_NR_lgetxattr:
8547
        {
8548
            void *p, *n, *v = 0;
8549
            if (arg3) {
8550
                v = lock_user(VERIFY_WRITE, arg3, arg4, 0);
8551
                if (!v) {
8552
                    ret = -TARGET_EFAULT;
8553
                    break;
8554
                }
8555
            }
8556
            p = lock_user_string(arg1);
8557
            n = lock_user_string(arg2);
8558
            if (p && n) {
8559
                if (num == TARGET_NR_getxattr) {
8560
                    ret = get_errno(getxattr(p, n, v, arg4));
8561
                } else {
8562
                    ret = get_errno(lgetxattr(p, n, v, arg4));
8563
                }
8564
            } else {
8565
                ret = -TARGET_EFAULT;
8566
            }
8567
            unlock_user(p, arg1, 0);
8568
            unlock_user(n, arg2, 0);
8569
            unlock_user(v, arg3, arg4);
8570
        }
8571
        break;
8572
    case TARGET_NR_fgetxattr:
8573
        {
8574
            void *n, *v = 0;
8575
            if (arg3) {
8576
                v = lock_user(VERIFY_WRITE, arg3, arg4, 0);
8577
                if (!v) {
8578
                    ret = -TARGET_EFAULT;
8579
                    break;
8580
                }
8581
            }
8582
            n = lock_user_string(arg2);
8583
            if (n) {
8584
                ret = get_errno(fgetxattr(arg1, n, v, arg4));
8585
            } else {
8586
                ret = -TARGET_EFAULT;
8587
            }
8588
            unlock_user(n, arg2, 0);
8589
            unlock_user(v, arg3, arg4);
8590
        }
8591
        break;
8592
    case TARGET_NR_removexattr:
8593
    case TARGET_NR_lremovexattr:
8594
        {
8595
            void *p, *n;
8596
            p = lock_user_string(arg1);
8597
            n = lock_user_string(arg2);
8598
            if (p && n) {
8599
                if (num == TARGET_NR_removexattr) {
8600
                    ret = get_errno(removexattr(p, n));
8601
                } else {
8602
                    ret = get_errno(lremovexattr(p, n));
8603
                }
8604
            } else {
8605
                ret = -TARGET_EFAULT;
8606
            }
8607
            unlock_user(p, arg1, 0);
8608
            unlock_user(n, arg2, 0);
8609
        }
8610
        break;
8611
    case TARGET_NR_fremovexattr:
8612
        {
8613
            void *n;
8614
            n = lock_user_string(arg2);
8615
            if (n) {
8616
                ret = get_errno(fremovexattr(arg1, n));
8617
            } else {
8618
                ret = -TARGET_EFAULT;
8619
            }
8620
            unlock_user(n, arg2, 0);
8621
        }
8622
        break;
8623
#endif
8624
#endif /* CONFIG_ATTR */
8625
#ifdef TARGET_NR_set_thread_area
8626
    case TARGET_NR_set_thread_area:
8627
#if defined(TARGET_MIPS)
8628
      ((CPUMIPSState *) cpu_env)->tls_value = arg1;
8629
      ret = 0;
8630
      break;
8631
#elif defined(TARGET_CRIS)
8632
      if (arg1 & 0xff)
8633
          ret = -TARGET_EINVAL;
8634
      else {
8635
          ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
8636
          ret = 0;
8637
      }
8638
      break;
8639
#elif defined(TARGET_I386) && defined(TARGET_ABI32)
8640
      ret = do_set_thread_area(cpu_env, arg1);
8641
      break;
8642
#elif defined(TARGET_M68K)
8643
      {
8644
          TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
8645
          ts->tp_value = arg1;
8646
          ret = 0;
8647
          break;
8648
      }
8649
#else
8650
      goto unimplemented_nowarn;
8651
#endif
8652
#endif
8653
#ifdef TARGET_NR_get_thread_area
8654
    case TARGET_NR_get_thread_area:
8655
#if defined(TARGET_I386) && defined(TARGET_ABI32)
8656
        ret = do_get_thread_area(cpu_env, arg1);
8657
        break;
8658
#elif defined(TARGET_M68K)
8659
        {
8660
            TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
8661
            ret = ts->tp_value;
8662
            break;
8663
        }
8664
#else
8665
        goto unimplemented_nowarn;
8666
#endif
8667
#endif
8668
#ifdef TARGET_NR_getdomainname
8669
    case TARGET_NR_getdomainname:
8670
        goto unimplemented_nowarn;
8671
#endif
8672

    
8673
#ifdef TARGET_NR_clock_gettime
8674
    case TARGET_NR_clock_gettime:
8675
    {
8676
        struct timespec ts;
8677
        ret = get_errno(clock_gettime(arg1, &ts));
8678
        if (!is_error(ret)) {
8679
            host_to_target_timespec(arg2, &ts);
8680
        }
8681
        break;
8682
    }
8683
#endif
8684
#ifdef TARGET_NR_clock_getres
8685
    case TARGET_NR_clock_getres:
8686
    {
8687
        struct timespec ts;
8688
        ret = get_errno(clock_getres(arg1, &ts));
8689
        if (!is_error(ret)) {
8690
            host_to_target_timespec(arg2, &ts);
8691
        }
8692
        break;
8693
    }
8694
#endif
8695
#ifdef TARGET_NR_clock_nanosleep
8696
    case TARGET_NR_clock_nanosleep:
8697
    {
8698
        struct timespec ts;
8699
        target_to_host_timespec(&ts, arg3);
8700
        ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
8701
        if (arg4)
8702
            host_to_target_timespec(arg4, &ts);
8703
        break;
8704
    }
8705
#endif
8706

    
8707
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
8708
    case TARGET_NR_set_tid_address:
8709
        ret = get_errno(set_tid_address((int *)g2h(arg1)));
8710
        break;
8711
#endif
8712

    
8713
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
8714
    case TARGET_NR_tkill:
8715
        ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
8716
        break;
8717
#endif
8718

    
8719
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
8720
    case TARGET_NR_tgkill:
8721
        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
8722
                        target_to_host_signal(arg3)));
8723
        break;
8724
#endif
8725

    
8726
#ifdef TARGET_NR_set_robust_list
8727
    case TARGET_NR_set_robust_list:
8728
    case TARGET_NR_get_robust_list:
8729
        /* The ABI for supporting robust futexes has userspace pass
8730
         * the kernel a pointer to a linked list which is updated by
8731
         * userspace after the syscall; the list is walked by the kernel
8732
         * when the thread exits. Since the linked list in QEMU guest
8733
         * memory isn't a valid linked list for the host and we have
8734
         * no way to reliably intercept the thread-death event, we can't
8735
         * support these. Silently return ENOSYS so that guest userspace
8736
         * falls back to a non-robust futex implementation (which should
8737
         * be OK except in the corner case of the guest crashing while
8738
         * holding a mutex that is shared with another process via
8739
         * shared memory).
8740
         */
8741
        goto unimplemented_nowarn;
8742
#endif
8743

    
8744
#if defined(TARGET_NR_utimensat)
8745
    case TARGET_NR_utimensat:
8746
        {
8747
            struct timespec *tsp, ts[2];
8748
            if (!arg3) {
8749
                tsp = NULL;
8750
            } else {
8751
                target_to_host_timespec(ts, arg3);
8752
                target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
8753
                tsp = ts;
8754
            }
8755
            if (!arg2)
8756
                ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4));
8757
            else {
8758
                if (!(p = lock_user_string(arg2))) {
8759
                    ret = -TARGET_EFAULT;
8760
                    goto fail;
8761
                }
8762
                ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4));
8763
                unlock_user(p, arg2, 0);
8764
            }
8765
        }
8766
        break;
8767
#endif
8768
    case TARGET_NR_futex:
8769
        ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
8770
        break;
8771
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
8772
    case TARGET_NR_inotify_init:
8773
        ret = get_errno(sys_inotify_init());
8774
        break;
8775
#endif
8776
#ifdef CONFIG_INOTIFY1
8777
#if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
8778
    case TARGET_NR_inotify_init1:
8779
        ret = get_errno(sys_inotify_init1(arg1));
8780
        break;
8781
#endif
8782
#endif
8783
#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
8784
    case TARGET_NR_inotify_add_watch:
8785
        p = lock_user_string(arg2);
8786
        ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
8787
        unlock_user(p, arg2, 0);
8788
        break;
8789
#endif
8790
#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
8791
    case TARGET_NR_inotify_rm_watch:
8792
        ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
8793
        break;
8794
#endif
8795

    
8796
#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
8797
    case TARGET_NR_mq_open:
8798
        {
8799
            struct mq_attr posix_mq_attr;
8800

    
8801
            p = lock_user_string(arg1 - 1);
8802
            if (arg4 != 0)
8803
                copy_from_user_mq_attr (&posix_mq_attr, arg4);
8804
            ret = get_errno(mq_open(p, arg2, arg3, &posix_mq_attr));
8805
            unlock_user (p, arg1, 0);
8806
        }
8807
        break;
8808

    
8809
    case TARGET_NR_mq_unlink:
8810
        p = lock_user_string(arg1 - 1);
8811
        ret = get_errno(mq_unlink(p));
8812
        unlock_user (p, arg1, 0);
8813
        break;
8814

    
8815
    case TARGET_NR_mq_timedsend:
8816
        {
8817
            struct timespec ts;
8818

    
8819
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
8820
            if (arg5 != 0) {
8821
                target_to_host_timespec(&ts, arg5);
8822
                ret = get_errno(mq_timedsend(arg1, p, arg3, arg4, &ts));
8823
                host_to_target_timespec(arg5, &ts);
8824
            }
8825
            else
8826
                ret = get_errno(mq_send(arg1, p, arg3, arg4));
8827
            unlock_user (p, arg2, arg3);
8828
        }
8829
        break;
8830

    
8831
    case TARGET_NR_mq_timedreceive:
8832
        {
8833
            struct timespec ts;
8834
            unsigned int prio;
8835

    
8836
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
8837
            if (arg5 != 0) {
8838
                target_to_host_timespec(&ts, arg5);
8839
                ret = get_errno(mq_timedreceive(arg1, p, arg3, &prio, &ts));
8840
                host_to_target_timespec(arg5, &ts);
8841
            }
8842
            else
8843
                ret = get_errno(mq_receive(arg1, p, arg3, &prio));
8844
            unlock_user (p, arg2, arg3);
8845
            if (arg4 != 0)
8846
                put_user_u32(prio, arg4);
8847
        }
8848
        break;
8849

    
8850
    /* Not implemented for now... */
8851
/*     case TARGET_NR_mq_notify: */
8852
/*         break; */
8853

    
8854
    case TARGET_NR_mq_getsetattr:
8855
        {
8856
            struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
8857
            ret = 0;
8858
            if (arg3 != 0) {
8859
                ret = mq_getattr(arg1, &posix_mq_attr_out);
8860
                copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
8861
            }
8862
            if (arg2 != 0) {
8863
                copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
8864
                ret |= mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_attr_out);
8865
            }
8866

    
8867
        }
8868
        break;
8869
#endif
8870

    
8871
#ifdef CONFIG_SPLICE
8872
#ifdef TARGET_NR_tee
8873
    case TARGET_NR_tee:
8874
        {
8875
            ret = get_errno(tee(arg1,arg2,arg3,arg4));
8876
        }
8877
        break;
8878
#endif
8879
#ifdef TARGET_NR_splice
8880
    case TARGET_NR_splice:
8881
        {
8882
            loff_t loff_in, loff_out;
8883
            loff_t *ploff_in = NULL, *ploff_out = NULL;
8884
            if(arg2) {
8885
                get_user_u64(loff_in, arg2);
8886
                ploff_in = &loff_in;
8887
            }
8888
            if(arg4) {
8889
                get_user_u64(loff_out, arg2);
8890
                ploff_out = &loff_out;
8891
            }
8892
            ret = get_errno(splice(arg1, ploff_in, arg3, ploff_out, arg5, arg6));
8893
        }
8894
        break;
8895
#endif
8896
#ifdef TARGET_NR_vmsplice
8897
        case TARGET_NR_vmsplice:
8898
        {
8899
            struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
8900
            if (vec != NULL) {
8901
                ret = get_errno(vmsplice(arg1, vec, arg3, arg4));
8902
                unlock_iovec(vec, arg2, arg3, 0);
8903
            } else {
8904
                ret = -host_to_target_errno(errno);
8905
            }
8906
        }
8907
        break;
8908
#endif
8909
#endif /* CONFIG_SPLICE */
8910
#ifdef CONFIG_EVENTFD
8911
#if defined(TARGET_NR_eventfd)
8912
    case TARGET_NR_eventfd:
8913
        ret = get_errno(eventfd(arg1, 0));
8914
        break;
8915
#endif
8916
#if defined(TARGET_NR_eventfd2)
8917
    case TARGET_NR_eventfd2:
8918
    {
8919
        int host_flags = arg2 & (~(TARGET_O_NONBLOCK | TARGET_O_CLOEXEC));
8920
        if (arg2 & TARGET_O_NONBLOCK) {
8921
            host_flags |= O_NONBLOCK;
8922
        }
8923
        if (arg2 & TARGET_O_CLOEXEC) {
8924
            host_flags |= O_CLOEXEC;
8925
        }
8926
        ret = get_errno(eventfd(arg1, host_flags));
8927
        break;
8928
    }
8929
#endif
8930
#endif /* CONFIG_EVENTFD  */
8931
#if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate)
8932
    case TARGET_NR_fallocate:
8933
#if TARGET_ABI_BITS == 32
8934
        ret = get_errno(fallocate(arg1, arg2, target_offset64(arg3, arg4),
8935
                                  target_offset64(arg5, arg6)));
8936
#else
8937
        ret = get_errno(fallocate(arg1, arg2, arg3, arg4));
8938
#endif
8939
        break;
8940
#endif
8941
#if defined(CONFIG_SYNC_FILE_RANGE)
8942
#if defined(TARGET_NR_sync_file_range)
8943
    case TARGET_NR_sync_file_range:
8944
#if TARGET_ABI_BITS == 32
8945
#if defined(TARGET_MIPS)
8946
        ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
8947
                                        target_offset64(arg5, arg6), arg7));
8948
#else
8949
        ret = get_errno(sync_file_range(arg1, target_offset64(arg2, arg3),
8950
                                        target_offset64(arg4, arg5), arg6));
8951
#endif /* !TARGET_MIPS */
8952
#else
8953
        ret = get_errno(sync_file_range(arg1, arg2, arg3, arg4));
8954
#endif
8955
        break;
8956
#endif
8957
#if defined(TARGET_NR_sync_file_range2)
8958
    case TARGET_NR_sync_file_range2:
8959
        /* This is like sync_file_range but the arguments are reordered */
8960
#if TARGET_ABI_BITS == 32
8961
        ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
8962
                                        target_offset64(arg5, arg6), arg2));
8963
#else
8964
        ret = get_errno(sync_file_range(arg1, arg3, arg4, arg2));
8965
#endif
8966
        break;
8967
#endif
8968
#endif
8969
#if defined(CONFIG_EPOLL)
8970
#if defined(TARGET_NR_epoll_create)
8971
    case TARGET_NR_epoll_create:
8972
        ret = get_errno(epoll_create(arg1));
8973
        break;
8974
#endif
8975
#if defined(TARGET_NR_epoll_create1) && defined(CONFIG_EPOLL_CREATE1)
8976
    case TARGET_NR_epoll_create1:
8977
        ret = get_errno(epoll_create1(arg1));
8978
        break;
8979
#endif
8980
#if defined(TARGET_NR_epoll_ctl)
8981
    case TARGET_NR_epoll_ctl:
8982
    {
8983
        struct epoll_event ep;
8984
        struct epoll_event *epp = 0;
8985
        if (arg4) {
8986
            struct target_epoll_event *target_ep;
8987
            if (!lock_user_struct(VERIFY_READ, target_ep, arg4, 1)) {
8988
                goto efault;
8989
            }
8990
            ep.events = tswap32(target_ep->events);
8991
            /* The epoll_data_t union is just opaque data to the kernel,
8992
             * so we transfer all 64 bits across and need not worry what
8993
             * actual data type it is.
8994
             */
8995
            ep.data.u64 = tswap64(target_ep->data.u64);
8996
            unlock_user_struct(target_ep, arg4, 0);
8997
            epp = &ep;
8998
        }
8999
        ret = get_errno(epoll_ctl(arg1, arg2, arg3, epp));
9000
        break;
9001
    }
9002
#endif
9003

    
9004
#if defined(TARGET_NR_epoll_pwait) && defined(CONFIG_EPOLL_PWAIT)
9005
#define IMPLEMENT_EPOLL_PWAIT
9006
#endif
9007
#if defined(TARGET_NR_epoll_wait) || defined(IMPLEMENT_EPOLL_PWAIT)
9008
#if defined(TARGET_NR_epoll_wait)
9009
    case TARGET_NR_epoll_wait:
9010
#endif
9011
#if defined(IMPLEMENT_EPOLL_PWAIT)
9012
    case TARGET_NR_epoll_pwait:
9013
#endif
9014
    {
9015
        struct target_epoll_event *target_ep;
9016
        struct epoll_event *ep;
9017
        int epfd = arg1;
9018
        int maxevents = arg3;
9019
        int timeout = arg4;
9020

    
9021
        target_ep = lock_user(VERIFY_WRITE, arg2,
9022
                              maxevents * sizeof(struct target_epoll_event), 1);
9023
        if (!target_ep) {
9024
            goto efault;
9025
        }
9026

    
9027
        ep = alloca(maxevents * sizeof(struct epoll_event));
9028

    
9029
        switch (num) {
9030
#if defined(IMPLEMENT_EPOLL_PWAIT)
9031
        case TARGET_NR_epoll_pwait:
9032
        {
9033
            target_sigset_t *target_set;
9034
            sigset_t _set, *set = &_set;
9035

    
9036
            if (arg5) {
9037
                target_set = lock_user(VERIFY_READ, arg5,
9038
                                       sizeof(target_sigset_t), 1);
9039
                if (!target_set) {
9040
                    unlock_user(target_ep, arg2, 0);
9041
                    goto efault;
9042
                }
9043
                target_to_host_sigset(set, target_set);
9044
                unlock_user(target_set, arg5, 0);
9045
            } else {
9046
                set = NULL;
9047
            }
9048

    
9049
            ret = get_errno(epoll_pwait(epfd, ep, maxevents, timeout, set));
9050
            break;
9051
        }
9052
#endif
9053
#if defined(TARGET_NR_epoll_wait)
9054
        case TARGET_NR_epoll_wait:
9055
            ret = get_errno(epoll_wait(epfd, ep, maxevents, timeout));
9056
            break;
9057
#endif
9058
        default:
9059
            ret = -TARGET_ENOSYS;
9060
        }
9061
        if (!is_error(ret)) {
9062
            int i;
9063
            for (i = 0; i < ret; i++) {
9064
                target_ep[i].events = tswap32(ep[i].events);
9065
                target_ep[i].data.u64 = tswap64(ep[i].data.u64);
9066
            }
9067
        }
9068
        unlock_user(target_ep, arg2, ret * sizeof(struct target_epoll_event));
9069
        break;
9070
    }
9071
#endif
9072
#endif
9073
#ifdef TARGET_NR_prlimit64
9074
    case TARGET_NR_prlimit64:
9075
    {
9076
        /* args: pid, resource number, ptr to new rlimit, ptr to old rlimit */
9077
        struct target_rlimit64 *target_rnew, *target_rold;
9078
        struct host_rlimit64 rnew, rold, *rnewp = 0;
9079
        if (arg3) {
9080
            if (!lock_user_struct(VERIFY_READ, target_rnew, arg3, 1)) {
9081
                goto efault;
9082
            }
9083
            rnew.rlim_cur = tswap64(target_rnew->rlim_cur);
9084
            rnew.rlim_max = tswap64(target_rnew->rlim_max);
9085
            unlock_user_struct(target_rnew, arg3, 0);
9086
            rnewp = &rnew;
9087
        }
9088

    
9089
        ret = get_errno(sys_prlimit64(arg1, arg2, rnewp, arg4 ? &rold : 0));
9090
        if (!is_error(ret) && arg4) {
9091
            if (!lock_user_struct(VERIFY_WRITE, target_rold, arg4, 1)) {
9092
                goto efault;
9093
            }
9094
            target_rold->rlim_cur = tswap64(rold.rlim_cur);
9095
            target_rold->rlim_max = tswap64(rold.rlim_max);
9096
            unlock_user_struct(target_rold, arg4, 1);
9097
        }
9098
        break;
9099
    }
9100
#endif
9101
#ifdef TARGET_NR_gethostname
9102
    case TARGET_NR_gethostname:
9103
    {
9104
        char *name = lock_user(VERIFY_WRITE, arg1, arg2, 0);
9105
        if (name) {
9106
            ret = get_errno(gethostname(name, arg2));
9107
            unlock_user(name, arg1, arg2);
9108
        } else {
9109
            ret = -TARGET_EFAULT;
9110
        }
9111
        break;
9112
    }
9113
#endif
9114
#ifdef TARGET_NR_atomic_cmpxchg_32
9115
    case TARGET_NR_atomic_cmpxchg_32:
9116
    {
9117
        /* should use start_exclusive from main.c */
9118
        abi_ulong mem_value;
9119
        if (get_user_u32(mem_value, arg6)) {
9120
            target_siginfo_t info;
9121
            info.si_signo = SIGSEGV;
9122
            info.si_errno = 0;
9123
            info.si_code = TARGET_SEGV_MAPERR;
9124
            info._sifields._sigfault._addr = arg6;
9125
            queue_signal((CPUArchState *)cpu_env, info.si_signo, &info);
9126
            ret = 0xdeadbeef;
9127

    
9128
        }
9129
        if (mem_value == arg2)
9130
            put_user_u32(arg1, arg6);
9131
        ret = mem_value;
9132
        break;
9133
    }
9134
#endif
9135
#ifdef TARGET_NR_atomic_barrier
9136
    case TARGET_NR_atomic_barrier:
9137
    {
9138
        /* Like the kernel implementation and the qemu arm barrier, no-op this? */
9139
        break;
9140
    }
9141
#endif
9142

    
9143
#ifdef TARGET_NR_timer_create
9144
    case TARGET_NR_timer_create:
9145
    {
9146
        /* args: clockid_t clockid, struct sigevent *sevp, timer_t *timerid */
9147

    
9148
        struct sigevent host_sevp = { {0}, }, *phost_sevp = NULL;
9149
        struct target_sigevent *ptarget_sevp;
9150
        struct target_timer_t *ptarget_timer;
9151

    
9152
        int clkid = arg1;
9153
        int timer_index = next_free_host_timer();
9154

    
9155
        if (timer_index < 0) {
9156
            ret = -TARGET_EAGAIN;
9157
        } else {
9158
            timer_t *phtimer = g_posix_timers  + timer_index;
9159

    
9160
            if (arg2) {
9161
                if (!lock_user_struct(VERIFY_READ, ptarget_sevp, arg2, 1)) {
9162
                    goto efault;
9163
                }
9164

    
9165
                host_sevp.sigev_signo = tswap32(ptarget_sevp->sigev_signo);
9166
                host_sevp.sigev_notify = tswap32(ptarget_sevp->sigev_notify);
9167

    
9168
                phost_sevp = &host_sevp;
9169
            }
9170

    
9171
            ret = get_errno(timer_create(clkid, phost_sevp, phtimer));
9172
            if (ret) {
9173
                phtimer = NULL;
9174
            } else {
9175
                if (!lock_user_struct(VERIFY_WRITE, ptarget_timer, arg3, 1)) {
9176
                    goto efault;
9177
                }
9178
                ptarget_timer->ptr = tswap32(0xcafe0000 | timer_index);
9179
                unlock_user_struct(ptarget_timer, arg3, 1);
9180
            }
9181
        }
9182
        break;
9183
    }
9184
#endif
9185

    
9186
#ifdef TARGET_NR_timer_settime
9187
    case TARGET_NR_timer_settime:
9188
    {
9189
        /* args: timer_t timerid, int flags, const struct itimerspec *new_value,
9190
         * struct itimerspec * old_value */
9191
        arg1 &= 0xffff;
9192
        if (arg3 == 0 || arg1 < 0 || arg1 >= ARRAY_SIZE(g_posix_timers)) {
9193
            ret = -TARGET_EINVAL;
9194
        } else {
9195
            timer_t htimer = g_posix_timers[arg1];
9196
            struct itimerspec hspec_new = {{0},}, hspec_old = {{0},};
9197

    
9198
            target_to_host_itimerspec(&hspec_new, arg3);
9199
            ret = get_errno(
9200
                          timer_settime(htimer, arg2, &hspec_new, &hspec_old));
9201
            host_to_target_itimerspec(arg2, &hspec_old);
9202
        }
9203
        break;
9204
    }
9205
#endif
9206

    
9207
#ifdef TARGET_NR_timer_gettime
9208
    case TARGET_NR_timer_gettime:
9209
    {
9210
        /* args: timer_t timerid, struct itimerspec *curr_value */
9211
        arg1 &= 0xffff;
9212
        if (!arg2) {
9213
            return -TARGET_EFAULT;
9214
        } else if (arg1 < 0 || arg1 >= ARRAY_SIZE(g_posix_timers)) {
9215
            ret = -TARGET_EINVAL;
9216
        } else {
9217
            timer_t htimer = g_posix_timers[arg1];
9218
            struct itimerspec hspec;
9219
            ret = get_errno(timer_gettime(htimer, &hspec));
9220

    
9221
            if (host_to_target_itimerspec(arg2, &hspec)) {
9222
                ret = -TARGET_EFAULT;
9223
            }
9224
        }
9225
        break;
9226
    }
9227
#endif
9228

    
9229
#ifdef TARGET_NR_timer_getoverrun
9230
    case TARGET_NR_timer_getoverrun:
9231
    {
9232
        /* args: timer_t timerid */
9233
        arg1 &= 0xffff;
9234
        if (arg1 < 0 || arg1 >= ARRAY_SIZE(g_posix_timers)) {
9235
            ret = -TARGET_EINVAL;
9236
        } else {
9237
            timer_t htimer = g_posix_timers[arg1];
9238
            ret = get_errno(timer_getoverrun(htimer));
9239
        }
9240
        break;
9241
    }
9242
#endif
9243

    
9244
#ifdef TARGET_NR_timer_delete
9245
    case TARGET_NR_timer_delete:
9246
    {
9247
        /* args: timer_t timerid */
9248
        arg1 &= 0xffff;
9249
        if (arg1 < 0 || arg1 >= ARRAY_SIZE(g_posix_timers)) {
9250
            ret = -TARGET_EINVAL;
9251
        } else {
9252
            timer_t htimer = g_posix_timers[arg1];
9253
            ret = get_errno(timer_delete(htimer));
9254
            g_posix_timers[arg1] = 0;
9255
        }
9256
        break;
9257
    }
9258
#endif
9259

    
9260
    default:
9261
    unimplemented:
9262
        gemu_log("qemu: Unsupported syscall: %d\n", num);
9263
#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
9264
    unimplemented_nowarn:
9265
#endif
9266
        ret = -TARGET_ENOSYS;
9267
        break;
9268
    }
9269
fail:
9270
#ifdef DEBUG
9271
    gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
9272
#endif
9273
    if(do_strace)
9274
        print_syscall_ret(num, ret);
9275
    return ret;
9276
efault:
9277
    ret = -TARGET_EFAULT;
9278
    goto fail;
9279
}