~ubuntu-branches/ubuntu/trusty/qemu/trusty

« back to all changes in this revision

Viewing changes to .pc/ubuntu/signal-added-a-wrapper-for-sigprocmask-function.patch/linux-user/syscall.c

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn, dann frazier, Serge Hallyn
  • Date: 2014-03-06 16:15:50 UTC
  • Revision ID: package-import@ubuntu.com-20140306161550-83y1d9kr1t4t19tz
Tags: 1.7.0+dfsg-3ubuntu5
[ dann frazier ]
* Add patches from the susematz tree to avoid intermittent segfaults:
   - ubuntu/signal-added-a-wrapper-for-sigprocmask-function.patch
   - ubuntu/signal-sigsegv-protection-on-do_sigprocmask.patch
   - ubuntu/Don-t-block-SIGSEGV-at-more-places.patch

[ Serge Hallyn ]
* Modify do_sigprocmask to only change behavior for aarch64.
  (LP: #1285363)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Linux syscalls
 
3
 *
 
4
 *  Copyright (c) 2003 Fabrice Bellard
 
5
 *
 
6
 *  This program is free software; you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License as published by
 
8
 *  the Free Software Foundation; either version 2 of the License, or
 
9
 *  (at your option) any later version.
 
10
 *
 
11
 *  This program is distributed in the hope that it will be useful,
 
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 *  GNU General Public License for more details.
 
15
 *
 
16
 *  You should have received a copy of the GNU General Public License
 
17
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
 
18
 */
 
19
#define _ATFILE_SOURCE
 
20
#include <stdlib.h>
 
21
#include <stdio.h>
 
22
#include <stdarg.h>
 
23
#include <string.h>
 
24
#include <elf.h>
 
25
#include <endian.h>
 
26
#include <errno.h>
 
27
#include <unistd.h>
 
28
#include <fcntl.h>
 
29
#include <time.h>
 
30
#include <limits.h>
 
31
#include <grp.h>
 
32
#include <sys/types.h>
 
33
#include <sys/ipc.h>
 
34
#include <sys/msg.h>
 
35
#include <sys/wait.h>
 
36
#include <sys/time.h>
 
37
#include <sys/stat.h>
 
38
#include <sys/mount.h>
 
39
#include <sys/file.h>
 
40
#include <sys/fsuid.h>
 
41
#include <sys/personality.h>
 
42
#include <sys/prctl.h>
 
43
#include <sys/resource.h>
 
44
#include <sys/mman.h>
 
45
#include <sys/swap.h>
 
46
#include <signal.h>
 
47
#include <sched.h>
 
48
#ifdef __ia64__
 
49
int __clone2(int (*fn)(void *), void *child_stack_base,
 
50
             size_t stack_size, int flags, void *arg, ...);
 
51
#endif
 
52
#include <sys/socket.h>
 
53
#include <sys/un.h>
 
54
#include <sys/uio.h>
 
55
#include <sys/poll.h>
 
56
#include <sys/times.h>
 
57
#include <sys/shm.h>
 
58
#include <sys/sem.h>
 
59
#include <sys/statfs.h>
 
60
#include <utime.h>
 
61
#include <sys/sysinfo.h>
 
62
#include <sys/utsname.h>
 
63
//#include <sys/user.h>
 
64
#include <netinet/ip.h>
 
65
#include <netinet/tcp.h>
 
66
#include <linux/wireless.h>
 
67
#include <linux/icmp.h>
 
68
#include "qemu-common.h"
 
69
#ifdef TARGET_GPROF
 
70
#include <sys/gmon.h>
 
71
#endif
 
72
#ifdef CONFIG_EVENTFD
 
73
#include <sys/eventfd.h>
 
74
#endif
 
75
#ifdef CONFIG_EPOLL
 
76
#include <sys/epoll.h>
 
77
#endif
 
78
#ifdef CONFIG_ATTR
 
79
#include "qemu/xattr.h"
 
80
#endif
 
81
#ifdef CONFIG_SENDFILE
 
82
#include <sys/sendfile.h>
 
83
#endif
 
84
 
 
85
#define termios host_termios
 
86
#define winsize host_winsize
 
87
#define termio host_termio
 
88
#define sgttyb host_sgttyb /* same as target */
 
89
#define tchars host_tchars /* same as target */
 
90
#define ltchars host_ltchars /* same as target */
 
91
 
 
92
#include <linux/termios.h>
 
93
#include <linux/unistd.h>
 
94
#include <linux/utsname.h>
 
95
#include <linux/cdrom.h>
 
96
#include <linux/hdreg.h>
 
97
#include <linux/soundcard.h>
 
98
#include <linux/kd.h>
 
99
#include <linux/mtio.h>
 
100
#include <linux/fs.h>
 
101
#if defined(CONFIG_FIEMAP)
 
102
#include <linux/fiemap.h>
 
103
#endif
 
104
#include <linux/fb.h>
 
105
#include <linux/vt.h>
 
106
#include <linux/dm-ioctl.h>
 
107
#include <linux/reboot.h>
 
108
#include <linux/route.h>
 
109
#include <linux/filter.h>
 
110
#include "linux_loop.h"
 
111
#include "cpu-uname.h"
 
112
 
 
113
#include "qemu.h"
 
114
 
 
115
#define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
 
116
    CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
 
117
 
 
118
//#define DEBUG
 
119
 
 
120
//#include <linux/msdos_fs.h>
 
121
#define VFAT_IOCTL_READDIR_BOTH         _IOR('r', 1, struct linux_dirent [2])
 
122
#define VFAT_IOCTL_READDIR_SHORT        _IOR('r', 2, struct linux_dirent [2])
 
123
 
 
124
 
 
125
#undef _syscall0
 
126
#undef _syscall1
 
127
#undef _syscall2
 
128
#undef _syscall3
 
129
#undef _syscall4
 
130
#undef _syscall5
 
131
#undef _syscall6
 
132
 
 
133
#define _syscall0(type,name)            \
 
134
static type name (void)                 \
 
135
{                                       \
 
136
        return syscall(__NR_##name);    \
 
137
}
 
138
 
 
139
#define _syscall1(type,name,type1,arg1)         \
 
140
static type name (type1 arg1)                   \
 
141
{                                               \
 
142
        return syscall(__NR_##name, arg1);      \
 
143
}
 
144
 
 
145
#define _syscall2(type,name,type1,arg1,type2,arg2)      \
 
146
static type name (type1 arg1,type2 arg2)                \
 
147
{                                                       \
 
148
        return syscall(__NR_##name, arg1, arg2);        \
 
149
}
 
150
 
 
151
#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)   \
 
152
static type name (type1 arg1,type2 arg2,type3 arg3)             \
 
153
{                                                               \
 
154
        return syscall(__NR_##name, arg1, arg2, arg3);          \
 
155
}
 
156
 
 
157
#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)        \
 
158
static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4)                  \
 
159
{                                                                               \
 
160
        return syscall(__NR_##name, arg1, arg2, arg3, arg4);                    \
 
161
}
 
162
 
 
163
#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,        \
 
164
                  type5,arg5)                                                   \
 
165
static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5)       \
 
166
{                                                                               \
 
167
        return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5);              \
 
168
}
 
169
 
 
170
 
 
171
#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,        \
 
172
                  type5,arg5,type6,arg6)                                        \
 
173
static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,       \
 
174
                  type6 arg6)                                                   \
 
175
{                                                                               \
 
176
        return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6);        \
 
177
}
 
178
 
 
179
 
 
180
#define __NR_sys_uname __NR_uname
 
181
#define __NR_sys_getcwd1 __NR_getcwd
 
182
#define __NR_sys_getdents __NR_getdents
 
183
#define __NR_sys_getdents64 __NR_getdents64
 
184
#define __NR_sys_getpriority __NR_getpriority
 
185
#define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
 
186
#define __NR_sys_syslog __NR_syslog
 
187
#define __NR_sys_tgkill __NR_tgkill
 
188
#define __NR_sys_tkill __NR_tkill
 
189
#define __NR_sys_futex __NR_futex
 
190
#define __NR_sys_inotify_init __NR_inotify_init
 
191
#define __NR_sys_inotify_add_watch __NR_inotify_add_watch
 
192
#define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
 
193
 
 
194
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) || \
 
195
    defined(__s390x__)
 
196
#define __NR__llseek __NR_lseek
 
197
#endif
 
198
 
 
199
#ifdef __NR_gettid
 
200
_syscall0(int, gettid)
 
201
#else
 
202
/* This is a replacement for the host gettid() and must return a host
 
203
   errno. */
 
204
static int gettid(void) {
 
205
    return -ENOSYS;
 
206
}
 
207
#endif
 
208
#ifdef __NR_getdents
 
209
_syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
 
210
#endif
 
211
#if !defined(__NR_getdents) || \
 
212
    (defined(TARGET_NR_getdents64) && defined(__NR_getdents64))
 
213
_syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
 
214
#endif
 
215
#if defined(TARGET_NR__llseek) && defined(__NR_llseek)
 
216
_syscall5(int, _llseek,  uint,  fd, ulong, hi, ulong, lo,
 
217
          loff_t *, res, uint, wh);
 
218
#endif
 
219
_syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
 
220
_syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
 
221
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
 
222
_syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
 
223
#endif
 
224
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
 
225
_syscall2(int,sys_tkill,int,tid,int,sig)
 
226
#endif
 
227
#ifdef __NR_exit_group
 
228
_syscall1(int,exit_group,int,error_code)
 
229
#endif
 
230
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
 
231
_syscall1(int,set_tid_address,int *,tidptr)
 
232
#endif
 
233
#if defined(TARGET_NR_futex) && defined(__NR_futex)
 
234
_syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
 
235
          const struct timespec *,timeout,int *,uaddr2,int,val3)
 
236
#endif
 
237
#define __NR_sys_sched_getaffinity __NR_sched_getaffinity
 
238
_syscall3(int, sys_sched_getaffinity, pid_t, pid, unsigned int, len,
 
239
          unsigned long *, user_mask_ptr);
 
240
#define __NR_sys_sched_setaffinity __NR_sched_setaffinity
 
241
_syscall3(int, sys_sched_setaffinity, pid_t, pid, unsigned int, len,
 
242
          unsigned long *, user_mask_ptr);
 
243
_syscall4(int, reboot, int, magic1, int, magic2, unsigned int, cmd,
 
244
          void *, arg);
 
245
 
 
246
static bitmask_transtbl fcntl_flags_tbl[] = {
 
247
  { TARGET_O_ACCMODE,   TARGET_O_WRONLY,    O_ACCMODE,   O_WRONLY,    },
 
248
  { TARGET_O_ACCMODE,   TARGET_O_RDWR,      O_ACCMODE,   O_RDWR,      },
 
249
  { TARGET_O_CREAT,     TARGET_O_CREAT,     O_CREAT,     O_CREAT,     },
 
250
  { TARGET_O_EXCL,      TARGET_O_EXCL,      O_EXCL,      O_EXCL,      },
 
251
  { TARGET_O_NOCTTY,    TARGET_O_NOCTTY,    O_NOCTTY,    O_NOCTTY,    },
 
252
  { TARGET_O_TRUNC,     TARGET_O_TRUNC,     O_TRUNC,     O_TRUNC,     },
 
253
  { TARGET_O_APPEND,    TARGET_O_APPEND,    O_APPEND,    O_APPEND,    },
 
254
  { TARGET_O_NONBLOCK,  TARGET_O_NONBLOCK,  O_NONBLOCK,  O_NONBLOCK,  },
 
255
  { TARGET_O_SYNC,      TARGET_O_DSYNC,     O_SYNC,      O_DSYNC,     },
 
256
  { TARGET_O_SYNC,      TARGET_O_SYNC,      O_SYNC,      O_SYNC,      },
 
257
  { TARGET_FASYNC,      TARGET_FASYNC,      FASYNC,      FASYNC,      },
 
258
  { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
 
259
  { TARGET_O_NOFOLLOW,  TARGET_O_NOFOLLOW,  O_NOFOLLOW,  O_NOFOLLOW,  },
 
260
#if defined(O_DIRECT)
 
261
  { TARGET_O_DIRECT,    TARGET_O_DIRECT,    O_DIRECT,    O_DIRECT,    },
 
262
#endif
 
263
#if defined(O_NOATIME)
 
264
  { TARGET_O_NOATIME,   TARGET_O_NOATIME,   O_NOATIME,   O_NOATIME    },
 
265
#endif
 
266
#if defined(O_CLOEXEC)
 
267
  { TARGET_O_CLOEXEC,   TARGET_O_CLOEXEC,   O_CLOEXEC,   O_CLOEXEC    },
 
268
#endif
 
269
#if defined(O_PATH)
 
270
  { TARGET_O_PATH,      TARGET_O_PATH,      O_PATH,      O_PATH       },
 
271
#endif
 
272
  /* Don't terminate the list prematurely on 64-bit host+guest.  */
 
273
#if TARGET_O_LARGEFILE != 0 || O_LARGEFILE != 0
 
274
  { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
 
275
#endif
 
276
  { 0, 0, 0, 0 }
 
277
};
 
278
 
 
279
#define COPY_UTSNAME_FIELD(dest, src) \
 
280
  do { \
 
281
      /* __NEW_UTS_LEN doesn't include terminating null */ \
 
282
      (void) strncpy((dest), (src), __NEW_UTS_LEN); \
 
283
      (dest)[__NEW_UTS_LEN] = '\0'; \
 
284
  } while (0)
 
285
 
 
286
static int sys_uname(struct new_utsname *buf)
 
287
{
 
288
  struct utsname uts_buf;
 
289
 
 
290
  if (uname(&uts_buf) < 0)
 
291
      return (-1);
 
292
 
 
293
  /*
 
294
   * Just in case these have some differences, we
 
295
   * translate utsname to new_utsname (which is the
 
296
   * struct linux kernel uses).
 
297
   */
 
298
 
 
299
  memset(buf, 0, sizeof(*buf));
 
300
  COPY_UTSNAME_FIELD(buf->sysname, uts_buf.sysname);
 
301
  COPY_UTSNAME_FIELD(buf->nodename, uts_buf.nodename);
 
302
  COPY_UTSNAME_FIELD(buf->release, uts_buf.release);
 
303
  COPY_UTSNAME_FIELD(buf->version, uts_buf.version);
 
304
  COPY_UTSNAME_FIELD(buf->machine, uts_buf.machine);
 
305
#ifdef _GNU_SOURCE
 
306
  COPY_UTSNAME_FIELD(buf->domainname, uts_buf.domainname);
 
307
#endif
 
308
  return (0);
 
309
 
 
310
#undef COPY_UTSNAME_FIELD
 
311
}
 
312
 
 
313
static int sys_getcwd1(char *buf, size_t size)
 
314
{
 
315
  if (getcwd(buf, size) == NULL) {
 
316
      /* getcwd() sets errno */
 
317
      return (-1);
 
318
  }
 
319
  return strlen(buf)+1;
 
320
}
 
321
 
 
322
#ifdef TARGET_NR_openat
 
323
static int sys_openat(int dirfd, const char *pathname, int flags, mode_t mode)
 
324
{
 
325
  /*
 
326
   * open(2) has extra parameter 'mode' when called with
 
327
   * flag O_CREAT.
 
328
   */
 
329
  if ((flags & O_CREAT) != 0) {
 
330
      return (openat(dirfd, pathname, flags, mode));
 
331
  }
 
332
  return (openat(dirfd, pathname, flags));
 
333
}
 
334
#endif
 
335
 
 
336
#ifdef TARGET_NR_utimensat
 
337
#ifdef CONFIG_UTIMENSAT
 
338
static int sys_utimensat(int dirfd, const char *pathname,
 
339
    const struct timespec times[2], int flags)
 
340
{
 
341
    if (pathname == NULL)
 
342
        return futimens(dirfd, times);
 
343
    else
 
344
        return utimensat(dirfd, pathname, times, flags);
 
345
}
 
346
#elif defined(__NR_utimensat)
 
347
#define __NR_sys_utimensat __NR_utimensat
 
348
_syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
 
349
          const struct timespec *,tsp,int,flags)
 
350
#else
 
351
static int sys_utimensat(int dirfd, const char *pathname,
 
352
                         const struct timespec times[2], int flags)
 
353
{
 
354
    errno = ENOSYS;
 
355
    return -1;
 
356
}
 
357
#endif
 
358
#endif /* TARGET_NR_utimensat */
 
359
 
 
360
#ifdef CONFIG_INOTIFY
 
361
#include <sys/inotify.h>
 
362
 
 
363
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
 
364
static int sys_inotify_init(void)
 
365
{
 
366
  return (inotify_init());
 
367
}
 
368
#endif
 
369
#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
 
370
static int sys_inotify_add_watch(int fd,const char *pathname, int32_t mask)
 
371
{
 
372
  return (inotify_add_watch(fd, pathname, mask));
 
373
}
 
374
#endif
 
375
#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
 
376
static int sys_inotify_rm_watch(int fd, int32_t wd)
 
377
{
 
378
  return (inotify_rm_watch(fd, wd));
 
379
}
 
380
#endif
 
381
#ifdef CONFIG_INOTIFY1
 
382
#if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
 
383
static int sys_inotify_init1(int flags)
 
384
{
 
385
  return (inotify_init1(flags));
 
386
}
 
387
#endif
 
388
#endif
 
389
#else
 
390
/* Userspace can usually survive runtime without inotify */
 
391
#undef TARGET_NR_inotify_init
 
392
#undef TARGET_NR_inotify_init1
 
393
#undef TARGET_NR_inotify_add_watch
 
394
#undef TARGET_NR_inotify_rm_watch
 
395
#endif /* CONFIG_INOTIFY  */
 
396
 
 
397
#if defined(TARGET_NR_ppoll)
 
398
#ifndef __NR_ppoll
 
399
# define __NR_ppoll -1
 
400
#endif
 
401
#define __NR_sys_ppoll __NR_ppoll
 
402
_syscall5(int, sys_ppoll, struct pollfd *, fds, nfds_t, nfds,
 
403
          struct timespec *, timeout, const __sigset_t *, sigmask,
 
404
          size_t, sigsetsize)
 
405
#endif
 
406
 
 
407
#if defined(TARGET_NR_pselect6)
 
408
#ifndef __NR_pselect6
 
409
# define __NR_pselect6 -1
 
410
#endif
 
411
#define __NR_sys_pselect6 __NR_pselect6
 
412
_syscall6(int, sys_pselect6, int, nfds, fd_set *, readfds, fd_set *, writefds,
 
413
          fd_set *, exceptfds, struct timespec *, timeout, void *, sig);
 
414
#endif
 
415
 
 
416
#if defined(TARGET_NR_prlimit64)
 
417
#ifndef __NR_prlimit64
 
418
# define __NR_prlimit64 -1
 
419
#endif
 
420
#define __NR_sys_prlimit64 __NR_prlimit64
 
421
/* The glibc rlimit structure may not be that used by the underlying syscall */
 
422
struct host_rlimit64 {
 
423
    uint64_t rlim_cur;
 
424
    uint64_t rlim_max;
 
425
};
 
426
_syscall4(int, sys_prlimit64, pid_t, pid, int, resource,
 
427
          const struct host_rlimit64 *, new_limit,
 
428
          struct host_rlimit64 *, old_limit)
 
429
#endif
 
430
 
 
431
/* ARM EABI and MIPS expect 64bit types aligned even on pairs or registers */
 
432
#ifdef TARGET_ARM
 
433
static inline int regpairs_aligned(void *cpu_env) {
 
434
    return ((((CPUARMState *)cpu_env)->eabi) == 1) ;
 
435
}
 
436
#elif defined(TARGET_MIPS)
 
437
static inline int regpairs_aligned(void *cpu_env) { return 1; }
 
438
#elif defined(TARGET_PPC) && !defined(TARGET_PPC64)
 
439
/* SysV AVI for PPC32 expects 64bit parameters to be passed on odd/even pairs
 
440
 * of registers which translates to the same as ARM/MIPS, because we start with
 
441
 * r3 as arg1 */
 
442
static inline int regpairs_aligned(void *cpu_env) { return 1; }
 
443
#else
 
444
static inline int regpairs_aligned(void *cpu_env) { return 0; }
 
445
#endif
 
446
 
 
447
#define ERRNO_TABLE_SIZE 1200
 
448
 
 
449
/* target_to_host_errno_table[] is initialized from
 
450
 * host_to_target_errno_table[] in syscall_init(). */
 
451
static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
 
452
};
 
453
 
 
454
/*
 
455
 * This list is the union of errno values overridden in asm-<arch>/errno.h
 
456
 * minus the errnos that are not actually generic to all archs.
 
457
 */
 
458
static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
 
459
    [EIDRM]             = TARGET_EIDRM,
 
460
    [ECHRNG]            = TARGET_ECHRNG,
 
461
    [EL2NSYNC]          = TARGET_EL2NSYNC,
 
462
    [EL3HLT]            = TARGET_EL3HLT,
 
463
    [EL3RST]            = TARGET_EL3RST,
 
464
    [ELNRNG]            = TARGET_ELNRNG,
 
465
    [EUNATCH]           = TARGET_EUNATCH,
 
466
    [ENOCSI]            = TARGET_ENOCSI,
 
467
    [EL2HLT]            = TARGET_EL2HLT,
 
468
    [EDEADLK]           = TARGET_EDEADLK,
 
469
    [ENOLCK]            = TARGET_ENOLCK,
 
470
    [EBADE]             = TARGET_EBADE,
 
471
    [EBADR]             = TARGET_EBADR,
 
472
    [EXFULL]            = TARGET_EXFULL,
 
473
    [ENOANO]            = TARGET_ENOANO,
 
474
    [EBADRQC]           = TARGET_EBADRQC,
 
475
    [EBADSLT]           = TARGET_EBADSLT,
 
476
    [EBFONT]            = TARGET_EBFONT,
 
477
    [ENOSTR]            = TARGET_ENOSTR,
 
478
    [ENODATA]           = TARGET_ENODATA,
 
479
    [ETIME]             = TARGET_ETIME,
 
480
    [ENOSR]             = TARGET_ENOSR,
 
481
    [ENONET]            = TARGET_ENONET,
 
482
    [ENOPKG]            = TARGET_ENOPKG,
 
483
    [EREMOTE]           = TARGET_EREMOTE,
 
484
    [ENOLINK]           = TARGET_ENOLINK,
 
485
    [EADV]              = TARGET_EADV,
 
486
    [ESRMNT]            = TARGET_ESRMNT,
 
487
    [ECOMM]             = TARGET_ECOMM,
 
488
    [EPROTO]            = TARGET_EPROTO,
 
489
    [EDOTDOT]           = TARGET_EDOTDOT,
 
490
    [EMULTIHOP]         = TARGET_EMULTIHOP,
 
491
    [EBADMSG]           = TARGET_EBADMSG,
 
492
    [ENAMETOOLONG]      = TARGET_ENAMETOOLONG,
 
493
    [EOVERFLOW]         = TARGET_EOVERFLOW,
 
494
    [ENOTUNIQ]          = TARGET_ENOTUNIQ,
 
495
    [EBADFD]            = TARGET_EBADFD,
 
496
    [EREMCHG]           = TARGET_EREMCHG,
 
497
    [ELIBACC]           = TARGET_ELIBACC,
 
498
    [ELIBBAD]           = TARGET_ELIBBAD,
 
499
    [ELIBSCN]           = TARGET_ELIBSCN,
 
500
    [ELIBMAX]           = TARGET_ELIBMAX,
 
501
    [ELIBEXEC]          = TARGET_ELIBEXEC,
 
502
    [EILSEQ]            = TARGET_EILSEQ,
 
503
    [ENOSYS]            = TARGET_ENOSYS,
 
504
    [ELOOP]             = TARGET_ELOOP,
 
505
    [ERESTART]          = TARGET_ERESTART,
 
506
    [ESTRPIPE]          = TARGET_ESTRPIPE,
 
507
    [ENOTEMPTY]         = TARGET_ENOTEMPTY,
 
508
    [EUSERS]            = TARGET_EUSERS,
 
509
    [ENOTSOCK]          = TARGET_ENOTSOCK,
 
510
    [EDESTADDRREQ]      = TARGET_EDESTADDRREQ,
 
511
    [EMSGSIZE]          = TARGET_EMSGSIZE,
 
512
    [EPROTOTYPE]        = TARGET_EPROTOTYPE,
 
513
    [ENOPROTOOPT]       = TARGET_ENOPROTOOPT,
 
514
    [EPROTONOSUPPORT]   = TARGET_EPROTONOSUPPORT,
 
515
    [ESOCKTNOSUPPORT]   = TARGET_ESOCKTNOSUPPORT,
 
516
    [EOPNOTSUPP]        = TARGET_EOPNOTSUPP,
 
517
    [EPFNOSUPPORT]      = TARGET_EPFNOSUPPORT,
 
518
    [EAFNOSUPPORT]      = TARGET_EAFNOSUPPORT,
 
519
    [EADDRINUSE]        = TARGET_EADDRINUSE,
 
520
    [EADDRNOTAVAIL]     = TARGET_EADDRNOTAVAIL,
 
521
    [ENETDOWN]          = TARGET_ENETDOWN,
 
522
    [ENETUNREACH]       = TARGET_ENETUNREACH,
 
523
    [ENETRESET]         = TARGET_ENETRESET,
 
524
    [ECONNABORTED]      = TARGET_ECONNABORTED,
 
525
    [ECONNRESET]        = TARGET_ECONNRESET,
 
526
    [ENOBUFS]           = TARGET_ENOBUFS,
 
527
    [EISCONN]           = TARGET_EISCONN,
 
528
    [ENOTCONN]          = TARGET_ENOTCONN,
 
529
    [EUCLEAN]           = TARGET_EUCLEAN,
 
530
    [ENOTNAM]           = TARGET_ENOTNAM,
 
531
    [ENAVAIL]           = TARGET_ENAVAIL,
 
532
    [EISNAM]            = TARGET_EISNAM,
 
533
    [EREMOTEIO]         = TARGET_EREMOTEIO,
 
534
    [ESHUTDOWN]         = TARGET_ESHUTDOWN,
 
535
    [ETOOMANYREFS]      = TARGET_ETOOMANYREFS,
 
536
    [ETIMEDOUT]         = TARGET_ETIMEDOUT,
 
537
    [ECONNREFUSED]      = TARGET_ECONNREFUSED,
 
538
    [EHOSTDOWN]         = TARGET_EHOSTDOWN,
 
539
    [EHOSTUNREACH]      = TARGET_EHOSTUNREACH,
 
540
    [EALREADY]          = TARGET_EALREADY,
 
541
    [EINPROGRESS]       = TARGET_EINPROGRESS,
 
542
    [ESTALE]            = TARGET_ESTALE,
 
543
    [ECANCELED]         = TARGET_ECANCELED,
 
544
    [ENOMEDIUM]         = TARGET_ENOMEDIUM,
 
545
    [EMEDIUMTYPE]       = TARGET_EMEDIUMTYPE,
 
546
#ifdef ENOKEY
 
547
    [ENOKEY]            = TARGET_ENOKEY,
 
548
#endif
 
549
#ifdef EKEYEXPIRED
 
550
    [EKEYEXPIRED]       = TARGET_EKEYEXPIRED,
 
551
#endif
 
552
#ifdef EKEYREVOKED
 
553
    [EKEYREVOKED]       = TARGET_EKEYREVOKED,
 
554
#endif
 
555
#ifdef EKEYREJECTED
 
556
    [EKEYREJECTED]      = TARGET_EKEYREJECTED,
 
557
#endif
 
558
#ifdef EOWNERDEAD
 
559
    [EOWNERDEAD]        = TARGET_EOWNERDEAD,
 
560
#endif
 
561
#ifdef ENOTRECOVERABLE
 
562
    [ENOTRECOVERABLE]   = TARGET_ENOTRECOVERABLE,
 
563
#endif
 
564
};
 
565
 
 
566
static inline int host_to_target_errno(int err)
 
567
{
 
568
    if(host_to_target_errno_table[err])
 
569
        return host_to_target_errno_table[err];
 
570
    return err;
 
571
}
 
572
 
 
573
static inline int target_to_host_errno(int err)
 
574
{
 
575
    if (target_to_host_errno_table[err])
 
576
        return target_to_host_errno_table[err];
 
577
    return err;
 
578
}
 
579
 
 
580
static inline abi_long get_errno(abi_long ret)
 
581
{
 
582
    if (ret == -1)
 
583
        return -host_to_target_errno(errno);
 
584
    else
 
585
        return ret;
 
586
}
 
587
 
 
588
static inline int is_error(abi_long ret)
 
589
{
 
590
    return (abi_ulong)ret >= (abi_ulong)(-4096);
 
591
}
 
592
 
 
593
char *target_strerror(int err)
 
594
{
 
595
    if ((err >= ERRNO_TABLE_SIZE) || (err < 0)) {
 
596
        return NULL;
 
597
    }
 
598
    return strerror(target_to_host_errno(err));
 
599
}
 
600
 
 
601
static abi_ulong target_brk;
 
602
static abi_ulong target_original_brk;
 
603
static abi_ulong brk_page;
 
604
 
 
605
void target_set_brk(abi_ulong new_brk)
 
606
{
 
607
    target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
 
608
    brk_page = HOST_PAGE_ALIGN(target_brk);
 
609
}
 
610
 
 
611
//#define DEBUGF_BRK(message, args...) do { fprintf(stderr, (message), ## args); } while (0)
 
612
#define DEBUGF_BRK(message, args...)
 
613
 
 
614
/* do_brk() must return target values and target errnos. */
 
615
abi_long do_brk(abi_ulong new_brk)
 
616
{
 
617
    abi_long mapped_addr;
 
618
    int new_alloc_size;
 
619
 
 
620
    DEBUGF_BRK("do_brk(" TARGET_ABI_FMT_lx ") -> ", new_brk);
 
621
 
 
622
    if (!new_brk) {
 
623
        DEBUGF_BRK(TARGET_ABI_FMT_lx " (!new_brk)\n", target_brk);
 
624
        return target_brk;
 
625
    }
 
626
    if (new_brk < target_original_brk) {
 
627
        DEBUGF_BRK(TARGET_ABI_FMT_lx " (new_brk < target_original_brk)\n",
 
628
                   target_brk);
 
629
        return target_brk;
 
630
    }
 
631
 
 
632
    /* If the new brk is less than the highest page reserved to the
 
633
     * target heap allocation, set it and we're almost done...  */
 
634
    if (new_brk <= brk_page) {
 
635
        /* Heap contents are initialized to zero, as for anonymous
 
636
         * mapped pages.  */
 
637
        if (new_brk > target_brk) {
 
638
            memset(g2h(target_brk), 0, new_brk - target_brk);
 
639
        }
 
640
        target_brk = new_brk;
 
641
        DEBUGF_BRK(TARGET_ABI_FMT_lx " (new_brk <= brk_page)\n", target_brk);
 
642
        return target_brk;
 
643
    }
 
644
 
 
645
    /* We need to allocate more memory after the brk... Note that
 
646
     * we don't use MAP_FIXED because that will map over the top of
 
647
     * any existing mapping (like the one with the host libc or qemu
 
648
     * itself); instead we treat "mapped but at wrong address" as
 
649
     * a failure and unmap again.
 
650
     */
 
651
    new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page);
 
652
    mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
 
653
                                        PROT_READ|PROT_WRITE,
 
654
                                        MAP_ANON|MAP_PRIVATE, 0, 0));
 
655
 
 
656
    if (mapped_addr == brk_page) {
 
657
        /* Heap contents are initialized to zero, as for anonymous
 
658
         * mapped pages.  Technically the new pages are already
 
659
         * initialized to zero since they *are* anonymous mapped
 
660
         * pages, however we have to take care with the contents that
 
661
         * come from the remaining part of the previous page: it may
 
662
         * contains garbage data due to a previous heap usage (grown
 
663
         * then shrunken).  */
 
664
        memset(g2h(target_brk), 0, brk_page - target_brk);
 
665
 
 
666
        target_brk = new_brk;
 
667
        brk_page = HOST_PAGE_ALIGN(target_brk);
 
668
        DEBUGF_BRK(TARGET_ABI_FMT_lx " (mapped_addr == brk_page)\n",
 
669
            target_brk);
 
670
        return target_brk;
 
671
    } else if (mapped_addr != -1) {
 
672
        /* Mapped but at wrong address, meaning there wasn't actually
 
673
         * enough space for this brk.
 
674
         */
 
675
        target_munmap(mapped_addr, new_alloc_size);
 
676
        mapped_addr = -1;
 
677
        DEBUGF_BRK(TARGET_ABI_FMT_lx " (mapped_addr != -1)\n", target_brk);
 
678
    }
 
679
    else {
 
680
        DEBUGF_BRK(TARGET_ABI_FMT_lx " (otherwise)\n", target_brk);
 
681
    }
 
682
 
 
683
#if defined(TARGET_ALPHA)
 
684
    /* We (partially) emulate OSF/1 on Alpha, which requires we
 
685
       return a proper errno, not an unchanged brk value.  */
 
686
    return -TARGET_ENOMEM;
 
687
#endif
 
688
    /* For everything else, return the previous break. */
 
689
    return target_brk;
 
690
}
 
691
 
 
692
static inline abi_long copy_from_user_fdset(fd_set *fds,
 
693
                                            abi_ulong target_fds_addr,
 
694
                                            int n)
 
695
{
 
696
    int i, nw, j, k;
 
697
    abi_ulong b, *target_fds;
 
698
 
 
699
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
 
700
    if (!(target_fds = lock_user(VERIFY_READ,
 
701
                                 target_fds_addr,
 
702
                                 sizeof(abi_ulong) * nw,
 
703
                                 1)))
 
704
        return -TARGET_EFAULT;
 
705
 
 
706
    FD_ZERO(fds);
 
707
    k = 0;
 
708
    for (i = 0; i < nw; i++) {
 
709
        /* grab the abi_ulong */
 
710
        __get_user(b, &target_fds[i]);
 
711
        for (j = 0; j < TARGET_ABI_BITS; j++) {
 
712
            /* check the bit inside the abi_ulong */
 
713
            if ((b >> j) & 1)
 
714
                FD_SET(k, fds);
 
715
            k++;
 
716
        }
 
717
    }
 
718
 
 
719
    unlock_user(target_fds, target_fds_addr, 0);
 
720
 
 
721
    return 0;
 
722
}
 
723
 
 
724
static inline abi_ulong copy_from_user_fdset_ptr(fd_set *fds, fd_set **fds_ptr,
 
725
                                                 abi_ulong target_fds_addr,
 
726
                                                 int n)
 
727
{
 
728
    if (target_fds_addr) {
 
729
        if (copy_from_user_fdset(fds, target_fds_addr, n))
 
730
            return -TARGET_EFAULT;
 
731
        *fds_ptr = fds;
 
732
    } else {
 
733
        *fds_ptr = NULL;
 
734
    }
 
735
    return 0;
 
736
}
 
737
 
 
738
static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
 
739
                                          const fd_set *fds,
 
740
                                          int n)
 
741
{
 
742
    int i, nw, j, k;
 
743
    abi_long v;
 
744
    abi_ulong *target_fds;
 
745
 
 
746
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
 
747
    if (!(target_fds = lock_user(VERIFY_WRITE,
 
748
                                 target_fds_addr,
 
749
                                 sizeof(abi_ulong) * nw,
 
750
                                 0)))
 
751
        return -TARGET_EFAULT;
 
752
 
 
753
    k = 0;
 
754
    for (i = 0; i < nw; i++) {
 
755
        v = 0;
 
756
        for (j = 0; j < TARGET_ABI_BITS; j++) {
 
757
            v |= ((abi_ulong)(FD_ISSET(k, fds) != 0) << j);
 
758
            k++;
 
759
        }
 
760
        __put_user(v, &target_fds[i]);
 
761
    }
 
762
 
 
763
    unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
 
764
 
 
765
    return 0;
 
766
}
 
767
 
 
768
#if defined(__alpha__)
 
769
#define HOST_HZ 1024
 
770
#else
 
771
#define HOST_HZ 100
 
772
#endif
 
773
 
 
774
static inline abi_long host_to_target_clock_t(long ticks)
 
775
{
 
776
#if HOST_HZ == TARGET_HZ
 
777
    return ticks;
 
778
#else
 
779
    return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
 
780
#endif
 
781
}
 
782
 
 
783
static inline abi_long host_to_target_rusage(abi_ulong target_addr,
 
784
                                             const struct rusage *rusage)
 
785
{
 
786
    struct target_rusage *target_rusage;
 
787
 
 
788
    if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
 
789
        return -TARGET_EFAULT;
 
790
    target_rusage->ru_utime.tv_sec = tswapal(rusage->ru_utime.tv_sec);
 
791
    target_rusage->ru_utime.tv_usec = tswapal(rusage->ru_utime.tv_usec);
 
792
    target_rusage->ru_stime.tv_sec = tswapal(rusage->ru_stime.tv_sec);
 
793
    target_rusage->ru_stime.tv_usec = tswapal(rusage->ru_stime.tv_usec);
 
794
    target_rusage->ru_maxrss = tswapal(rusage->ru_maxrss);
 
795
    target_rusage->ru_ixrss = tswapal(rusage->ru_ixrss);
 
796
    target_rusage->ru_idrss = tswapal(rusage->ru_idrss);
 
797
    target_rusage->ru_isrss = tswapal(rusage->ru_isrss);
 
798
    target_rusage->ru_minflt = tswapal(rusage->ru_minflt);
 
799
    target_rusage->ru_majflt = tswapal(rusage->ru_majflt);
 
800
    target_rusage->ru_nswap = tswapal(rusage->ru_nswap);
 
801
    target_rusage->ru_inblock = tswapal(rusage->ru_inblock);
 
802
    target_rusage->ru_oublock = tswapal(rusage->ru_oublock);
 
803
    target_rusage->ru_msgsnd = tswapal(rusage->ru_msgsnd);
 
804
    target_rusage->ru_msgrcv = tswapal(rusage->ru_msgrcv);
 
805
    target_rusage->ru_nsignals = tswapal(rusage->ru_nsignals);
 
806
    target_rusage->ru_nvcsw = tswapal(rusage->ru_nvcsw);
 
807
    target_rusage->ru_nivcsw = tswapal(rusage->ru_nivcsw);
 
808
    unlock_user_struct(target_rusage, target_addr, 1);
 
809
 
 
810
    return 0;
 
811
}
 
812
 
 
813
static inline rlim_t target_to_host_rlim(abi_ulong target_rlim)
 
814
{
 
815
    abi_ulong target_rlim_swap;
 
816
    rlim_t result;
 
817
    
 
818
    target_rlim_swap = tswapal(target_rlim);
 
819
    if (target_rlim_swap == TARGET_RLIM_INFINITY)
 
820
        return RLIM_INFINITY;
 
821
 
 
822
    result = target_rlim_swap;
 
823
    if (target_rlim_swap != (rlim_t)result)
 
824
        return RLIM_INFINITY;
 
825
    
 
826
    return result;
 
827
}
 
828
 
 
829
static inline abi_ulong host_to_target_rlim(rlim_t rlim)
 
830
{
 
831
    abi_ulong target_rlim_swap;
 
832
    abi_ulong result;
 
833
    
 
834
    if (rlim == RLIM_INFINITY || rlim != (abi_long)rlim)
 
835
        target_rlim_swap = TARGET_RLIM_INFINITY;
 
836
    else
 
837
        target_rlim_swap = rlim;
 
838
    result = tswapal(target_rlim_swap);
 
839
    
 
840
    return result;
 
841
}
 
842
 
 
843
static inline int target_to_host_resource(int code)
 
844
{
 
845
    switch (code) {
 
846
    case TARGET_RLIMIT_AS:
 
847
        return RLIMIT_AS;
 
848
    case TARGET_RLIMIT_CORE:
 
849
        return RLIMIT_CORE;
 
850
    case TARGET_RLIMIT_CPU:
 
851
        return RLIMIT_CPU;
 
852
    case TARGET_RLIMIT_DATA:
 
853
        return RLIMIT_DATA;
 
854
    case TARGET_RLIMIT_FSIZE:
 
855
        return RLIMIT_FSIZE;
 
856
    case TARGET_RLIMIT_LOCKS:
 
857
        return RLIMIT_LOCKS;
 
858
    case TARGET_RLIMIT_MEMLOCK:
 
859
        return RLIMIT_MEMLOCK;
 
860
    case TARGET_RLIMIT_MSGQUEUE:
 
861
        return RLIMIT_MSGQUEUE;
 
862
    case TARGET_RLIMIT_NICE:
 
863
        return RLIMIT_NICE;
 
864
    case TARGET_RLIMIT_NOFILE:
 
865
        return RLIMIT_NOFILE;
 
866
    case TARGET_RLIMIT_NPROC:
 
867
        return RLIMIT_NPROC;
 
868
    case TARGET_RLIMIT_RSS:
 
869
        return RLIMIT_RSS;
 
870
    case TARGET_RLIMIT_RTPRIO:
 
871
        return RLIMIT_RTPRIO;
 
872
    case TARGET_RLIMIT_SIGPENDING:
 
873
        return RLIMIT_SIGPENDING;
 
874
    case TARGET_RLIMIT_STACK:
 
875
        return RLIMIT_STACK;
 
876
    default:
 
877
        return code;
 
878
    }
 
879
}
 
880
 
 
881
static inline abi_long copy_from_user_timeval(struct timeval *tv,
 
882
                                              abi_ulong target_tv_addr)
 
883
{
 
884
    struct target_timeval *target_tv;
 
885
 
 
886
    if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
 
887
        return -TARGET_EFAULT;
 
888
 
 
889
    __get_user(tv->tv_sec, &target_tv->tv_sec);
 
890
    __get_user(tv->tv_usec, &target_tv->tv_usec);
 
891
 
 
892
    unlock_user_struct(target_tv, target_tv_addr, 0);
 
893
 
 
894
    return 0;
 
895
}
 
896
 
 
897
static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
 
898
                                            const struct timeval *tv)
 
899
{
 
900
    struct target_timeval *target_tv;
 
901
 
 
902
    if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
 
903
        return -TARGET_EFAULT;
 
904
 
 
905
    __put_user(tv->tv_sec, &target_tv->tv_sec);
 
906
    __put_user(tv->tv_usec, &target_tv->tv_usec);
 
907
 
 
908
    unlock_user_struct(target_tv, target_tv_addr, 1);
 
909
 
 
910
    return 0;
 
911
}
 
912
 
 
913
#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
 
914
#include <mqueue.h>
 
915
 
 
916
static inline abi_long copy_from_user_mq_attr(struct mq_attr *attr,
 
917
                                              abi_ulong target_mq_attr_addr)
 
918
{
 
919
    struct target_mq_attr *target_mq_attr;
 
920
 
 
921
    if (!lock_user_struct(VERIFY_READ, target_mq_attr,
 
922
                          target_mq_attr_addr, 1))
 
923
        return -TARGET_EFAULT;
 
924
 
 
925
    __get_user(attr->mq_flags, &target_mq_attr->mq_flags);
 
926
    __get_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
 
927
    __get_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
 
928
    __get_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
 
929
 
 
930
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0);
 
931
 
 
932
    return 0;
 
933
}
 
934
 
 
935
static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr,
 
936
                                            const struct mq_attr *attr)
 
937
{
 
938
    struct target_mq_attr *target_mq_attr;
 
939
 
 
940
    if (!lock_user_struct(VERIFY_WRITE, target_mq_attr,
 
941
                          target_mq_attr_addr, 0))
 
942
        return -TARGET_EFAULT;
 
943
 
 
944
    __put_user(attr->mq_flags, &target_mq_attr->mq_flags);
 
945
    __put_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
 
946
    __put_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
 
947
    __put_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
 
948
 
 
949
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1);
 
950
 
 
951
    return 0;
 
952
}
 
953
#endif
 
954
 
 
955
#if defined(TARGET_NR_select) || defined(TARGET_NR__newselect)
 
956
/* do_select() must return target values and target errnos. */
 
957
static abi_long do_select(int n,
 
958
                          abi_ulong rfd_addr, abi_ulong wfd_addr,
 
959
                          abi_ulong efd_addr, abi_ulong target_tv_addr)
 
960
{
 
961
    fd_set rfds, wfds, efds;
 
962
    fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
 
963
    struct timeval tv, *tv_ptr;
 
964
    abi_long ret;
 
965
 
 
966
    ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
 
967
    if (ret) {
 
968
        return ret;
 
969
    }
 
970
    ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
 
971
    if (ret) {
 
972
        return ret;
 
973
    }
 
974
    ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
 
975
    if (ret) {
 
976
        return ret;
 
977
    }
 
978
 
 
979
    if (target_tv_addr) {
 
980
        if (copy_from_user_timeval(&tv, target_tv_addr))
 
981
            return -TARGET_EFAULT;
 
982
        tv_ptr = &tv;
 
983
    } else {
 
984
        tv_ptr = NULL;
 
985
    }
 
986
 
 
987
    ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
 
988
 
 
989
    if (!is_error(ret)) {
 
990
        if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
 
991
            return -TARGET_EFAULT;
 
992
        if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
 
993
            return -TARGET_EFAULT;
 
994
        if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
 
995
            return -TARGET_EFAULT;
 
996
 
 
997
        if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
 
998
            return -TARGET_EFAULT;
 
999
    }
 
1000
 
 
1001
    return ret;
 
1002
}
 
1003
#endif
 
1004
 
 
1005
static abi_long do_pipe2(int host_pipe[], int flags)
 
1006
{
 
1007
#ifdef CONFIG_PIPE2
 
1008
    return pipe2(host_pipe, flags);
 
1009
#else
 
1010
    return -ENOSYS;
 
1011
#endif
 
1012
}
 
1013
 
 
1014
static abi_long do_pipe(void *cpu_env, abi_ulong pipedes,
 
1015
                        int flags, int is_pipe2)
 
1016
{
 
1017
    int host_pipe[2];
 
1018
    abi_long ret;
 
1019
    ret = flags ? do_pipe2(host_pipe, flags) : pipe(host_pipe);
 
1020
 
 
1021
    if (is_error(ret))
 
1022
        return get_errno(ret);
 
1023
 
 
1024
    /* Several targets have special calling conventions for the original
 
1025
       pipe syscall, but didn't replicate this into the pipe2 syscall.  */
 
1026
    if (!is_pipe2) {
 
1027
#if defined(TARGET_ALPHA)
 
1028
        ((CPUAlphaState *)cpu_env)->ir[IR_A4] = host_pipe[1];
 
1029
        return host_pipe[0];
 
1030
#elif defined(TARGET_MIPS)
 
1031
        ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1];
 
1032
        return host_pipe[0];
 
1033
#elif defined(TARGET_SH4)
 
1034
        ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
 
1035
        return host_pipe[0];
 
1036
#elif defined(TARGET_SPARC)
 
1037
        ((CPUSPARCState*)cpu_env)->regwptr[1] = host_pipe[1];
 
1038
        return host_pipe[0];
 
1039
#endif
 
1040
    }
 
1041
 
 
1042
    if (put_user_s32(host_pipe[0], pipedes)
 
1043
        || put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0])))
 
1044
        return -TARGET_EFAULT;
 
1045
    return get_errno(ret);
 
1046
}
 
1047
 
 
1048
static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn,
 
1049
                                              abi_ulong target_addr,
 
1050
                                              socklen_t len)
 
1051
{
 
1052
    struct target_ip_mreqn *target_smreqn;
 
1053
 
 
1054
    target_smreqn = lock_user(VERIFY_READ, target_addr, len, 1);
 
1055
    if (!target_smreqn)
 
1056
        return -TARGET_EFAULT;
 
1057
    mreqn->imr_multiaddr.s_addr = target_smreqn->imr_multiaddr.s_addr;
 
1058
    mreqn->imr_address.s_addr = target_smreqn->imr_address.s_addr;
 
1059
    if (len == sizeof(struct target_ip_mreqn))
 
1060
        mreqn->imr_ifindex = tswapal(target_smreqn->imr_ifindex);
 
1061
    unlock_user(target_smreqn, target_addr, 0);
 
1062
 
 
1063
    return 0;
 
1064
}
 
1065
 
 
1066
static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
 
1067
                                               abi_ulong target_addr,
 
1068
                                               socklen_t len)
 
1069
{
 
1070
    const socklen_t unix_maxlen = sizeof (struct sockaddr_un);
 
1071
    sa_family_t sa_family;
 
1072
    struct target_sockaddr *target_saddr;
 
1073
 
 
1074
    target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
 
1075
    if (!target_saddr)
 
1076
        return -TARGET_EFAULT;
 
1077
 
 
1078
    sa_family = tswap16(target_saddr->sa_family);
 
1079
 
 
1080
    /* Oops. The caller might send a incomplete sun_path; sun_path
 
1081
     * must be terminated by \0 (see the manual page), but
 
1082
     * unfortunately it is quite common to specify sockaddr_un
 
1083
     * length as "strlen(x->sun_path)" while it should be
 
1084
     * "strlen(...) + 1". We'll fix that here if needed.
 
1085
     * Linux kernel has a similar feature.
 
1086
     */
 
1087
 
 
1088
    if (sa_family == AF_UNIX) {
 
1089
        if (len < unix_maxlen && len > 0) {
 
1090
            char *cp = (char*)target_saddr;
 
1091
 
 
1092
            if ( cp[len-1] && !cp[len] )
 
1093
                len++;
 
1094
        }
 
1095
        if (len > unix_maxlen)
 
1096
            len = unix_maxlen;
 
1097
    }
 
1098
 
 
1099
    memcpy(addr, target_saddr, len);
 
1100
    addr->sa_family = sa_family;
 
1101
    unlock_user(target_saddr, target_addr, 0);
 
1102
 
 
1103
    return 0;
 
1104
}
 
1105
 
 
1106
static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
 
1107
                                               struct sockaddr *addr,
 
1108
                                               socklen_t len)
 
1109
{
 
1110
    struct target_sockaddr *target_saddr;
 
1111
 
 
1112
    target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
 
1113
    if (!target_saddr)
 
1114
        return -TARGET_EFAULT;
 
1115
    memcpy(target_saddr, addr, len);
 
1116
    target_saddr->sa_family = tswap16(addr->sa_family);
 
1117
    unlock_user(target_saddr, target_addr, len);
 
1118
 
 
1119
    return 0;
 
1120
}
 
1121
 
 
1122
static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
 
1123
                                           struct target_msghdr *target_msgh)
 
1124
{
 
1125
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
 
1126
    abi_long msg_controllen;
 
1127
    abi_ulong target_cmsg_addr;
 
1128
    struct target_cmsghdr *target_cmsg;
 
1129
    socklen_t space = 0;
 
1130
    
 
1131
    msg_controllen = tswapal(target_msgh->msg_controllen);
 
1132
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
 
1133
        goto the_end;
 
1134
    target_cmsg_addr = tswapal(target_msgh->msg_control);
 
1135
    target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
 
1136
    if (!target_cmsg)
 
1137
        return -TARGET_EFAULT;
 
1138
 
 
1139
    while (cmsg && target_cmsg) {
 
1140
        void *data = CMSG_DATA(cmsg);
 
1141
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
 
1142
 
 
1143
        int len = tswapal(target_cmsg->cmsg_len)
 
1144
                  - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
 
1145
 
 
1146
        space += CMSG_SPACE(len);
 
1147
        if (space > msgh->msg_controllen) {
 
1148
            space -= CMSG_SPACE(len);
 
1149
            gemu_log("Host cmsg overflow\n");
 
1150
            break;
 
1151
        }
 
1152
 
 
1153
        if (tswap32(target_cmsg->cmsg_level) == TARGET_SOL_SOCKET) {
 
1154
            cmsg->cmsg_level = SOL_SOCKET;
 
1155
        } else {
 
1156
            cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
 
1157
        }
 
1158
        cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
 
1159
        cmsg->cmsg_len = CMSG_LEN(len);
 
1160
 
 
1161
        if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
 
1162
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
 
1163
            memcpy(data, target_data, len);
 
1164
        } else {
 
1165
            int *fd = (int *)data;
 
1166
            int *target_fd = (int *)target_data;
 
1167
            int i, numfds = len / sizeof(int);
 
1168
 
 
1169
            for (i = 0; i < numfds; i++)
 
1170
                fd[i] = tswap32(target_fd[i]);
 
1171
        }
 
1172
 
 
1173
        cmsg = CMSG_NXTHDR(msgh, cmsg);
 
1174
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
 
1175
    }
 
1176
    unlock_user(target_cmsg, target_cmsg_addr, 0);
 
1177
 the_end:
 
1178
    msgh->msg_controllen = space;
 
1179
    return 0;
 
1180
}
 
1181
 
 
1182
static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
 
1183
                                           struct msghdr *msgh)
 
1184
{
 
1185
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
 
1186
    abi_long msg_controllen;
 
1187
    abi_ulong target_cmsg_addr;
 
1188
    struct target_cmsghdr *target_cmsg;
 
1189
    socklen_t space = 0;
 
1190
 
 
1191
    msg_controllen = tswapal(target_msgh->msg_controllen);
 
1192
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
 
1193
        goto the_end;
 
1194
    target_cmsg_addr = tswapal(target_msgh->msg_control);
 
1195
    target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
 
1196
    if (!target_cmsg)
 
1197
        return -TARGET_EFAULT;
 
1198
 
 
1199
    while (cmsg && target_cmsg) {
 
1200
        void *data = CMSG_DATA(cmsg);
 
1201
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
 
1202
 
 
1203
        int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
 
1204
 
 
1205
        space += TARGET_CMSG_SPACE(len);
 
1206
        if (space > msg_controllen) {
 
1207
            space -= TARGET_CMSG_SPACE(len);
 
1208
            gemu_log("Target cmsg overflow\n");
 
1209
            break;
 
1210
        }
 
1211
 
 
1212
        if (cmsg->cmsg_level == SOL_SOCKET) {
 
1213
            target_cmsg->cmsg_level = tswap32(TARGET_SOL_SOCKET);
 
1214
        } else {
 
1215
            target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
 
1216
        }
 
1217
        target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
 
1218
        target_cmsg->cmsg_len = tswapal(TARGET_CMSG_LEN(len));
 
1219
 
 
1220
        if ((cmsg->cmsg_level == SOL_SOCKET) &&
 
1221
                                (cmsg->cmsg_type == SCM_RIGHTS)) {
 
1222
            int *fd = (int *)data;
 
1223
            int *target_fd = (int *)target_data;
 
1224
            int i, numfds = len / sizeof(int);
 
1225
 
 
1226
            for (i = 0; i < numfds; i++)
 
1227
                target_fd[i] = tswap32(fd[i]);
 
1228
        } else if ((cmsg->cmsg_level == SOL_SOCKET) &&
 
1229
                                (cmsg->cmsg_type == SO_TIMESTAMP) &&
 
1230
                                (len == sizeof(struct timeval))) {
 
1231
            /* copy struct timeval to target */
 
1232
            struct timeval *tv = (struct timeval *)data;
 
1233
            struct target_timeval *target_tv =
 
1234
                                        (struct target_timeval *)target_data;
 
1235
 
 
1236
            target_tv->tv_sec = tswapal(tv->tv_sec);
 
1237
            target_tv->tv_usec = tswapal(tv->tv_usec);
 
1238
        } else {
 
1239
            gemu_log("Unsupported ancillary data: %d/%d\n",
 
1240
                                        cmsg->cmsg_level, cmsg->cmsg_type);
 
1241
            memcpy(target_data, data, len);
 
1242
        }
 
1243
 
 
1244
        cmsg = CMSG_NXTHDR(msgh, cmsg);
 
1245
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
 
1246
    }
 
1247
    unlock_user(target_cmsg, target_cmsg_addr, space);
 
1248
 the_end:
 
1249
    target_msgh->msg_controllen = tswapal(space);
 
1250
    return 0;
 
1251
}
 
1252
 
 
1253
/* do_setsockopt() Must return target values and target errnos. */
 
1254
static abi_long do_setsockopt(int sockfd, int level, int optname,
 
1255
                              abi_ulong optval_addr, socklen_t optlen)
 
1256
{
 
1257
    abi_long ret;
 
1258
    int val;
 
1259
    struct ip_mreqn *ip_mreq;
 
1260
    struct ip_mreq_source *ip_mreq_source;
 
1261
 
 
1262
    switch(level) {
 
1263
    case SOL_TCP:
 
1264
        /* TCP options all take an 'int' value.  */
 
1265
        if (optlen < sizeof(uint32_t))
 
1266
            return -TARGET_EINVAL;
 
1267
 
 
1268
        if (get_user_u32(val, optval_addr))
 
1269
            return -TARGET_EFAULT;
 
1270
        ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
 
1271
        break;
 
1272
    case SOL_IP:
 
1273
        switch(optname) {
 
1274
        case IP_TOS:
 
1275
        case IP_TTL:
 
1276
        case IP_HDRINCL:
 
1277
        case IP_ROUTER_ALERT:
 
1278
        case IP_RECVOPTS:
 
1279
        case IP_RETOPTS:
 
1280
        case IP_PKTINFO:
 
1281
        case IP_MTU_DISCOVER:
 
1282
        case IP_RECVERR:
 
1283
        case IP_RECVTOS:
 
1284
#ifdef IP_FREEBIND
 
1285
        case IP_FREEBIND:
 
1286
#endif
 
1287
        case IP_MULTICAST_TTL:
 
1288
        case IP_MULTICAST_LOOP:
 
1289
            val = 0;
 
1290
            if (optlen >= sizeof(uint32_t)) {
 
1291
                if (get_user_u32(val, optval_addr))
 
1292
                    return -TARGET_EFAULT;
 
1293
            } else if (optlen >= 1) {
 
1294
                if (get_user_u8(val, optval_addr))
 
1295
                    return -TARGET_EFAULT;
 
1296
            }
 
1297
            ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
 
1298
            break;
 
1299
        case IP_ADD_MEMBERSHIP:
 
1300
        case IP_DROP_MEMBERSHIP:
 
1301
            if (optlen < sizeof (struct target_ip_mreq) ||
 
1302
                optlen > sizeof (struct target_ip_mreqn))
 
1303
                return -TARGET_EINVAL;
 
1304
 
 
1305
            ip_mreq = (struct ip_mreqn *) alloca(optlen);
 
1306
            target_to_host_ip_mreq(ip_mreq, optval_addr, optlen);
 
1307
            ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq, optlen));
 
1308
            break;
 
1309
 
 
1310
        case IP_BLOCK_SOURCE:
 
1311
        case IP_UNBLOCK_SOURCE:
 
1312
        case IP_ADD_SOURCE_MEMBERSHIP:
 
1313
        case IP_DROP_SOURCE_MEMBERSHIP:
 
1314
            if (optlen != sizeof (struct target_ip_mreq_source))
 
1315
                return -TARGET_EINVAL;
 
1316
 
 
1317
            ip_mreq_source = lock_user(VERIFY_READ, optval_addr, optlen, 1);
 
1318
            ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq_source, optlen));
 
1319
            unlock_user (ip_mreq_source, optval_addr, 0);
 
1320
            break;
 
1321
 
 
1322
        default:
 
1323
            goto unimplemented;
 
1324
        }
 
1325
        break;
 
1326
    case SOL_IPV6:
 
1327
        switch (optname) {
 
1328
        case IPV6_MTU_DISCOVER:
 
1329
        case IPV6_MTU:
 
1330
        case IPV6_V6ONLY:
 
1331
        case IPV6_RECVPKTINFO:
 
1332
            val = 0;
 
1333
            if (optlen < sizeof(uint32_t)) {
 
1334
                return -TARGET_EINVAL;
 
1335
            }
 
1336
            if (get_user_u32(val, optval_addr)) {
 
1337
                return -TARGET_EFAULT;
 
1338
            }
 
1339
            ret = get_errno(setsockopt(sockfd, level, optname,
 
1340
                                       &val, sizeof(val)));
 
1341
            break;
 
1342
        default:
 
1343
            goto unimplemented;
 
1344
        }
 
1345
        break;
 
1346
    case SOL_RAW:
 
1347
        switch (optname) {
 
1348
        case ICMP_FILTER:
 
1349
            /* struct icmp_filter takes an u32 value */
 
1350
            if (optlen < sizeof(uint32_t)) {
 
1351
                return -TARGET_EINVAL;
 
1352
            }
 
1353
 
 
1354
            if (get_user_u32(val, optval_addr)) {
 
1355
                return -TARGET_EFAULT;
 
1356
            }
 
1357
            ret = get_errno(setsockopt(sockfd, level, optname,
 
1358
                                       &val, sizeof(val)));
 
1359
            break;
 
1360
 
 
1361
        default:
 
1362
            goto unimplemented;
 
1363
        }
 
1364
        break;
 
1365
    case TARGET_SOL_SOCKET:
 
1366
        switch (optname) {
 
1367
        case TARGET_SO_RCVTIMEO:
 
1368
        {
 
1369
                struct timeval tv;
 
1370
 
 
1371
                optname = SO_RCVTIMEO;
 
1372
 
 
1373
set_timeout:
 
1374
                if (optlen != sizeof(struct target_timeval)) {
 
1375
                    return -TARGET_EINVAL;
 
1376
                }
 
1377
 
 
1378
                if (copy_from_user_timeval(&tv, optval_addr)) {
 
1379
                    return -TARGET_EFAULT;
 
1380
                }
 
1381
 
 
1382
                ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname,
 
1383
                                &tv, sizeof(tv)));
 
1384
                return ret;
 
1385
        }
 
1386
        case TARGET_SO_SNDTIMEO:
 
1387
                optname = SO_SNDTIMEO;
 
1388
                goto set_timeout;
 
1389
        case TARGET_SO_ATTACH_FILTER:
 
1390
        {
 
1391
                struct target_sock_fprog *tfprog;
 
1392
                struct target_sock_filter *tfilter;
 
1393
                struct sock_fprog fprog;
 
1394
                struct sock_filter *filter;
 
1395
                int i;
 
1396
 
 
1397
                if (optlen != sizeof(*tfprog)) {
 
1398
                    return -TARGET_EINVAL;
 
1399
                }
 
1400
                if (!lock_user_struct(VERIFY_READ, tfprog, optval_addr, 0)) {
 
1401
                    return -TARGET_EFAULT;
 
1402
                }
 
1403
                if (!lock_user_struct(VERIFY_READ, tfilter,
 
1404
                                      tswapal(tfprog->filter), 0)) {
 
1405
                    unlock_user_struct(tfprog, optval_addr, 1);
 
1406
                    return -TARGET_EFAULT;
 
1407
                }
 
1408
 
 
1409
                fprog.len = tswap16(tfprog->len);
 
1410
                filter = malloc(fprog.len * sizeof(*filter));
 
1411
                if (filter == NULL) {
 
1412
                    unlock_user_struct(tfilter, tfprog->filter, 1);
 
1413
                    unlock_user_struct(tfprog, optval_addr, 1);
 
1414
                    return -TARGET_ENOMEM;
 
1415
                }
 
1416
                for (i = 0; i < fprog.len; i++) {
 
1417
                    filter[i].code = tswap16(tfilter[i].code);
 
1418
                    filter[i].jt = tfilter[i].jt;
 
1419
                    filter[i].jf = tfilter[i].jf;
 
1420
                    filter[i].k = tswap32(tfilter[i].k);
 
1421
                }
 
1422
                fprog.filter = filter;
 
1423
 
 
1424
                ret = get_errno(setsockopt(sockfd, SOL_SOCKET,
 
1425
                                SO_ATTACH_FILTER, &fprog, sizeof(fprog)));
 
1426
                free(filter);
 
1427
 
 
1428
                unlock_user_struct(tfilter, tfprog->filter, 1);
 
1429
                unlock_user_struct(tfprog, optval_addr, 1);
 
1430
                return ret;
 
1431
        }
 
1432
            /* Options with 'int' argument.  */
 
1433
        case TARGET_SO_DEBUG:
 
1434
                optname = SO_DEBUG;
 
1435
                break;
 
1436
        case TARGET_SO_REUSEADDR:
 
1437
                optname = SO_REUSEADDR;
 
1438
                break;
 
1439
        case TARGET_SO_TYPE:
 
1440
                optname = SO_TYPE;
 
1441
                break;
 
1442
        case TARGET_SO_ERROR:
 
1443
                optname = SO_ERROR;
 
1444
                break;
 
1445
        case TARGET_SO_DONTROUTE:
 
1446
                optname = SO_DONTROUTE;
 
1447
                break;
 
1448
        case TARGET_SO_BROADCAST:
 
1449
                optname = SO_BROADCAST;
 
1450
                break;
 
1451
        case TARGET_SO_SNDBUF:
 
1452
                optname = SO_SNDBUF;
 
1453
                break;
 
1454
        case TARGET_SO_RCVBUF:
 
1455
                optname = SO_RCVBUF;
 
1456
                break;
 
1457
        case TARGET_SO_KEEPALIVE:
 
1458
                optname = SO_KEEPALIVE;
 
1459
                break;
 
1460
        case TARGET_SO_OOBINLINE:
 
1461
                optname = SO_OOBINLINE;
 
1462
                break;
 
1463
        case TARGET_SO_NO_CHECK:
 
1464
                optname = SO_NO_CHECK;
 
1465
                break;
 
1466
        case TARGET_SO_PRIORITY:
 
1467
                optname = SO_PRIORITY;
 
1468
                break;
 
1469
#ifdef SO_BSDCOMPAT
 
1470
        case TARGET_SO_BSDCOMPAT:
 
1471
                optname = SO_BSDCOMPAT;
 
1472
                break;
 
1473
#endif
 
1474
        case TARGET_SO_PASSCRED:
 
1475
                optname = SO_PASSCRED;
 
1476
                break;
 
1477
        case TARGET_SO_TIMESTAMP:
 
1478
                optname = SO_TIMESTAMP;
 
1479
                break;
 
1480
        case TARGET_SO_RCVLOWAT:
 
1481
                optname = SO_RCVLOWAT;
 
1482
                break;
 
1483
            break;
 
1484
        default:
 
1485
            goto unimplemented;
 
1486
        }
 
1487
        if (optlen < sizeof(uint32_t))
 
1488
            return -TARGET_EINVAL;
 
1489
 
 
1490
        if (get_user_u32(val, optval_addr))
 
1491
            return -TARGET_EFAULT;
 
1492
        ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
 
1493
        break;
 
1494
    default:
 
1495
    unimplemented:
 
1496
        gemu_log("Unsupported setsockopt level=%d optname=%d\n", level, optname);
 
1497
        ret = -TARGET_ENOPROTOOPT;
 
1498
    }
 
1499
    return ret;
 
1500
}
 
1501
 
 
1502
/* do_getsockopt() Must return target values and target errnos. */
 
1503
static abi_long do_getsockopt(int sockfd, int level, int optname,
 
1504
                              abi_ulong optval_addr, abi_ulong optlen)
 
1505
{
 
1506
    abi_long ret;
 
1507
    int len, val;
 
1508
    socklen_t lv;
 
1509
 
 
1510
    switch(level) {
 
1511
    case TARGET_SOL_SOCKET:
 
1512
        level = SOL_SOCKET;
 
1513
        switch (optname) {
 
1514
        /* These don't just return a single integer */
 
1515
        case TARGET_SO_LINGER:
 
1516
        case TARGET_SO_RCVTIMEO:
 
1517
        case TARGET_SO_SNDTIMEO:
 
1518
        case TARGET_SO_PEERNAME:
 
1519
            goto unimplemented;
 
1520
        case TARGET_SO_PEERCRED: {
 
1521
            struct ucred cr;
 
1522
            socklen_t crlen;
 
1523
            struct target_ucred *tcr;
 
1524
 
 
1525
            if (get_user_u32(len, optlen)) {
 
1526
                return -TARGET_EFAULT;
 
1527
            }
 
1528
            if (len < 0) {
 
1529
                return -TARGET_EINVAL;
 
1530
            }
 
1531
 
 
1532
            crlen = sizeof(cr);
 
1533
            ret = get_errno(getsockopt(sockfd, level, SO_PEERCRED,
 
1534
                                       &cr, &crlen));
 
1535
            if (ret < 0) {
 
1536
                return ret;
 
1537
            }
 
1538
            if (len > crlen) {
 
1539
                len = crlen;
 
1540
            }
 
1541
            if (!lock_user_struct(VERIFY_WRITE, tcr, optval_addr, 0)) {
 
1542
                return -TARGET_EFAULT;
 
1543
            }
 
1544
            __put_user(cr.pid, &tcr->pid);
 
1545
            __put_user(cr.uid, &tcr->uid);
 
1546
            __put_user(cr.gid, &tcr->gid);
 
1547
            unlock_user_struct(tcr, optval_addr, 1);
 
1548
            if (put_user_u32(len, optlen)) {
 
1549
                return -TARGET_EFAULT;
 
1550
            }
 
1551
            break;
 
1552
        }
 
1553
        /* Options with 'int' argument.  */
 
1554
        case TARGET_SO_DEBUG:
 
1555
            optname = SO_DEBUG;
 
1556
            goto int_case;
 
1557
        case TARGET_SO_REUSEADDR:
 
1558
            optname = SO_REUSEADDR;
 
1559
            goto int_case;
 
1560
        case TARGET_SO_TYPE:
 
1561
            optname = SO_TYPE;
 
1562
            goto int_case;
 
1563
        case TARGET_SO_ERROR:
 
1564
            optname = SO_ERROR;
 
1565
            goto int_case;
 
1566
        case TARGET_SO_DONTROUTE:
 
1567
            optname = SO_DONTROUTE;
 
1568
            goto int_case;
 
1569
        case TARGET_SO_BROADCAST:
 
1570
            optname = SO_BROADCAST;
 
1571
            goto int_case;
 
1572
        case TARGET_SO_SNDBUF:
 
1573
            optname = SO_SNDBUF;
 
1574
            goto int_case;
 
1575
        case TARGET_SO_RCVBUF:
 
1576
            optname = SO_RCVBUF;
 
1577
            goto int_case;
 
1578
        case TARGET_SO_KEEPALIVE:
 
1579
            optname = SO_KEEPALIVE;
 
1580
            goto int_case;
 
1581
        case TARGET_SO_OOBINLINE:
 
1582
            optname = SO_OOBINLINE;
 
1583
            goto int_case;
 
1584
        case TARGET_SO_NO_CHECK:
 
1585
            optname = SO_NO_CHECK;
 
1586
            goto int_case;
 
1587
        case TARGET_SO_PRIORITY:
 
1588
            optname = SO_PRIORITY;
 
1589
            goto int_case;
 
1590
#ifdef SO_BSDCOMPAT
 
1591
        case TARGET_SO_BSDCOMPAT:
 
1592
            optname = SO_BSDCOMPAT;
 
1593
            goto int_case;
 
1594
#endif
 
1595
        case TARGET_SO_PASSCRED:
 
1596
            optname = SO_PASSCRED;
 
1597
            goto int_case;
 
1598
        case TARGET_SO_TIMESTAMP:
 
1599
            optname = SO_TIMESTAMP;
 
1600
            goto int_case;
 
1601
        case TARGET_SO_RCVLOWAT:
 
1602
            optname = SO_RCVLOWAT;
 
1603
            goto int_case;
 
1604
        default:
 
1605
            goto int_case;
 
1606
        }
 
1607
        break;
 
1608
    case SOL_TCP:
 
1609
        /* TCP options all take an 'int' value.  */
 
1610
    int_case:
 
1611
        if (get_user_u32(len, optlen))
 
1612
            return -TARGET_EFAULT;
 
1613
        if (len < 0)
 
1614
            return -TARGET_EINVAL;
 
1615
        lv = sizeof(lv);
 
1616
        ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
 
1617
        if (ret < 0)
 
1618
            return ret;
 
1619
        if (len > lv)
 
1620
            len = lv;
 
1621
        if (len == 4) {
 
1622
            if (put_user_u32(val, optval_addr))
 
1623
                return -TARGET_EFAULT;
 
1624
        } else {
 
1625
            if (put_user_u8(val, optval_addr))
 
1626
                return -TARGET_EFAULT;
 
1627
        }
 
1628
        if (put_user_u32(len, optlen))
 
1629
            return -TARGET_EFAULT;
 
1630
        break;
 
1631
    case SOL_IP:
 
1632
        switch(optname) {
 
1633
        case IP_TOS:
 
1634
        case IP_TTL:
 
1635
        case IP_HDRINCL:
 
1636
        case IP_ROUTER_ALERT:
 
1637
        case IP_RECVOPTS:
 
1638
        case IP_RETOPTS:
 
1639
        case IP_PKTINFO:
 
1640
        case IP_MTU_DISCOVER:
 
1641
        case IP_RECVERR:
 
1642
        case IP_RECVTOS:
 
1643
#ifdef IP_FREEBIND
 
1644
        case IP_FREEBIND:
 
1645
#endif
 
1646
        case IP_MULTICAST_TTL:
 
1647
        case IP_MULTICAST_LOOP:
 
1648
            if (get_user_u32(len, optlen))
 
1649
                return -TARGET_EFAULT;
 
1650
            if (len < 0)
 
1651
                return -TARGET_EINVAL;
 
1652
            lv = sizeof(lv);
 
1653
            ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
 
1654
            if (ret < 0)
 
1655
                return ret;
 
1656
            if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
 
1657
                len = 1;
 
1658
                if (put_user_u32(len, optlen)
 
1659
                    || put_user_u8(val, optval_addr))
 
1660
                    return -TARGET_EFAULT;
 
1661
            } else {
 
1662
                if (len > sizeof(int))
 
1663
                    len = sizeof(int);
 
1664
                if (put_user_u32(len, optlen)
 
1665
                    || put_user_u32(val, optval_addr))
 
1666
                    return -TARGET_EFAULT;
 
1667
            }
 
1668
            break;
 
1669
        default:
 
1670
            ret = -TARGET_ENOPROTOOPT;
 
1671
            break;
 
1672
        }
 
1673
        break;
 
1674
    default:
 
1675
    unimplemented:
 
1676
        gemu_log("getsockopt level=%d optname=%d not yet supported\n",
 
1677
                 level, optname);
 
1678
        ret = -TARGET_EOPNOTSUPP;
 
1679
        break;
 
1680
    }
 
1681
    return ret;
 
1682
}
 
1683
 
 
1684
static struct iovec *lock_iovec(int type, abi_ulong target_addr,
 
1685
                                int count, int copy)
 
1686
{
 
1687
    struct target_iovec *target_vec;
 
1688
    struct iovec *vec;
 
1689
    abi_ulong total_len, max_len;
 
1690
    int i;
 
1691
 
 
1692
    if (count == 0) {
 
1693
        errno = 0;
 
1694
        return NULL;
 
1695
    }
 
1696
    if (count < 0 || count > IOV_MAX) {
 
1697
        errno = EINVAL;
 
1698
        return NULL;
 
1699
    }
 
1700
 
 
1701
    vec = calloc(count, sizeof(struct iovec));
 
1702
    if (vec == NULL) {
 
1703
        errno = ENOMEM;
 
1704
        return NULL;
 
1705
    }
 
1706
 
 
1707
    target_vec = lock_user(VERIFY_READ, target_addr,
 
1708
                           count * sizeof(struct target_iovec), 1);
 
1709
    if (target_vec == NULL) {
 
1710
        errno = EFAULT;
 
1711
        goto fail2;
 
1712
    }
 
1713
 
 
1714
    /* ??? If host page size > target page size, this will result in a
 
1715
       value larger than what we can actually support.  */
 
1716
    max_len = 0x7fffffff & TARGET_PAGE_MASK;
 
1717
    total_len = 0;
 
1718
 
 
1719
    for (i = 0; i < count; i++) {
 
1720
        abi_ulong base = tswapal(target_vec[i].iov_base);
 
1721
        abi_long len = tswapal(target_vec[i].iov_len);
 
1722
 
 
1723
        if (len < 0) {
 
1724
            errno = EINVAL;
 
1725
            goto fail;
 
1726
        } else if (len == 0) {
 
1727
            /* Zero length pointer is ignored.  */
 
1728
            vec[i].iov_base = 0;
 
1729
        } else {
 
1730
            vec[i].iov_base = lock_user(type, base, len, copy);
 
1731
            if (!vec[i].iov_base) {
 
1732
                errno = EFAULT;
 
1733
                goto fail;
 
1734
            }
 
1735
            if (len > max_len - total_len) {
 
1736
                len = max_len - total_len;
 
1737
            }
 
1738
        }
 
1739
        vec[i].iov_len = len;
 
1740
        total_len += len;
 
1741
    }
 
1742
 
 
1743
    unlock_user(target_vec, target_addr, 0);
 
1744
    return vec;
 
1745
 
 
1746
 fail:
 
1747
    free(vec);
 
1748
 fail2:
 
1749
    unlock_user(target_vec, target_addr, 0);
 
1750
    return NULL;
 
1751
}
 
1752
 
 
1753
static void unlock_iovec(struct iovec *vec, abi_ulong target_addr,
 
1754
                         int count, int copy)
 
1755
{
 
1756
    struct target_iovec *target_vec;
 
1757
    int i;
 
1758
 
 
1759
    target_vec = lock_user(VERIFY_READ, target_addr,
 
1760
                           count * sizeof(struct target_iovec), 1);
 
1761
    if (target_vec) {
 
1762
        for (i = 0; i < count; i++) {
 
1763
            abi_ulong base = tswapal(target_vec[i].iov_base);
 
1764
            abi_long len = tswapal(target_vec[i].iov_base);
 
1765
            if (len < 0) {
 
1766
                break;
 
1767
            }
 
1768
            unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
 
1769
        }
 
1770
        unlock_user(target_vec, target_addr, 0);
 
1771
    }
 
1772
 
 
1773
    free(vec);
 
1774
}
 
1775
 
 
1776
static inline int target_to_host_sock_type(int *type)
 
1777
{
 
1778
    int host_type = 0;
 
1779
    int target_type = *type;
 
1780
 
 
1781
    switch (target_type & TARGET_SOCK_TYPE_MASK) {
 
1782
    case TARGET_SOCK_DGRAM:
 
1783
        host_type = SOCK_DGRAM;
 
1784
        break;
 
1785
    case TARGET_SOCK_STREAM:
 
1786
        host_type = SOCK_STREAM;
 
1787
        break;
 
1788
    default:
 
1789
        host_type = target_type & TARGET_SOCK_TYPE_MASK;
 
1790
        break;
 
1791
    }
 
1792
    if (target_type & TARGET_SOCK_CLOEXEC) {
 
1793
#if defined(SOCK_CLOEXEC)
 
1794
        host_type |= SOCK_CLOEXEC;
 
1795
#else
 
1796
        return -TARGET_EINVAL;
 
1797
#endif
 
1798
    }
 
1799
    if (target_type & TARGET_SOCK_NONBLOCK) {
 
1800
#if defined(SOCK_NONBLOCK)
 
1801
        host_type |= SOCK_NONBLOCK;
 
1802
#elif !defined(O_NONBLOCK)
 
1803
        return -TARGET_EINVAL;
 
1804
#endif
 
1805
    }
 
1806
    *type = host_type;
 
1807
    return 0;
 
1808
}
 
1809
 
 
1810
/* Try to emulate socket type flags after socket creation.  */
 
1811
static int sock_flags_fixup(int fd, int target_type)
 
1812
{
 
1813
#if !defined(SOCK_NONBLOCK) && defined(O_NONBLOCK)
 
1814
    if (target_type & TARGET_SOCK_NONBLOCK) {
 
1815
        int flags = fcntl(fd, F_GETFL);
 
1816
        if (fcntl(fd, F_SETFL, O_NONBLOCK | flags) == -1) {
 
1817
            close(fd);
 
1818
            return -TARGET_EINVAL;
 
1819
        }
 
1820
    }
 
1821
#endif
 
1822
    return fd;
 
1823
}
 
1824
 
 
1825
/* do_socket() Must return target values and target errnos. */
 
1826
static abi_long do_socket(int domain, int type, int protocol)
 
1827
{
 
1828
    int target_type = type;
 
1829
    int ret;
 
1830
 
 
1831
    ret = target_to_host_sock_type(&type);
 
1832
    if (ret) {
 
1833
        return ret;
 
1834
    }
 
1835
 
 
1836
    if (domain == PF_NETLINK)
 
1837
        return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
 
1838
    ret = get_errno(socket(domain, type, protocol));
 
1839
    if (ret >= 0) {
 
1840
        ret = sock_flags_fixup(ret, target_type);
 
1841
    }
 
1842
    return ret;
 
1843
}
 
1844
 
 
1845
/* do_bind() Must return target values and target errnos. */
 
1846
static abi_long do_bind(int sockfd, abi_ulong target_addr,
 
1847
                        socklen_t addrlen)
 
1848
{
 
1849
    void *addr;
 
1850
    abi_long ret;
 
1851
 
 
1852
    if ((int)addrlen < 0) {
 
1853
        return -TARGET_EINVAL;
 
1854
    }
 
1855
 
 
1856
    addr = alloca(addrlen+1);
 
1857
 
 
1858
    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
 
1859
    if (ret)
 
1860
        return ret;
 
1861
 
 
1862
    return get_errno(bind(sockfd, addr, addrlen));
 
1863
}
 
1864
 
 
1865
/* do_connect() Must return target values and target errnos. */
 
1866
static abi_long do_connect(int sockfd, abi_ulong target_addr,
 
1867
                           socklen_t addrlen)
 
1868
{
 
1869
    void *addr;
 
1870
    abi_long ret;
 
1871
 
 
1872
    if ((int)addrlen < 0) {
 
1873
        return -TARGET_EINVAL;
 
1874
    }
 
1875
 
 
1876
    addr = alloca(addrlen);
 
1877
 
 
1878
    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
 
1879
    if (ret)
 
1880
        return ret;
 
1881
 
 
1882
    return get_errno(connect(sockfd, addr, addrlen));
 
1883
}
 
1884
 
 
1885
/* do_sendrecvmsg() Must return target values and target errnos. */
 
1886
static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
 
1887
                               int flags, int send)
 
1888
{
 
1889
    abi_long ret, len;
 
1890
    struct target_msghdr *msgp;
 
1891
    struct msghdr msg;
 
1892
    int count;
 
1893
    struct iovec *vec;
 
1894
    abi_ulong target_vec;
 
1895
 
 
1896
    /* FIXME */
 
1897
    if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
 
1898
                          msgp,
 
1899
                          target_msg,
 
1900
                          send ? 1 : 0))
 
1901
        return -TARGET_EFAULT;
 
1902
    if (msgp->msg_name) {
 
1903
        msg.msg_namelen = tswap32(msgp->msg_namelen);
 
1904
        msg.msg_name = alloca(msg.msg_namelen);
 
1905
        ret = target_to_host_sockaddr(msg.msg_name, tswapal(msgp->msg_name),
 
1906
                                msg.msg_namelen);
 
1907
        if (ret) {
 
1908
            goto out2;
 
1909
        }
 
1910
    } else {
 
1911
        msg.msg_name = NULL;
 
1912
        msg.msg_namelen = 0;
 
1913
    }
 
1914
    msg.msg_controllen = 2 * tswapal(msgp->msg_controllen);
 
1915
    msg.msg_control = alloca(msg.msg_controllen);
 
1916
    msg.msg_flags = tswap32(msgp->msg_flags);
 
1917
 
 
1918
    count = tswapal(msgp->msg_iovlen);
 
1919
    target_vec = tswapal(msgp->msg_iov);
 
1920
    vec = lock_iovec(send ? VERIFY_READ : VERIFY_WRITE,
 
1921
                     target_vec, count, send);
 
1922
    if (vec == NULL) {
 
1923
        ret = -host_to_target_errno(errno);
 
1924
        goto out2;
 
1925
    }
 
1926
    msg.msg_iovlen = count;
 
1927
    msg.msg_iov = vec;
 
1928
 
 
1929
    if (send) {
 
1930
        ret = target_to_host_cmsg(&msg, msgp);
 
1931
        if (ret == 0)
 
1932
            ret = get_errno(sendmsg(fd, &msg, flags));
 
1933
    } else {
 
1934
        ret = get_errno(recvmsg(fd, &msg, flags));
 
1935
        if (!is_error(ret)) {
 
1936
            len = ret;
 
1937
            ret = host_to_target_cmsg(msgp, &msg);
 
1938
            if (!is_error(ret)) {
 
1939
                msgp->msg_namelen = tswap32(msg.msg_namelen);
 
1940
                if (msg.msg_name != NULL) {
 
1941
                    ret = host_to_target_sockaddr(tswapal(msgp->msg_name),
 
1942
                                    msg.msg_name, msg.msg_namelen);
 
1943
                    if (ret) {
 
1944
                        goto out;
 
1945
                    }
 
1946
                }
 
1947
 
 
1948
                ret = len;
 
1949
            }
 
1950
        }
 
1951
    }
 
1952
 
 
1953
out:
 
1954
    unlock_iovec(vec, target_vec, count, !send);
 
1955
out2:
 
1956
    unlock_user_struct(msgp, target_msg, send ? 0 : 1);
 
1957
    return ret;
 
1958
}
 
1959
 
 
1960
#ifdef TARGET_NR_sendmmsg
 
1961
static abi_long do_sendmmsg(int fd, abi_ulong target_msgvec,
 
1962
                            unsigned int vlen, unsigned int flags)
 
1963
{
 
1964
    struct target_mmsghdr *mmsgp;
 
1965
    abi_ulong arg2 = target_msgvec;
 
1966
    int i;
 
1967
 
 
1968
    if (!(mmsgp = lock_user(VERIFY_WRITE, target_msgvec,
 
1969
                            sizeof(*mmsgp) * vlen, 1))) {
 
1970
        return -TARGET_EFAULT;
 
1971
    }
 
1972
 
 
1973
    for (i = 0; i < vlen; i++) {
 
1974
        mmsgp[i].msg_len = tswap32(do_sendrecvmsg(fd, arg2, flags, 1));
 
1975
        arg2 += sizeof(struct target_mmsghdr);
 
1976
    }
 
1977
 
 
1978
    unlock_user(mmsgp, target_msgvec, 0);
 
1979
    /* XXX need to handle nonblocking case too */
 
1980
    return vlen;
 
1981
}
 
1982
#endif
 
1983
 
 
1984
/* If we don't have a system accept4() then just call accept.
 
1985
 * The callsites to do_accept4() will ensure that they don't
 
1986
 * pass a non-zero flags argument in this config.
 
1987
 */
 
1988
#ifndef CONFIG_ACCEPT4
 
1989
static inline int accept4(int sockfd, struct sockaddr *addr,
 
1990
                          socklen_t *addrlen, int flags)
 
1991
{
 
1992
    assert(flags == 0);
 
1993
    return accept(sockfd, addr, addrlen);
 
1994
}
 
1995
#endif
 
1996
 
 
1997
/* do_accept4() Must return target values and target errnos. */
 
1998
static abi_long do_accept4(int fd, abi_ulong target_addr,
 
1999
                           abi_ulong target_addrlen_addr, int flags)
 
2000
{
 
2001
    socklen_t addrlen;
 
2002
    void *addr;
 
2003
    abi_long ret;
 
2004
 
 
2005
    if (target_addr == 0) {
 
2006
        return get_errno(accept4(fd, NULL, NULL, flags));
 
2007
    }
 
2008
 
 
2009
    /* linux returns EINVAL if addrlen pointer is invalid */
 
2010
    if (get_user_u32(addrlen, target_addrlen_addr))
 
2011
        return -TARGET_EINVAL;
 
2012
 
 
2013
    if ((int)addrlen < 0) {
 
2014
        return -TARGET_EINVAL;
 
2015
    }
 
2016
 
 
2017
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
 
2018
        return -TARGET_EINVAL;
 
2019
 
 
2020
    addr = alloca(addrlen);
 
2021
 
 
2022
    ret = get_errno(accept4(fd, addr, &addrlen, flags));
 
2023
    if (!is_error(ret)) {
 
2024
        host_to_target_sockaddr(target_addr, addr, addrlen);
 
2025
        if (put_user_u32(addrlen, target_addrlen_addr))
 
2026
            ret = -TARGET_EFAULT;
 
2027
    }
 
2028
    return ret;
 
2029
}
 
2030
 
 
2031
/* do_getpeername() Must return target values and target errnos. */
 
2032
static abi_long do_getpeername(int fd, abi_ulong target_addr,
 
2033
                               abi_ulong target_addrlen_addr)
 
2034
{
 
2035
    socklen_t addrlen;
 
2036
    void *addr;
 
2037
    abi_long ret;
 
2038
 
 
2039
    if (get_user_u32(addrlen, target_addrlen_addr))
 
2040
        return -TARGET_EFAULT;
 
2041
 
 
2042
    if ((int)addrlen < 0) {
 
2043
        return -TARGET_EINVAL;
 
2044
    }
 
2045
 
 
2046
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
 
2047
        return -TARGET_EFAULT;
 
2048
 
 
2049
    addr = alloca(addrlen);
 
2050
 
 
2051
    ret = get_errno(getpeername(fd, addr, &addrlen));
 
2052
    if (!is_error(ret)) {
 
2053
        host_to_target_sockaddr(target_addr, addr, addrlen);
 
2054
        if (put_user_u32(addrlen, target_addrlen_addr))
 
2055
            ret = -TARGET_EFAULT;
 
2056
    }
 
2057
    return ret;
 
2058
}
 
2059
 
 
2060
/* do_getsockname() Must return target values and target errnos. */
 
2061
static abi_long do_getsockname(int fd, abi_ulong target_addr,
 
2062
                               abi_ulong target_addrlen_addr)
 
2063
{
 
2064
    socklen_t addrlen;
 
2065
    void *addr;
 
2066
    abi_long ret;
 
2067
 
 
2068
    if (get_user_u32(addrlen, target_addrlen_addr))
 
2069
        return -TARGET_EFAULT;
 
2070
 
 
2071
    if ((int)addrlen < 0) {
 
2072
        return -TARGET_EINVAL;
 
2073
    }
 
2074
 
 
2075
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
 
2076
        return -TARGET_EFAULT;
 
2077
 
 
2078
    addr = alloca(addrlen);
 
2079
 
 
2080
    ret = get_errno(getsockname(fd, addr, &addrlen));
 
2081
    if (!is_error(ret)) {
 
2082
        host_to_target_sockaddr(target_addr, addr, addrlen);
 
2083
        if (put_user_u32(addrlen, target_addrlen_addr))
 
2084
            ret = -TARGET_EFAULT;
 
2085
    }
 
2086
    return ret;
 
2087
}
 
2088
 
 
2089
/* do_socketpair() Must return target values and target errnos. */
 
2090
static abi_long do_socketpair(int domain, int type, int protocol,
 
2091
                              abi_ulong target_tab_addr)
 
2092
{
 
2093
    int tab[2];
 
2094
    abi_long ret;
 
2095
 
 
2096
    target_to_host_sock_type(&type);
 
2097
 
 
2098
    ret = get_errno(socketpair(domain, type, protocol, tab));
 
2099
    if (!is_error(ret)) {
 
2100
        if (put_user_s32(tab[0], target_tab_addr)
 
2101
            || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
 
2102
            ret = -TARGET_EFAULT;
 
2103
    }
 
2104
    return ret;
 
2105
}
 
2106
 
 
2107
/* do_sendto() Must return target values and target errnos. */
 
2108
static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
 
2109
                          abi_ulong target_addr, socklen_t addrlen)
 
2110
{
 
2111
    void *addr;
 
2112
    void *host_msg;
 
2113
    abi_long ret;
 
2114
 
 
2115
    if ((int)addrlen < 0) {
 
2116
        return -TARGET_EINVAL;
 
2117
    }
 
2118
 
 
2119
    host_msg = lock_user(VERIFY_READ, msg, len, 1);
 
2120
    if (!host_msg)
 
2121
        return -TARGET_EFAULT;
 
2122
    if (target_addr) {
 
2123
        addr = alloca(addrlen);
 
2124
        ret = target_to_host_sockaddr(addr, target_addr, addrlen);
 
2125
        if (ret) {
 
2126
            unlock_user(host_msg, msg, 0);
 
2127
            return ret;
 
2128
        }
 
2129
        ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
 
2130
    } else {
 
2131
        ret = get_errno(send(fd, host_msg, len, flags));
 
2132
    }
 
2133
    unlock_user(host_msg, msg, 0);
 
2134
    return ret;
 
2135
}
 
2136
 
 
2137
/* do_recvfrom() Must return target values and target errnos. */
 
2138
static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
 
2139
                            abi_ulong target_addr,
 
2140
                            abi_ulong target_addrlen)
 
2141
{
 
2142
    socklen_t addrlen;
 
2143
    void *addr;
 
2144
    void *host_msg;
 
2145
    abi_long ret;
 
2146
 
 
2147
    host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
 
2148
    if (!host_msg)
 
2149
        return -TARGET_EFAULT;
 
2150
    if (target_addr) {
 
2151
        if (get_user_u32(addrlen, target_addrlen)) {
 
2152
            ret = -TARGET_EFAULT;
 
2153
            goto fail;
 
2154
        }
 
2155
        if ((int)addrlen < 0) {
 
2156
            ret = -TARGET_EINVAL;
 
2157
            goto fail;
 
2158
        }
 
2159
        addr = alloca(addrlen);
 
2160
        ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
 
2161
    } else {
 
2162
        addr = NULL; /* To keep compiler quiet.  */
 
2163
        ret = get_errno(qemu_recv(fd, host_msg, len, flags));
 
2164
    }
 
2165
    if (!is_error(ret)) {
 
2166
        if (target_addr) {
 
2167
            host_to_target_sockaddr(target_addr, addr, addrlen);
 
2168
            if (put_user_u32(addrlen, target_addrlen)) {
 
2169
                ret = -TARGET_EFAULT;
 
2170
                goto fail;
 
2171
            }
 
2172
        }
 
2173
        unlock_user(host_msg, msg, len);
 
2174
    } else {
 
2175
fail:
 
2176
        unlock_user(host_msg, msg, 0);
 
2177
    }
 
2178
    return ret;
 
2179
}
 
2180
 
 
2181
#ifdef TARGET_NR_socketcall
 
2182
/* do_socketcall() Must return target values and target errnos. */
 
2183
static abi_long do_socketcall(int num, abi_ulong vptr)
 
2184
{
 
2185
    abi_long ret;
 
2186
    const int n = sizeof(abi_ulong);
 
2187
 
 
2188
    switch(num) {
 
2189
    case SOCKOP_socket:
 
2190
        {
 
2191
            abi_ulong domain, type, protocol;
 
2192
 
 
2193
            if (get_user_ual(domain, vptr)
 
2194
                || get_user_ual(type, vptr + n)
 
2195
                || get_user_ual(protocol, vptr + 2 * n))
 
2196
                return -TARGET_EFAULT;
 
2197
 
 
2198
            ret = do_socket(domain, type, protocol);
 
2199
        }
 
2200
        break;
 
2201
    case SOCKOP_bind:
 
2202
        {
 
2203
            abi_ulong sockfd;
 
2204
            abi_ulong target_addr;
 
2205
            socklen_t addrlen;
 
2206
 
 
2207
            if (get_user_ual(sockfd, vptr)
 
2208
                || get_user_ual(target_addr, vptr + n)
 
2209
                || get_user_ual(addrlen, vptr + 2 * n))
 
2210
                return -TARGET_EFAULT;
 
2211
 
 
2212
            ret = do_bind(sockfd, target_addr, addrlen);
 
2213
        }
 
2214
        break;
 
2215
    case SOCKOP_connect:
 
2216
        {
 
2217
            abi_ulong sockfd;
 
2218
            abi_ulong target_addr;
 
2219
            socklen_t addrlen;
 
2220
 
 
2221
            if (get_user_ual(sockfd, vptr)
 
2222
                || get_user_ual(target_addr, vptr + n)
 
2223
                || get_user_ual(addrlen, vptr + 2 * n))
 
2224
                return -TARGET_EFAULT;
 
2225
 
 
2226
            ret = do_connect(sockfd, target_addr, addrlen);
 
2227
        }
 
2228
        break;
 
2229
    case SOCKOP_listen:
 
2230
        {
 
2231
            abi_ulong sockfd, backlog;
 
2232
 
 
2233
            if (get_user_ual(sockfd, vptr)
 
2234
                || get_user_ual(backlog, vptr + n))
 
2235
                return -TARGET_EFAULT;
 
2236
 
 
2237
            ret = get_errno(listen(sockfd, backlog));
 
2238
        }
 
2239
        break;
 
2240
    case SOCKOP_accept:
 
2241
        {
 
2242
            abi_ulong sockfd;
 
2243
            abi_ulong target_addr, target_addrlen;
 
2244
 
 
2245
            if (get_user_ual(sockfd, vptr)
 
2246
                || get_user_ual(target_addr, vptr + n)
 
2247
                || get_user_ual(target_addrlen, vptr + 2 * n))
 
2248
                return -TARGET_EFAULT;
 
2249
 
 
2250
            ret = do_accept4(sockfd, target_addr, target_addrlen, 0);
 
2251
        }
 
2252
        break;
 
2253
    case SOCKOP_getsockname:
 
2254
        {
 
2255
            abi_ulong sockfd;
 
2256
            abi_ulong target_addr, target_addrlen;
 
2257
 
 
2258
            if (get_user_ual(sockfd, vptr)
 
2259
                || get_user_ual(target_addr, vptr + n)
 
2260
                || get_user_ual(target_addrlen, vptr + 2 * n))
 
2261
                return -TARGET_EFAULT;
 
2262
 
 
2263
            ret = do_getsockname(sockfd, target_addr, target_addrlen);
 
2264
        }
 
2265
        break;
 
2266
    case SOCKOP_getpeername:
 
2267
        {
 
2268
            abi_ulong sockfd;
 
2269
            abi_ulong target_addr, target_addrlen;
 
2270
 
 
2271
            if (get_user_ual(sockfd, vptr)
 
2272
                || get_user_ual(target_addr, vptr + n)
 
2273
                || get_user_ual(target_addrlen, vptr + 2 * n))
 
2274
                return -TARGET_EFAULT;
 
2275
 
 
2276
            ret = do_getpeername(sockfd, target_addr, target_addrlen);
 
2277
        }
 
2278
        break;
 
2279
    case SOCKOP_socketpair:
 
2280
        {
 
2281
            abi_ulong domain, type, protocol;
 
2282
            abi_ulong tab;
 
2283
 
 
2284
            if (get_user_ual(domain, vptr)
 
2285
                || get_user_ual(type, vptr + n)
 
2286
                || get_user_ual(protocol, vptr + 2 * n)
 
2287
                || get_user_ual(tab, vptr + 3 * n))
 
2288
                return -TARGET_EFAULT;
 
2289
 
 
2290
            ret = do_socketpair(domain, type, protocol, tab);
 
2291
        }
 
2292
        break;
 
2293
    case SOCKOP_send:
 
2294
        {
 
2295
            abi_ulong sockfd;
 
2296
            abi_ulong msg;
 
2297
            size_t len;
 
2298
            abi_ulong flags;
 
2299
 
 
2300
            if (get_user_ual(sockfd, vptr)
 
2301
                || get_user_ual(msg, vptr + n)
 
2302
                || get_user_ual(len, vptr + 2 * n)
 
2303
                || get_user_ual(flags, vptr + 3 * n))
 
2304
                return -TARGET_EFAULT;
 
2305
 
 
2306
            ret = do_sendto(sockfd, msg, len, flags, 0, 0);
 
2307
        }
 
2308
        break;
 
2309
    case SOCKOP_recv:
 
2310
        {
 
2311
            abi_ulong sockfd;
 
2312
            abi_ulong msg;
 
2313
            size_t len;
 
2314
            abi_ulong flags;
 
2315
 
 
2316
            if (get_user_ual(sockfd, vptr)
 
2317
                || get_user_ual(msg, vptr + n)
 
2318
                || get_user_ual(len, vptr + 2 * n)
 
2319
                || get_user_ual(flags, vptr + 3 * n))
 
2320
                return -TARGET_EFAULT;
 
2321
 
 
2322
            ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
 
2323
        }
 
2324
        break;
 
2325
    case SOCKOP_sendto:
 
2326
        {
 
2327
            abi_ulong sockfd;
 
2328
            abi_ulong msg;
 
2329
            size_t len;
 
2330
            abi_ulong flags;
 
2331
            abi_ulong addr;
 
2332
            socklen_t addrlen;
 
2333
 
 
2334
            if (get_user_ual(sockfd, vptr)
 
2335
                || get_user_ual(msg, vptr + n)
 
2336
                || get_user_ual(len, vptr + 2 * n)
 
2337
                || get_user_ual(flags, vptr + 3 * n)
 
2338
                || get_user_ual(addr, vptr + 4 * n)
 
2339
                || get_user_ual(addrlen, vptr + 5 * n))
 
2340
                return -TARGET_EFAULT;
 
2341
 
 
2342
            ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
 
2343
        }
 
2344
        break;
 
2345
    case SOCKOP_recvfrom:
 
2346
        {
 
2347
            abi_ulong sockfd;
 
2348
            abi_ulong msg;
 
2349
            size_t len;
 
2350
            abi_ulong flags;
 
2351
            abi_ulong addr;
 
2352
            socklen_t addrlen;
 
2353
 
 
2354
            if (get_user_ual(sockfd, vptr)
 
2355
                || get_user_ual(msg, vptr + n)
 
2356
                || get_user_ual(len, vptr + 2 * n)
 
2357
                || get_user_ual(flags, vptr + 3 * n)
 
2358
                || get_user_ual(addr, vptr + 4 * n)
 
2359
                || get_user_ual(addrlen, vptr + 5 * n))
 
2360
                return -TARGET_EFAULT;
 
2361
 
 
2362
            ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
 
2363
        }
 
2364
        break;
 
2365
    case SOCKOP_shutdown:
 
2366
        {
 
2367
            abi_ulong sockfd, how;
 
2368
 
 
2369
            if (get_user_ual(sockfd, vptr)
 
2370
                || get_user_ual(how, vptr + n))
 
2371
                return -TARGET_EFAULT;
 
2372
 
 
2373
            ret = get_errno(shutdown(sockfd, how));
 
2374
        }
 
2375
        break;
 
2376
    case SOCKOP_sendmsg:
 
2377
    case SOCKOP_recvmsg:
 
2378
        {
 
2379
            abi_ulong fd;
 
2380
            abi_ulong target_msg;
 
2381
            abi_ulong flags;
 
2382
 
 
2383
            if (get_user_ual(fd, vptr)
 
2384
                || get_user_ual(target_msg, vptr + n)
 
2385
                || get_user_ual(flags, vptr + 2 * n))
 
2386
                return -TARGET_EFAULT;
 
2387
 
 
2388
            ret = do_sendrecvmsg(fd, target_msg, flags,
 
2389
                                 (num == SOCKOP_sendmsg));
 
2390
        }
 
2391
        break;
 
2392
    case SOCKOP_setsockopt:
 
2393
        {
 
2394
            abi_ulong sockfd;
 
2395
            abi_ulong level;
 
2396
            abi_ulong optname;
 
2397
            abi_ulong optval;
 
2398
            socklen_t optlen;
 
2399
 
 
2400
            if (get_user_ual(sockfd, vptr)
 
2401
                || get_user_ual(level, vptr + n)
 
2402
                || get_user_ual(optname, vptr + 2 * n)
 
2403
                || get_user_ual(optval, vptr + 3 * n)
 
2404
                || get_user_ual(optlen, vptr + 4 * n))
 
2405
                return -TARGET_EFAULT;
 
2406
 
 
2407
            ret = do_setsockopt(sockfd, level, optname, optval, optlen);
 
2408
        }
 
2409
        break;
 
2410
    case SOCKOP_getsockopt:
 
2411
        {
 
2412
            abi_ulong sockfd;
 
2413
            abi_ulong level;
 
2414
            abi_ulong optname;
 
2415
            abi_ulong optval;
 
2416
            socklen_t optlen;
 
2417
 
 
2418
            if (get_user_ual(sockfd, vptr)
 
2419
                || get_user_ual(level, vptr + n)
 
2420
                || get_user_ual(optname, vptr + 2 * n)
 
2421
                || get_user_ual(optval, vptr + 3 * n)
 
2422
                || get_user_ual(optlen, vptr + 4 * n))
 
2423
                return -TARGET_EFAULT;
 
2424
 
 
2425
            ret = do_getsockopt(sockfd, level, optname, optval, optlen);
 
2426
        }
 
2427
        break;
 
2428
    default:
 
2429
        gemu_log("Unsupported socketcall: %d\n", num);
 
2430
        ret = -TARGET_ENOSYS;
 
2431
        break;
 
2432
    }
 
2433
    return ret;
 
2434
}
 
2435
#endif
 
2436
 
 
2437
#define N_SHM_REGIONS   32
 
2438
 
 
2439
static struct shm_region {
 
2440
    abi_ulong   start;
 
2441
    abi_ulong   size;
 
2442
} shm_regions[N_SHM_REGIONS];
 
2443
 
 
2444
struct target_ipc_perm
 
2445
{
 
2446
    abi_long __key;
 
2447
    abi_ulong uid;
 
2448
    abi_ulong gid;
 
2449
    abi_ulong cuid;
 
2450
    abi_ulong cgid;
 
2451
    unsigned short int mode;
 
2452
    unsigned short int __pad1;
 
2453
    unsigned short int __seq;
 
2454
    unsigned short int __pad2;
 
2455
    abi_ulong __unused1;
 
2456
    abi_ulong __unused2;
 
2457
};
 
2458
 
 
2459
struct target_semid_ds
 
2460
{
 
2461
  struct target_ipc_perm sem_perm;
 
2462
  abi_ulong sem_otime;
 
2463
  abi_ulong __unused1;
 
2464
  abi_ulong sem_ctime;
 
2465
  abi_ulong __unused2;
 
2466
  abi_ulong sem_nsems;
 
2467
  abi_ulong __unused3;
 
2468
  abi_ulong __unused4;
 
2469
};
 
2470
 
 
2471
static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
 
2472
                                               abi_ulong target_addr)
 
2473
{
 
2474
    struct target_ipc_perm *target_ip;
 
2475
    struct target_semid_ds *target_sd;
 
2476
 
 
2477
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
 
2478
        return -TARGET_EFAULT;
 
2479
    target_ip = &(target_sd->sem_perm);
 
2480
    host_ip->__key = tswapal(target_ip->__key);
 
2481
    host_ip->uid = tswapal(target_ip->uid);
 
2482
    host_ip->gid = tswapal(target_ip->gid);
 
2483
    host_ip->cuid = tswapal(target_ip->cuid);
 
2484
    host_ip->cgid = tswapal(target_ip->cgid);
 
2485
    host_ip->mode = tswap16(target_ip->mode);
 
2486
    unlock_user_struct(target_sd, target_addr, 0);
 
2487
    return 0;
 
2488
}
 
2489
 
 
2490
static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
 
2491
                                               struct ipc_perm *host_ip)
 
2492
{
 
2493
    struct target_ipc_perm *target_ip;
 
2494
    struct target_semid_ds *target_sd;
 
2495
 
 
2496
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
 
2497
        return -TARGET_EFAULT;
 
2498
    target_ip = &(target_sd->sem_perm);
 
2499
    target_ip->__key = tswapal(host_ip->__key);
 
2500
    target_ip->uid = tswapal(host_ip->uid);
 
2501
    target_ip->gid = tswapal(host_ip->gid);
 
2502
    target_ip->cuid = tswapal(host_ip->cuid);
 
2503
    target_ip->cgid = tswapal(host_ip->cgid);
 
2504
    target_ip->mode = tswap16(host_ip->mode);
 
2505
    unlock_user_struct(target_sd, target_addr, 1);
 
2506
    return 0;
 
2507
}
 
2508
 
 
2509
static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
 
2510
                                               abi_ulong target_addr)
 
2511
{
 
2512
    struct target_semid_ds *target_sd;
 
2513
 
 
2514
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
 
2515
        return -TARGET_EFAULT;
 
2516
    if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr))
 
2517
        return -TARGET_EFAULT;
 
2518
    host_sd->sem_nsems = tswapal(target_sd->sem_nsems);
 
2519
    host_sd->sem_otime = tswapal(target_sd->sem_otime);
 
2520
    host_sd->sem_ctime = tswapal(target_sd->sem_ctime);
 
2521
    unlock_user_struct(target_sd, target_addr, 0);
 
2522
    return 0;
 
2523
}
 
2524
 
 
2525
static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
 
2526
                                               struct semid_ds *host_sd)
 
2527
{
 
2528
    struct target_semid_ds *target_sd;
 
2529
 
 
2530
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
 
2531
        return -TARGET_EFAULT;
 
2532
    if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
 
2533
        return -TARGET_EFAULT;
 
2534
    target_sd->sem_nsems = tswapal(host_sd->sem_nsems);
 
2535
    target_sd->sem_otime = tswapal(host_sd->sem_otime);
 
2536
    target_sd->sem_ctime = tswapal(host_sd->sem_ctime);
 
2537
    unlock_user_struct(target_sd, target_addr, 1);
 
2538
    return 0;
 
2539
}
 
2540
 
 
2541
struct target_seminfo {
 
2542
    int semmap;
 
2543
    int semmni;
 
2544
    int semmns;
 
2545
    int semmnu;
 
2546
    int semmsl;
 
2547
    int semopm;
 
2548
    int semume;
 
2549
    int semusz;
 
2550
    int semvmx;
 
2551
    int semaem;
 
2552
};
 
2553
 
 
2554
static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
 
2555
                                              struct seminfo *host_seminfo)
 
2556
{
 
2557
    struct target_seminfo *target_seminfo;
 
2558
    if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
 
2559
        return -TARGET_EFAULT;
 
2560
    __put_user(host_seminfo->semmap, &target_seminfo->semmap);
 
2561
    __put_user(host_seminfo->semmni, &target_seminfo->semmni);
 
2562
    __put_user(host_seminfo->semmns, &target_seminfo->semmns);
 
2563
    __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
 
2564
    __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
 
2565
    __put_user(host_seminfo->semopm, &target_seminfo->semopm);
 
2566
    __put_user(host_seminfo->semume, &target_seminfo->semume);
 
2567
    __put_user(host_seminfo->semusz, &target_seminfo->semusz);
 
2568
    __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
 
2569
    __put_user(host_seminfo->semaem, &target_seminfo->semaem);
 
2570
    unlock_user_struct(target_seminfo, target_addr, 1);
 
2571
    return 0;
 
2572
}
 
2573
 
 
2574
union semun {
 
2575
        int val;
 
2576
        struct semid_ds *buf;
 
2577
        unsigned short *array;
 
2578
        struct seminfo *__buf;
 
2579
};
 
2580
 
 
2581
union target_semun {
 
2582
        int val;
 
2583
        abi_ulong buf;
 
2584
        abi_ulong array;
 
2585
        abi_ulong __buf;
 
2586
};
 
2587
 
 
2588
static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
 
2589
                                               abi_ulong target_addr)
 
2590
{
 
2591
    int nsems;
 
2592
    unsigned short *array;
 
2593
    union semun semun;
 
2594
    struct semid_ds semid_ds;
 
2595
    int i, ret;
 
2596
 
 
2597
    semun.buf = &semid_ds;
 
2598
 
 
2599
    ret = semctl(semid, 0, IPC_STAT, semun);
 
2600
    if (ret == -1)
 
2601
        return get_errno(ret);
 
2602
 
 
2603
    nsems = semid_ds.sem_nsems;
 
2604
 
 
2605
    *host_array = malloc(nsems*sizeof(unsigned short));
 
2606
    array = lock_user(VERIFY_READ, target_addr,
 
2607
                      nsems*sizeof(unsigned short), 1);
 
2608
    if (!array)
 
2609
        return -TARGET_EFAULT;
 
2610
 
 
2611
    for(i=0; i<nsems; i++) {
 
2612
        __get_user((*host_array)[i], &array[i]);
 
2613
    }
 
2614
    unlock_user(array, target_addr, 0);
 
2615
 
 
2616
    return 0;
 
2617
}
 
2618
 
 
2619
static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
 
2620
                                               unsigned short **host_array)
 
2621
{
 
2622
    int nsems;
 
2623
    unsigned short *array;
 
2624
    union semun semun;
 
2625
    struct semid_ds semid_ds;
 
2626
    int i, ret;
 
2627
 
 
2628
    semun.buf = &semid_ds;
 
2629
 
 
2630
    ret = semctl(semid, 0, IPC_STAT, semun);
 
2631
    if (ret == -1)
 
2632
        return get_errno(ret);
 
2633
 
 
2634
    nsems = semid_ds.sem_nsems;
 
2635
 
 
2636
    array = lock_user(VERIFY_WRITE, target_addr,
 
2637
                      nsems*sizeof(unsigned short), 0);
 
2638
    if (!array)
 
2639
        return -TARGET_EFAULT;
 
2640
 
 
2641
    for(i=0; i<nsems; i++) {
 
2642
        __put_user((*host_array)[i], &array[i]);
 
2643
    }
 
2644
    free(*host_array);
 
2645
    unlock_user(array, target_addr, 1);
 
2646
 
 
2647
    return 0;
 
2648
}
 
2649
 
 
2650
static inline abi_long do_semctl(int semid, int semnum, int cmd,
 
2651
                                 union target_semun target_su)
 
2652
{
 
2653
    union semun arg;
 
2654
    struct semid_ds dsarg;
 
2655
    unsigned short *array = NULL;
 
2656
    struct seminfo seminfo;
 
2657
    abi_long ret = -TARGET_EINVAL;
 
2658
    abi_long err;
 
2659
    cmd &= 0xff;
 
2660
 
 
2661
    switch( cmd ) {
 
2662
        case GETVAL:
 
2663
        case SETVAL:
 
2664
            arg.val = tswap32(target_su.val);
 
2665
            ret = get_errno(semctl(semid, semnum, cmd, arg));
 
2666
            target_su.val = tswap32(arg.val);
 
2667
            break;
 
2668
        case GETALL:
 
2669
        case SETALL:
 
2670
            err = target_to_host_semarray(semid, &array, target_su.array);
 
2671
            if (err)
 
2672
                return err;
 
2673
            arg.array = array;
 
2674
            ret = get_errno(semctl(semid, semnum, cmd, arg));
 
2675
            err = host_to_target_semarray(semid, target_su.array, &array);
 
2676
            if (err)
 
2677
                return err;
 
2678
            break;
 
2679
        case IPC_STAT:
 
2680
        case IPC_SET:
 
2681
        case SEM_STAT:
 
2682
            err = target_to_host_semid_ds(&dsarg, target_su.buf);
 
2683
            if (err)
 
2684
                return err;
 
2685
            arg.buf = &dsarg;
 
2686
            ret = get_errno(semctl(semid, semnum, cmd, arg));
 
2687
            err = host_to_target_semid_ds(target_su.buf, &dsarg);
 
2688
            if (err)
 
2689
                return err;
 
2690
            break;
 
2691
        case IPC_INFO:
 
2692
        case SEM_INFO:
 
2693
            arg.__buf = &seminfo;
 
2694
            ret = get_errno(semctl(semid, semnum, cmd, arg));
 
2695
            err = host_to_target_seminfo(target_su.__buf, &seminfo);
 
2696
            if (err)
 
2697
                return err;
 
2698
            break;
 
2699
        case IPC_RMID:
 
2700
        case GETPID:
 
2701
        case GETNCNT:
 
2702
        case GETZCNT:
 
2703
            ret = get_errno(semctl(semid, semnum, cmd, NULL));
 
2704
            break;
 
2705
    }
 
2706
 
 
2707
    return ret;
 
2708
}
 
2709
 
 
2710
struct target_sembuf {
 
2711
    unsigned short sem_num;
 
2712
    short sem_op;
 
2713
    short sem_flg;
 
2714
};
 
2715
 
 
2716
static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
 
2717
                                             abi_ulong target_addr,
 
2718
                                             unsigned nsops)
 
2719
{
 
2720
    struct target_sembuf *target_sembuf;
 
2721
    int i;
 
2722
 
 
2723
    target_sembuf = lock_user(VERIFY_READ, target_addr,
 
2724
                              nsops*sizeof(struct target_sembuf), 1);
 
2725
    if (!target_sembuf)
 
2726
        return -TARGET_EFAULT;
 
2727
 
 
2728
    for(i=0; i<nsops; i++) {
 
2729
        __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
 
2730
        __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
 
2731
        __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
 
2732
    }
 
2733
 
 
2734
    unlock_user(target_sembuf, target_addr, 0);
 
2735
 
 
2736
    return 0;
 
2737
}
 
2738
 
 
2739
static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
 
2740
{
 
2741
    struct sembuf sops[nsops];
 
2742
 
 
2743
    if (target_to_host_sembuf(sops, ptr, nsops))
 
2744
        return -TARGET_EFAULT;
 
2745
 
 
2746
    return get_errno(semop(semid, sops, nsops));
 
2747
}
 
2748
 
 
2749
struct target_msqid_ds
 
2750
{
 
2751
    struct target_ipc_perm msg_perm;
 
2752
    abi_ulong msg_stime;
 
2753
#if TARGET_ABI_BITS == 32
 
2754
    abi_ulong __unused1;
 
2755
#endif
 
2756
    abi_ulong msg_rtime;
 
2757
#if TARGET_ABI_BITS == 32
 
2758
    abi_ulong __unused2;
 
2759
#endif
 
2760
    abi_ulong msg_ctime;
 
2761
#if TARGET_ABI_BITS == 32
 
2762
    abi_ulong __unused3;
 
2763
#endif
 
2764
    abi_ulong __msg_cbytes;
 
2765
    abi_ulong msg_qnum;
 
2766
    abi_ulong msg_qbytes;
 
2767
    abi_ulong msg_lspid;
 
2768
    abi_ulong msg_lrpid;
 
2769
    abi_ulong __unused4;
 
2770
    abi_ulong __unused5;
 
2771
};
 
2772
 
 
2773
static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
 
2774
                                               abi_ulong target_addr)
 
2775
{
 
2776
    struct target_msqid_ds *target_md;
 
2777
 
 
2778
    if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
 
2779
        return -TARGET_EFAULT;
 
2780
    if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
 
2781
        return -TARGET_EFAULT;
 
2782
    host_md->msg_stime = tswapal(target_md->msg_stime);
 
2783
    host_md->msg_rtime = tswapal(target_md->msg_rtime);
 
2784
    host_md->msg_ctime = tswapal(target_md->msg_ctime);
 
2785
    host_md->__msg_cbytes = tswapal(target_md->__msg_cbytes);
 
2786
    host_md->msg_qnum = tswapal(target_md->msg_qnum);
 
2787
    host_md->msg_qbytes = tswapal(target_md->msg_qbytes);
 
2788
    host_md->msg_lspid = tswapal(target_md->msg_lspid);
 
2789
    host_md->msg_lrpid = tswapal(target_md->msg_lrpid);
 
2790
    unlock_user_struct(target_md, target_addr, 0);
 
2791
    return 0;
 
2792
}
 
2793
 
 
2794
static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
 
2795
                                               struct msqid_ds *host_md)
 
2796
{
 
2797
    struct target_msqid_ds *target_md;
 
2798
 
 
2799
    if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
 
2800
        return -TARGET_EFAULT;
 
2801
    if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
 
2802
        return -TARGET_EFAULT;
 
2803
    target_md->msg_stime = tswapal(host_md->msg_stime);
 
2804
    target_md->msg_rtime = tswapal(host_md->msg_rtime);
 
2805
    target_md->msg_ctime = tswapal(host_md->msg_ctime);
 
2806
    target_md->__msg_cbytes = tswapal(host_md->__msg_cbytes);
 
2807
    target_md->msg_qnum = tswapal(host_md->msg_qnum);
 
2808
    target_md->msg_qbytes = tswapal(host_md->msg_qbytes);
 
2809
    target_md->msg_lspid = tswapal(host_md->msg_lspid);
 
2810
    target_md->msg_lrpid = tswapal(host_md->msg_lrpid);
 
2811
    unlock_user_struct(target_md, target_addr, 1);
 
2812
    return 0;
 
2813
}
 
2814
 
 
2815
struct target_msginfo {
 
2816
    int msgpool;
 
2817
    int msgmap;
 
2818
    int msgmax;
 
2819
    int msgmnb;
 
2820
    int msgmni;
 
2821
    int msgssz;
 
2822
    int msgtql;
 
2823
    unsigned short int msgseg;
 
2824
};
 
2825
 
 
2826
static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
 
2827
                                              struct msginfo *host_msginfo)
 
2828
{
 
2829
    struct target_msginfo *target_msginfo;
 
2830
    if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
 
2831
        return -TARGET_EFAULT;
 
2832
    __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
 
2833
    __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
 
2834
    __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
 
2835
    __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
 
2836
    __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
 
2837
    __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
 
2838
    __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
 
2839
    __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
 
2840
    unlock_user_struct(target_msginfo, target_addr, 1);
 
2841
    return 0;
 
2842
}
 
2843
 
 
2844
static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
 
2845
{
 
2846
    struct msqid_ds dsarg;
 
2847
    struct msginfo msginfo;
 
2848
    abi_long ret = -TARGET_EINVAL;
 
2849
 
 
2850
    cmd &= 0xff;
 
2851
 
 
2852
    switch (cmd) {
 
2853
    case IPC_STAT:
 
2854
    case IPC_SET:
 
2855
    case MSG_STAT:
 
2856
        if (target_to_host_msqid_ds(&dsarg,ptr))
 
2857
            return -TARGET_EFAULT;
 
2858
        ret = get_errno(msgctl(msgid, cmd, &dsarg));
 
2859
        if (host_to_target_msqid_ds(ptr,&dsarg))
 
2860
            return -TARGET_EFAULT;
 
2861
        break;
 
2862
    case IPC_RMID:
 
2863
        ret = get_errno(msgctl(msgid, cmd, NULL));
 
2864
        break;
 
2865
    case IPC_INFO:
 
2866
    case MSG_INFO:
 
2867
        ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
 
2868
        if (host_to_target_msginfo(ptr, &msginfo))
 
2869
            return -TARGET_EFAULT;
 
2870
        break;
 
2871
    }
 
2872
 
 
2873
    return ret;
 
2874
}
 
2875
 
 
2876
struct target_msgbuf {
 
2877
    abi_long mtype;
 
2878
    char        mtext[1];
 
2879
};
 
2880
 
 
2881
static inline abi_long do_msgsnd(int msqid, abi_long msgp,
 
2882
                                 unsigned int msgsz, int msgflg)
 
2883
{
 
2884
    struct target_msgbuf *target_mb;
 
2885
    struct msgbuf *host_mb;
 
2886
    abi_long ret = 0;
 
2887
 
 
2888
    if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
 
2889
        return -TARGET_EFAULT;
 
2890
    host_mb = malloc(msgsz+sizeof(long));
 
2891
    host_mb->mtype = (abi_long) tswapal(target_mb->mtype);
 
2892
    memcpy(host_mb->mtext, target_mb->mtext, msgsz);
 
2893
    ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
 
2894
    free(host_mb);
 
2895
    unlock_user_struct(target_mb, msgp, 0);
 
2896
 
 
2897
    return ret;
 
2898
}
 
2899
 
 
2900
static inline abi_long do_msgrcv(int msqid, abi_long msgp,
 
2901
                                 unsigned int msgsz, abi_long msgtyp,
 
2902
                                 int msgflg)
 
2903
{
 
2904
    struct target_msgbuf *target_mb;
 
2905
    char *target_mtext;
 
2906
    struct msgbuf *host_mb;
 
2907
    abi_long ret = 0;
 
2908
 
 
2909
    if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
 
2910
        return -TARGET_EFAULT;
 
2911
 
 
2912
    host_mb = g_malloc(msgsz+sizeof(long));
 
2913
    ret = get_errno(msgrcv(msqid, host_mb, msgsz, msgtyp, msgflg));
 
2914
 
 
2915
    if (ret > 0) {
 
2916
        abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
 
2917
        target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
 
2918
        if (!target_mtext) {
 
2919
            ret = -TARGET_EFAULT;
 
2920
            goto end;
 
2921
        }
 
2922
        memcpy(target_mb->mtext, host_mb->mtext, ret);
 
2923
        unlock_user(target_mtext, target_mtext_addr, ret);
 
2924
    }
 
2925
 
 
2926
    target_mb->mtype = tswapal(host_mb->mtype);
 
2927
 
 
2928
end:
 
2929
    if (target_mb)
 
2930
        unlock_user_struct(target_mb, msgp, 1);
 
2931
    g_free(host_mb);
 
2932
    return ret;
 
2933
}
 
2934
 
 
2935
struct target_shmid_ds
 
2936
{
 
2937
    struct target_ipc_perm shm_perm;
 
2938
    abi_ulong shm_segsz;
 
2939
    abi_ulong shm_atime;
 
2940
#if TARGET_ABI_BITS == 32
 
2941
    abi_ulong __unused1;
 
2942
#endif
 
2943
    abi_ulong shm_dtime;
 
2944
#if TARGET_ABI_BITS == 32
 
2945
    abi_ulong __unused2;
 
2946
#endif
 
2947
    abi_ulong shm_ctime;
 
2948
#if TARGET_ABI_BITS == 32
 
2949
    abi_ulong __unused3;
 
2950
#endif
 
2951
    int shm_cpid;
 
2952
    int shm_lpid;
 
2953
    abi_ulong shm_nattch;
 
2954
    unsigned long int __unused4;
 
2955
    unsigned long int __unused5;
 
2956
};
 
2957
 
 
2958
static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
 
2959
                                               abi_ulong target_addr)
 
2960
{
 
2961
    struct target_shmid_ds *target_sd;
 
2962
 
 
2963
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
 
2964
        return -TARGET_EFAULT;
 
2965
    if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr))
 
2966
        return -TARGET_EFAULT;
 
2967
    __get_user(host_sd->shm_segsz, &target_sd->shm_segsz);
 
2968
    __get_user(host_sd->shm_atime, &target_sd->shm_atime);
 
2969
    __get_user(host_sd->shm_dtime, &target_sd->shm_dtime);
 
2970
    __get_user(host_sd->shm_ctime, &target_sd->shm_ctime);
 
2971
    __get_user(host_sd->shm_cpid, &target_sd->shm_cpid);
 
2972
    __get_user(host_sd->shm_lpid, &target_sd->shm_lpid);
 
2973
    __get_user(host_sd->shm_nattch, &target_sd->shm_nattch);
 
2974
    unlock_user_struct(target_sd, target_addr, 0);
 
2975
    return 0;
 
2976
}
 
2977
 
 
2978
static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
 
2979
                                               struct shmid_ds *host_sd)
 
2980
{
 
2981
    struct target_shmid_ds *target_sd;
 
2982
 
 
2983
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
 
2984
        return -TARGET_EFAULT;
 
2985
    if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm)))
 
2986
        return -TARGET_EFAULT;
 
2987
    __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
 
2988
    __put_user(host_sd->shm_atime, &target_sd->shm_atime);
 
2989
    __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
 
2990
    __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
 
2991
    __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
 
2992
    __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
 
2993
    __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
 
2994
    unlock_user_struct(target_sd, target_addr, 1);
 
2995
    return 0;
 
2996
}
 
2997
 
 
2998
struct  target_shminfo {
 
2999
    abi_ulong shmmax;
 
3000
    abi_ulong shmmin;
 
3001
    abi_ulong shmmni;
 
3002
    abi_ulong shmseg;
 
3003
    abi_ulong shmall;
 
3004
};
 
3005
 
 
3006
static inline abi_long host_to_target_shminfo(abi_ulong target_addr,
 
3007
                                              struct shminfo *host_shminfo)
 
3008
{
 
3009
    struct target_shminfo *target_shminfo;
 
3010
    if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0))
 
3011
        return -TARGET_EFAULT;
 
3012
    __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
 
3013
    __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
 
3014
    __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
 
3015
    __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
 
3016
    __put_user(host_shminfo->shmall, &target_shminfo->shmall);
 
3017
    unlock_user_struct(target_shminfo, target_addr, 1);
 
3018
    return 0;
 
3019
}
 
3020
 
 
3021
struct target_shm_info {
 
3022
    int used_ids;
 
3023
    abi_ulong shm_tot;
 
3024
    abi_ulong shm_rss;
 
3025
    abi_ulong shm_swp;
 
3026
    abi_ulong swap_attempts;
 
3027
    abi_ulong swap_successes;
 
3028
};
 
3029
 
 
3030
static inline abi_long host_to_target_shm_info(abi_ulong target_addr,
 
3031
                                               struct shm_info *host_shm_info)
 
3032
{
 
3033
    struct target_shm_info *target_shm_info;
 
3034
    if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0))
 
3035
        return -TARGET_EFAULT;
 
3036
    __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
 
3037
    __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
 
3038
    __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
 
3039
    __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
 
3040
    __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts);
 
3041
    __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes);
 
3042
    unlock_user_struct(target_shm_info, target_addr, 1);
 
3043
    return 0;
 
3044
}
 
3045
 
 
3046
static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
 
3047
{
 
3048
    struct shmid_ds dsarg;
 
3049
    struct shminfo shminfo;
 
3050
    struct shm_info shm_info;
 
3051
    abi_long ret = -TARGET_EINVAL;
 
3052
 
 
3053
    cmd &= 0xff;
 
3054
 
 
3055
    switch(cmd) {
 
3056
    case IPC_STAT:
 
3057
    case IPC_SET:
 
3058
    case SHM_STAT:
 
3059
        if (target_to_host_shmid_ds(&dsarg, buf))
 
3060
            return -TARGET_EFAULT;
 
3061
        ret = get_errno(shmctl(shmid, cmd, &dsarg));
 
3062
        if (host_to_target_shmid_ds(buf, &dsarg))
 
3063
            return -TARGET_EFAULT;
 
3064
        break;
 
3065
    case IPC_INFO:
 
3066
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
 
3067
        if (host_to_target_shminfo(buf, &shminfo))
 
3068
            return -TARGET_EFAULT;
 
3069
        break;
 
3070
    case SHM_INFO:
 
3071
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
 
3072
        if (host_to_target_shm_info(buf, &shm_info))
 
3073
            return -TARGET_EFAULT;
 
3074
        break;
 
3075
    case IPC_RMID:
 
3076
    case SHM_LOCK:
 
3077
    case SHM_UNLOCK:
 
3078
        ret = get_errno(shmctl(shmid, cmd, NULL));
 
3079
        break;
 
3080
    }
 
3081
 
 
3082
    return ret;
 
3083
}
 
3084
 
 
3085
static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
 
3086
{
 
3087
    abi_long raddr;
 
3088
    void *host_raddr;
 
3089
    struct shmid_ds shm_info;
 
3090
    int i,ret;
 
3091
 
 
3092
    /* find out the length of the shared memory segment */
 
3093
    ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
 
3094
    if (is_error(ret)) {
 
3095
        /* can't get length, bail out */
 
3096
        return ret;
 
3097
    }
 
3098
 
 
3099
    mmap_lock();
 
3100
 
 
3101
    if (shmaddr)
 
3102
        host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
 
3103
    else {
 
3104
        abi_ulong mmap_start;
 
3105
 
 
3106
        mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
 
3107
 
 
3108
        if (mmap_start == -1) {
 
3109
            errno = ENOMEM;
 
3110
            host_raddr = (void *)-1;
 
3111
        } else
 
3112
            host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);
 
3113
    }
 
3114
 
 
3115
    if (host_raddr == (void *)-1) {
 
3116
        mmap_unlock();
 
3117
        return get_errno((long)host_raddr);
 
3118
    }
 
3119
    raddr=h2g((unsigned long)host_raddr);
 
3120
 
 
3121
    page_set_flags(raddr, raddr + shm_info.shm_segsz,
 
3122
                   PAGE_VALID | PAGE_READ |
 
3123
                   ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
 
3124
 
 
3125
    for (i = 0; i < N_SHM_REGIONS; i++) {
 
3126
        if (shm_regions[i].start == 0) {
 
3127
            shm_regions[i].start = raddr;
 
3128
            shm_regions[i].size = shm_info.shm_segsz;
 
3129
            break;
 
3130
        }
 
3131
    }
 
3132
 
 
3133
    mmap_unlock();
 
3134
    return raddr;
 
3135
 
 
3136
}
 
3137
 
 
3138
static inline abi_long do_shmdt(abi_ulong shmaddr)
 
3139
{
 
3140
    int i;
 
3141
 
 
3142
    for (i = 0; i < N_SHM_REGIONS; ++i) {
 
3143
        if (shm_regions[i].start == shmaddr) {
 
3144
            shm_regions[i].start = 0;
 
3145
            page_set_flags(shmaddr, shmaddr + shm_regions[i].size, 0);
 
3146
            break;
 
3147
        }
 
3148
    }
 
3149
 
 
3150
    return get_errno(shmdt(g2h(shmaddr)));
 
3151
}
 
3152
 
 
3153
#ifdef TARGET_NR_ipc
 
3154
/* ??? This only works with linear mappings.  */
 
3155
/* do_ipc() must return target values and target errnos. */
 
3156
static abi_long do_ipc(unsigned int call, int first,
 
3157
                       int second, int third,
 
3158
                       abi_long ptr, abi_long fifth)
 
3159
{
 
3160
    int version;
 
3161
    abi_long ret = 0;
 
3162
 
 
3163
    version = call >> 16;
 
3164
    call &= 0xffff;
 
3165
 
 
3166
    switch (call) {
 
3167
    case IPCOP_semop:
 
3168
        ret = do_semop(first, ptr, second);
 
3169
        break;
 
3170
 
 
3171
    case IPCOP_semget:
 
3172
        ret = get_errno(semget(first, second, third));
 
3173
        break;
 
3174
 
 
3175
    case IPCOP_semctl:
 
3176
        ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr);
 
3177
        break;
 
3178
 
 
3179
    case IPCOP_msgget:
 
3180
        ret = get_errno(msgget(first, second));
 
3181
        break;
 
3182
 
 
3183
    case IPCOP_msgsnd:
 
3184
        ret = do_msgsnd(first, ptr, second, third);
 
3185
        break;
 
3186
 
 
3187
    case IPCOP_msgctl:
 
3188
        ret = do_msgctl(first, second, ptr);
 
3189
        break;
 
3190
 
 
3191
    case IPCOP_msgrcv:
 
3192
        switch (version) {
 
3193
        case 0:
 
3194
            {
 
3195
                struct target_ipc_kludge {
 
3196
                    abi_long msgp;
 
3197
                    abi_long msgtyp;
 
3198
                } *tmp;
 
3199
 
 
3200
                if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
 
3201
                    ret = -TARGET_EFAULT;
 
3202
                    break;
 
3203
                }
 
3204
 
 
3205
                ret = do_msgrcv(first, tswapal(tmp->msgp), second, tswapal(tmp->msgtyp), third);
 
3206
 
 
3207
                unlock_user_struct(tmp, ptr, 0);
 
3208
                break;
 
3209
            }
 
3210
        default:
 
3211
            ret = do_msgrcv(first, ptr, second, fifth, third);
 
3212
        }
 
3213
        break;
 
3214
 
 
3215
    case IPCOP_shmat:
 
3216
        switch (version) {
 
3217
        default:
 
3218
        {
 
3219
            abi_ulong raddr;
 
3220
            raddr = do_shmat(first, ptr, second);
 
3221
            if (is_error(raddr))
 
3222
                return get_errno(raddr);
 
3223
            if (put_user_ual(raddr, third))
 
3224
                return -TARGET_EFAULT;
 
3225
            break;
 
3226
        }
 
3227
        case 1:
 
3228
            ret = -TARGET_EINVAL;
 
3229
            break;
 
3230
        }
 
3231
        break;
 
3232
    case IPCOP_shmdt:
 
3233
        ret = do_shmdt(ptr);
 
3234
        break;
 
3235
 
 
3236
    case IPCOP_shmget:
 
3237
        /* IPC_* flag values are the same on all linux platforms */
 
3238
        ret = get_errno(shmget(first, second, third));
 
3239
        break;
 
3240
 
 
3241
        /* IPC_* and SHM_* command values are the same on all linux platforms */
 
3242
    case IPCOP_shmctl:
 
3243
        ret = do_shmctl(first, second, third);
 
3244
        break;
 
3245
    default:
 
3246
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
 
3247
        ret = -TARGET_ENOSYS;
 
3248
        break;
 
3249
    }
 
3250
    return ret;
 
3251
}
 
3252
#endif
 
3253
 
 
3254
/* kernel structure types definitions */
 
3255
 
 
3256
#define STRUCT(name, ...) STRUCT_ ## name,
 
3257
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
 
3258
enum {
 
3259
#include "syscall_types.h"
 
3260
};
 
3261
#undef STRUCT
 
3262
#undef STRUCT_SPECIAL
 
3263
 
 
3264
#define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = {  __VA_ARGS__, TYPE_NULL };
 
3265
#define STRUCT_SPECIAL(name)
 
3266
#include "syscall_types.h"
 
3267
#undef STRUCT
 
3268
#undef STRUCT_SPECIAL
 
3269
 
 
3270
typedef struct IOCTLEntry IOCTLEntry;
 
3271
 
 
3272
typedef abi_long do_ioctl_fn(const IOCTLEntry *ie, uint8_t *buf_temp,
 
3273
                             int fd, abi_long cmd, abi_long arg);
 
3274
 
 
3275
struct IOCTLEntry {
 
3276
    unsigned int target_cmd;
 
3277
    unsigned int host_cmd;
 
3278
    const char *name;
 
3279
    int access;
 
3280
    do_ioctl_fn *do_ioctl;
 
3281
    const argtype arg_type[5];
 
3282
};
 
3283
 
 
3284
#define IOC_R 0x0001
 
3285
#define IOC_W 0x0002
 
3286
#define IOC_RW (IOC_R | IOC_W)
 
3287
 
 
3288
#define MAX_STRUCT_SIZE 4096
 
3289
 
 
3290
#ifdef CONFIG_FIEMAP
 
3291
/* So fiemap access checks don't overflow on 32 bit systems.
 
3292
 * This is very slightly smaller than the limit imposed by
 
3293
 * the underlying kernel.
 
3294
 */
 
3295
#define FIEMAP_MAX_EXTENTS ((UINT_MAX - sizeof(struct fiemap))  \
 
3296
                            / sizeof(struct fiemap_extent))
 
3297
 
 
3298
static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp,
 
3299
                                       int fd, abi_long cmd, abi_long arg)
 
3300
{
 
3301
    /* The parameter for this ioctl is a struct fiemap followed
 
3302
     * by an array of struct fiemap_extent whose size is set
 
3303
     * in fiemap->fm_extent_count. The array is filled in by the
 
3304
     * ioctl.
 
3305
     */
 
3306
    int target_size_in, target_size_out;
 
3307
    struct fiemap *fm;
 
3308
    const argtype *arg_type = ie->arg_type;
 
3309
    const argtype extent_arg_type[] = { MK_STRUCT(STRUCT_fiemap_extent) };
 
3310
    void *argptr, *p;
 
3311
    abi_long ret;
 
3312
    int i, extent_size = thunk_type_size(extent_arg_type, 0);
 
3313
    uint32_t outbufsz;
 
3314
    int free_fm = 0;
 
3315
 
 
3316
    assert(arg_type[0] == TYPE_PTR);
 
3317
    assert(ie->access == IOC_RW);
 
3318
    arg_type++;
 
3319
    target_size_in = thunk_type_size(arg_type, 0);
 
3320
    argptr = lock_user(VERIFY_READ, arg, target_size_in, 1);
 
3321
    if (!argptr) {
 
3322
        return -TARGET_EFAULT;
 
3323
    }
 
3324
    thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
 
3325
    unlock_user(argptr, arg, 0);
 
3326
    fm = (struct fiemap *)buf_temp;
 
3327
    if (fm->fm_extent_count > FIEMAP_MAX_EXTENTS) {
 
3328
        return -TARGET_EINVAL;
 
3329
    }
 
3330
 
 
3331
    outbufsz = sizeof (*fm) +
 
3332
        (sizeof(struct fiemap_extent) * fm->fm_extent_count);
 
3333
 
 
3334
    if (outbufsz > MAX_STRUCT_SIZE) {
 
3335
        /* We can't fit all the extents into the fixed size buffer.
 
3336
         * Allocate one that is large enough and use it instead.
 
3337
         */
 
3338
        fm = malloc(outbufsz);
 
3339
        if (!fm) {
 
3340
            return -TARGET_ENOMEM;
 
3341
        }
 
3342
        memcpy(fm, buf_temp, sizeof(struct fiemap));
 
3343
        free_fm = 1;
 
3344
    }
 
3345
    ret = get_errno(ioctl(fd, ie->host_cmd, fm));
 
3346
    if (!is_error(ret)) {
 
3347
        target_size_out = target_size_in;
 
3348
        /* An extent_count of 0 means we were only counting the extents
 
3349
         * so there are no structs to copy
 
3350
         */
 
3351
        if (fm->fm_extent_count != 0) {
 
3352
            target_size_out += fm->fm_mapped_extents * extent_size;
 
3353
        }
 
3354
        argptr = lock_user(VERIFY_WRITE, arg, target_size_out, 0);
 
3355
        if (!argptr) {
 
3356
            ret = -TARGET_EFAULT;
 
3357
        } else {
 
3358
            /* Convert the struct fiemap */
 
3359
            thunk_convert(argptr, fm, arg_type, THUNK_TARGET);
 
3360
            if (fm->fm_extent_count != 0) {
 
3361
                p = argptr + target_size_in;
 
3362
                /* ...and then all the struct fiemap_extents */
 
3363
                for (i = 0; i < fm->fm_mapped_extents; i++) {
 
3364
                    thunk_convert(p, &fm->fm_extents[i], extent_arg_type,
 
3365
                                  THUNK_TARGET);
 
3366
                    p += extent_size;
 
3367
                }
 
3368
            }
 
3369
            unlock_user(argptr, arg, target_size_out);
 
3370
        }
 
3371
    }
 
3372
    if (free_fm) {
 
3373
        free(fm);
 
3374
    }
 
3375
    return ret;
 
3376
}
 
3377
#endif
 
3378
 
 
3379
static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp,
 
3380
                                int fd, abi_long cmd, abi_long arg)
 
3381
{
 
3382
    const argtype *arg_type = ie->arg_type;
 
3383
    int target_size;
 
3384
    void *argptr;
 
3385
    int ret;
 
3386
    struct ifconf *host_ifconf;
 
3387
    uint32_t outbufsz;
 
3388
    const argtype ifreq_arg_type[] = { MK_STRUCT(STRUCT_sockaddr_ifreq) };
 
3389
    int target_ifreq_size;
 
3390
    int nb_ifreq;
 
3391
    int free_buf = 0;
 
3392
    int i;
 
3393
    int target_ifc_len;
 
3394
    abi_long target_ifc_buf;
 
3395
    int host_ifc_len;
 
3396
    char *host_ifc_buf;
 
3397
 
 
3398
    assert(arg_type[0] == TYPE_PTR);
 
3399
    assert(ie->access == IOC_RW);
 
3400
 
 
3401
    arg_type++;
 
3402
    target_size = thunk_type_size(arg_type, 0);
 
3403
 
 
3404
    argptr = lock_user(VERIFY_READ, arg, target_size, 1);
 
3405
    if (!argptr)
 
3406
        return -TARGET_EFAULT;
 
3407
    thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
 
3408
    unlock_user(argptr, arg, 0);
 
3409
 
 
3410
    host_ifconf = (struct ifconf *)(unsigned long)buf_temp;
 
3411
    target_ifc_len = host_ifconf->ifc_len;
 
3412
    target_ifc_buf = (abi_long)(unsigned long)host_ifconf->ifc_buf;
 
3413
 
 
3414
    target_ifreq_size = thunk_type_size(ifreq_arg_type, 0);
 
3415
    nb_ifreq = target_ifc_len / target_ifreq_size;
 
3416
    host_ifc_len = nb_ifreq * sizeof(struct ifreq);
 
3417
 
 
3418
    outbufsz = sizeof(*host_ifconf) + host_ifc_len;
 
3419
    if (outbufsz > MAX_STRUCT_SIZE) {
 
3420
        /* We can't fit all the extents into the fixed size buffer.
 
3421
         * Allocate one that is large enough and use it instead.
 
3422
         */
 
3423
        host_ifconf = malloc(outbufsz);
 
3424
        if (!host_ifconf) {
 
3425
            return -TARGET_ENOMEM;
 
3426
        }
 
3427
        memcpy(host_ifconf, buf_temp, sizeof(*host_ifconf));
 
3428
        free_buf = 1;
 
3429
    }
 
3430
    host_ifc_buf = (char*)host_ifconf + sizeof(*host_ifconf);
 
3431
 
 
3432
    host_ifconf->ifc_len = host_ifc_len;
 
3433
    host_ifconf->ifc_buf = host_ifc_buf;
 
3434
 
 
3435
    ret = get_errno(ioctl(fd, ie->host_cmd, host_ifconf));
 
3436
    if (!is_error(ret)) {
 
3437
        /* convert host ifc_len to target ifc_len */
 
3438
 
 
3439
        nb_ifreq = host_ifconf->ifc_len / sizeof(struct ifreq);
 
3440
        target_ifc_len = nb_ifreq * target_ifreq_size;
 
3441
        host_ifconf->ifc_len = target_ifc_len;
 
3442
 
 
3443
        /* restore target ifc_buf */
 
3444
 
 
3445
        host_ifconf->ifc_buf = (char *)(unsigned long)target_ifc_buf;
 
3446
 
 
3447
        /* copy struct ifconf to target user */
 
3448
 
 
3449
        argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
 
3450
        if (!argptr)
 
3451
            return -TARGET_EFAULT;
 
3452
        thunk_convert(argptr, host_ifconf, arg_type, THUNK_TARGET);
 
3453
        unlock_user(argptr, arg, target_size);
 
3454
 
 
3455
        /* copy ifreq[] to target user */
 
3456
 
 
3457
        argptr = lock_user(VERIFY_WRITE, target_ifc_buf, target_ifc_len, 0);
 
3458
        for (i = 0; i < nb_ifreq ; i++) {
 
3459
            thunk_convert(argptr + i * target_ifreq_size,
 
3460
                          host_ifc_buf + i * sizeof(struct ifreq),
 
3461
                          ifreq_arg_type, THUNK_TARGET);
 
3462
        }
 
3463
        unlock_user(argptr, target_ifc_buf, target_ifc_len);
 
3464
    }
 
3465
 
 
3466
    if (free_buf) {
 
3467
        free(host_ifconf);
 
3468
    }
 
3469
 
 
3470
    return ret;
 
3471
}
 
3472
 
 
3473
static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
 
3474
                            abi_long cmd, abi_long arg)
 
3475
{
 
3476
    void *argptr;
 
3477
    struct dm_ioctl *host_dm;
 
3478
    abi_long guest_data;
 
3479
    uint32_t guest_data_size;
 
3480
    int target_size;
 
3481
    const argtype *arg_type = ie->arg_type;
 
3482
    abi_long ret;
 
3483
    void *big_buf = NULL;
 
3484
    char *host_data;
 
3485
 
 
3486
    arg_type++;
 
3487
    target_size = thunk_type_size(arg_type, 0);
 
3488
    argptr = lock_user(VERIFY_READ, arg, target_size, 1);
 
3489
    if (!argptr) {
 
3490
        ret = -TARGET_EFAULT;
 
3491
        goto out;
 
3492
    }
 
3493
    thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
 
3494
    unlock_user(argptr, arg, 0);
 
3495
 
 
3496
    /* buf_temp is too small, so fetch things into a bigger buffer */
 
3497
    big_buf = g_malloc0(((struct dm_ioctl*)buf_temp)->data_size * 2);
 
3498
    memcpy(big_buf, buf_temp, target_size);
 
3499
    buf_temp = big_buf;
 
3500
    host_dm = big_buf;
 
3501
 
 
3502
    guest_data = arg + host_dm->data_start;
 
3503
    if ((guest_data - arg) < 0) {
 
3504
        ret = -EINVAL;
 
3505
        goto out;
 
3506
    }
 
3507
    guest_data_size = host_dm->data_size - host_dm->data_start;
 
3508
    host_data = (char*)host_dm + host_dm->data_start;
 
3509
 
 
3510
    argptr = lock_user(VERIFY_READ, guest_data, guest_data_size, 1);
 
3511
    switch (ie->host_cmd) {
 
3512
    case DM_REMOVE_ALL:
 
3513
    case DM_LIST_DEVICES:
 
3514
    case DM_DEV_CREATE:
 
3515
    case DM_DEV_REMOVE:
 
3516
    case DM_DEV_SUSPEND:
 
3517
    case DM_DEV_STATUS:
 
3518
    case DM_DEV_WAIT:
 
3519
    case DM_TABLE_STATUS:
 
3520
    case DM_TABLE_CLEAR:
 
3521
    case DM_TABLE_DEPS:
 
3522
    case DM_LIST_VERSIONS:
 
3523
        /* no input data */
 
3524
        break;
 
3525
    case DM_DEV_RENAME:
 
3526
    case DM_DEV_SET_GEOMETRY:
 
3527
        /* data contains only strings */
 
3528
        memcpy(host_data, argptr, guest_data_size);
 
3529
        break;
 
3530
    case DM_TARGET_MSG:
 
3531
        memcpy(host_data, argptr, guest_data_size);
 
3532
        *(uint64_t*)host_data = tswap64(*(uint64_t*)argptr);
 
3533
        break;
 
3534
    case DM_TABLE_LOAD:
 
3535
    {
 
3536
        void *gspec = argptr;
 
3537
        void *cur_data = host_data;
 
3538
        const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };
 
3539
        int spec_size = thunk_type_size(arg_type, 0);
 
3540
        int i;
 
3541
 
 
3542
        for (i = 0; i < host_dm->target_count; i++) {
 
3543
            struct dm_target_spec *spec = cur_data;
 
3544
            uint32_t next;
 
3545
            int slen;
 
3546
 
 
3547
            thunk_convert(spec, gspec, arg_type, THUNK_HOST);
 
3548
            slen = strlen((char*)gspec + spec_size) + 1;
 
3549
            next = spec->next;
 
3550
            spec->next = sizeof(*spec) + slen;
 
3551
            strcpy((char*)&spec[1], gspec + spec_size);
 
3552
            gspec += next;
 
3553
            cur_data += spec->next;
 
3554
        }
 
3555
        break;
 
3556
    }
 
3557
    default:
 
3558
        ret = -TARGET_EINVAL;
 
3559
        goto out;
 
3560
    }
 
3561
    unlock_user(argptr, guest_data, 0);
 
3562
 
 
3563
    ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
 
3564
    if (!is_error(ret)) {
 
3565
        guest_data = arg + host_dm->data_start;
 
3566
        guest_data_size = host_dm->data_size - host_dm->data_start;
 
3567
        argptr = lock_user(VERIFY_WRITE, guest_data, guest_data_size, 0);
 
3568
        switch (ie->host_cmd) {
 
3569
        case DM_REMOVE_ALL:
 
3570
        case DM_DEV_CREATE:
 
3571
        case DM_DEV_REMOVE:
 
3572
        case DM_DEV_RENAME:
 
3573
        case DM_DEV_SUSPEND:
 
3574
        case DM_DEV_STATUS:
 
3575
        case DM_TABLE_LOAD:
 
3576
        case DM_TABLE_CLEAR:
 
3577
        case DM_TARGET_MSG:
 
3578
        case DM_DEV_SET_GEOMETRY:
 
3579
            /* no return data */
 
3580
            break;
 
3581
        case DM_LIST_DEVICES:
 
3582
        {
 
3583
            struct dm_name_list *nl = (void*)host_dm + host_dm->data_start;
 
3584
            uint32_t remaining_data = guest_data_size;
 
3585
            void *cur_data = argptr;
 
3586
            const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_name_list) };
 
3587
            int nl_size = 12; /* can't use thunk_size due to alignment */
 
3588
 
 
3589
            while (1) {
 
3590
                uint32_t next = nl->next;
 
3591
                if (next) {
 
3592
                    nl->next = nl_size + (strlen(nl->name) + 1);
 
3593
                }
 
3594
                if (remaining_data < nl->next) {
 
3595
                    host_dm->flags |= DM_BUFFER_FULL_FLAG;
 
3596
                    break;
 
3597
                }
 
3598
                thunk_convert(cur_data, nl, arg_type, THUNK_TARGET);
 
3599
                strcpy(cur_data + nl_size, nl->name);
 
3600
                cur_data += nl->next;
 
3601
                remaining_data -= nl->next;
 
3602
                if (!next) {
 
3603
                    break;
 
3604
                }
 
3605
                nl = (void*)nl + next;
 
3606
            }
 
3607
            break;
 
3608
        }
 
3609
        case DM_DEV_WAIT:
 
3610
        case DM_TABLE_STATUS:
 
3611
        {
 
3612
            struct dm_target_spec *spec = (void*)host_dm + host_dm->data_start;
 
3613
            void *cur_data = argptr;
 
3614
            const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };
 
3615
            int spec_size = thunk_type_size(arg_type, 0);
 
3616
            int i;
 
3617
 
 
3618
            for (i = 0; i < host_dm->target_count; i++) {
 
3619
                uint32_t next = spec->next;
 
3620
                int slen = strlen((char*)&spec[1]) + 1;
 
3621
                spec->next = (cur_data - argptr) + spec_size + slen;
 
3622
                if (guest_data_size < spec->next) {
 
3623
                    host_dm->flags |= DM_BUFFER_FULL_FLAG;
 
3624
                    break;
 
3625
                }
 
3626
                thunk_convert(cur_data, spec, arg_type, THUNK_TARGET);
 
3627
                strcpy(cur_data + spec_size, (char*)&spec[1]);
 
3628
                cur_data = argptr + spec->next;
 
3629
                spec = (void*)host_dm + host_dm->data_start + next;
 
3630
            }
 
3631
            break;
 
3632
        }
 
3633
        case DM_TABLE_DEPS:
 
3634
        {
 
3635
            void *hdata = (void*)host_dm + host_dm->data_start;
 
3636
            int count = *(uint32_t*)hdata;
 
3637
            uint64_t *hdev = hdata + 8;
 
3638
            uint64_t *gdev = argptr + 8;
 
3639
            int i;
 
3640
 
 
3641
            *(uint32_t*)argptr = tswap32(count);
 
3642
            for (i = 0; i < count; i++) {
 
3643
                *gdev = tswap64(*hdev);
 
3644
                gdev++;
 
3645
                hdev++;
 
3646
            }
 
3647
            break;
 
3648
        }
 
3649
        case DM_LIST_VERSIONS:
 
3650
        {
 
3651
            struct dm_target_versions *vers = (void*)host_dm + host_dm->data_start;
 
3652
            uint32_t remaining_data = guest_data_size;
 
3653
            void *cur_data = argptr;
 
3654
            const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_versions) };
 
3655
            int vers_size = thunk_type_size(arg_type, 0);
 
3656
 
 
3657
            while (1) {
 
3658
                uint32_t next = vers->next;
 
3659
                if (next) {
 
3660
                    vers->next = vers_size + (strlen(vers->name) + 1);
 
3661
                }
 
3662
                if (remaining_data < vers->next) {
 
3663
                    host_dm->flags |= DM_BUFFER_FULL_FLAG;
 
3664
                    break;
 
3665
                }
 
3666
                thunk_convert(cur_data, vers, arg_type, THUNK_TARGET);
 
3667
                strcpy(cur_data + vers_size, vers->name);
 
3668
                cur_data += vers->next;
 
3669
                remaining_data -= vers->next;
 
3670
                if (!next) {
 
3671
                    break;
 
3672
                }
 
3673
                vers = (void*)vers + next;
 
3674
            }
 
3675
            break;
 
3676
        }
 
3677
        default:
 
3678
            ret = -TARGET_EINVAL;
 
3679
            goto out;
 
3680
        }
 
3681
        unlock_user(argptr, guest_data, guest_data_size);
 
3682
 
 
3683
        argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
 
3684
        if (!argptr) {
 
3685
            ret = -TARGET_EFAULT;
 
3686
            goto out;
 
3687
        }
 
3688
        thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
 
3689
        unlock_user(argptr, arg, target_size);
 
3690
    }
 
3691
out:
 
3692
    g_free(big_buf);
 
3693
    return ret;
 
3694
}
 
3695
 
 
3696
static abi_long do_ioctl_rt(const IOCTLEntry *ie, uint8_t *buf_temp,
 
3697
                                int fd, abi_long cmd, abi_long arg)
 
3698
{
 
3699
    const argtype *arg_type = ie->arg_type;
 
3700
    const StructEntry *se;
 
3701
    const argtype *field_types;
 
3702
    const int *dst_offsets, *src_offsets;
 
3703
    int target_size;
 
3704
    void *argptr;
 
3705
    abi_ulong *target_rt_dev_ptr;
 
3706
    unsigned long *host_rt_dev_ptr;
 
3707
    abi_long ret;
 
3708
    int i;
 
3709
 
 
3710
    assert(ie->access == IOC_W);
 
3711
    assert(*arg_type == TYPE_PTR);
 
3712
    arg_type++;
 
3713
    assert(*arg_type == TYPE_STRUCT);
 
3714
    target_size = thunk_type_size(arg_type, 0);
 
3715
    argptr = lock_user(VERIFY_READ, arg, target_size, 1);
 
3716
    if (!argptr) {
 
3717
        return -TARGET_EFAULT;
 
3718
    }
 
3719
    arg_type++;
 
3720
    assert(*arg_type == (int)STRUCT_rtentry);
 
3721
    se = struct_entries + *arg_type++;
 
3722
    assert(se->convert[0] == NULL);
 
3723
    /* convert struct here to be able to catch rt_dev string */
 
3724
    field_types = se->field_types;
 
3725
    dst_offsets = se->field_offsets[THUNK_HOST];
 
3726
    src_offsets = se->field_offsets[THUNK_TARGET];
 
3727
    for (i = 0; i < se->nb_fields; i++) {
 
3728
        if (dst_offsets[i] == offsetof(struct rtentry, rt_dev)) {
 
3729
            assert(*field_types == TYPE_PTRVOID);
 
3730
            target_rt_dev_ptr = (abi_ulong *)(argptr + src_offsets[i]);
 
3731
            host_rt_dev_ptr = (unsigned long *)(buf_temp + dst_offsets[i]);
 
3732
            if (*target_rt_dev_ptr != 0) {
 
3733
                *host_rt_dev_ptr = (unsigned long)lock_user_string(
 
3734
                                                  tswapal(*target_rt_dev_ptr));
 
3735
                if (!*host_rt_dev_ptr) {
 
3736
                    unlock_user(argptr, arg, 0);
 
3737
                    return -TARGET_EFAULT;
 
3738
                }
 
3739
            } else {
 
3740
                *host_rt_dev_ptr = 0;
 
3741
            }
 
3742
            field_types++;
 
3743
            continue;
 
3744
        }
 
3745
        field_types = thunk_convert(buf_temp + dst_offsets[i],
 
3746
                                    argptr + src_offsets[i],
 
3747
                                    field_types, THUNK_HOST);
 
3748
    }
 
3749
    unlock_user(argptr, arg, 0);
 
3750
 
 
3751
    ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
 
3752
    if (*host_rt_dev_ptr != 0) {
 
3753
        unlock_user((void *)*host_rt_dev_ptr,
 
3754
                    *target_rt_dev_ptr, 0);
 
3755
    }
 
3756
    return ret;
 
3757
}
 
3758
 
 
3759
static IOCTLEntry ioctl_entries[] = {
 
3760
#define IOCTL(cmd, access, ...) \
 
3761
    { TARGET_ ## cmd, cmd, #cmd, access, 0, {  __VA_ARGS__ } },
 
3762
#define IOCTL_SPECIAL(cmd, access, dofn, ...)                      \
 
3763
    { TARGET_ ## cmd, cmd, #cmd, access, dofn, {  __VA_ARGS__ } },
 
3764
#include "ioctls.h"
 
3765
    { 0, 0, },
 
3766
};
 
3767
 
 
3768
/* ??? Implement proper locking for ioctls.  */
 
3769
/* do_ioctl() Must return target values and target errnos. */
 
3770
static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
 
3771
{
 
3772
    const IOCTLEntry *ie;
 
3773
    const argtype *arg_type;
 
3774
    abi_long ret;
 
3775
    uint8_t buf_temp[MAX_STRUCT_SIZE];
 
3776
    int target_size;
 
3777
    void *argptr;
 
3778
 
 
3779
    ie = ioctl_entries;
 
3780
    for(;;) {
 
3781
        if (ie->target_cmd == 0) {
 
3782
            gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
 
3783
            return -TARGET_ENOSYS;
 
3784
        }
 
3785
        if (ie->target_cmd == cmd)
 
3786
            break;
 
3787
        ie++;
 
3788
    }
 
3789
    arg_type = ie->arg_type;
 
3790
#if defined(DEBUG)
 
3791
    gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
 
3792
#endif
 
3793
    if (ie->do_ioctl) {
 
3794
        return ie->do_ioctl(ie, buf_temp, fd, cmd, arg);
 
3795
    }
 
3796
 
 
3797
    switch(arg_type[0]) {
 
3798
    case TYPE_NULL:
 
3799
        /* no argument */
 
3800
        ret = get_errno(ioctl(fd, ie->host_cmd));
 
3801
        break;
 
3802
    case TYPE_PTRVOID:
 
3803
    case TYPE_INT:
 
3804
        /* int argment */
 
3805
        ret = get_errno(ioctl(fd, ie->host_cmd, arg));
 
3806
        break;
 
3807
    case TYPE_PTR:
 
3808
        arg_type++;
 
3809
        target_size = thunk_type_size(arg_type, 0);
 
3810
        switch(ie->access) {
 
3811
        case IOC_R:
 
3812
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
 
3813
            if (!is_error(ret)) {
 
3814
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
 
3815
                if (!argptr)
 
3816
                    return -TARGET_EFAULT;
 
3817
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
 
3818
                unlock_user(argptr, arg, target_size);
 
3819
            }
 
3820
            break;
 
3821
        case IOC_W:
 
3822
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
 
3823
            if (!argptr)
 
3824
                return -TARGET_EFAULT;
 
3825
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
 
3826
            unlock_user(argptr, arg, 0);
 
3827
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
 
3828
            break;
 
3829
        default:
 
3830
        case IOC_RW:
 
3831
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
 
3832
            if (!argptr)
 
3833
                return -TARGET_EFAULT;
 
3834
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
 
3835
            unlock_user(argptr, arg, 0);
 
3836
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
 
3837
            if (!is_error(ret)) {
 
3838
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
 
3839
                if (!argptr)
 
3840
                    return -TARGET_EFAULT;
 
3841
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
 
3842
                unlock_user(argptr, arg, target_size);
 
3843
            }
 
3844
            break;
 
3845
        }
 
3846
        break;
 
3847
    default:
 
3848
        gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
 
3849
                 (long)cmd, arg_type[0]);
 
3850
        ret = -TARGET_ENOSYS;
 
3851
        break;
 
3852
    }
 
3853
    return ret;
 
3854
}
 
3855
 
 
3856
static const bitmask_transtbl iflag_tbl[] = {
 
3857
        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
 
3858
        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
 
3859
        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
 
3860
        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
 
3861
        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
 
3862
        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
 
3863
        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
 
3864
        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
 
3865
        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
 
3866
        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
 
3867
        { TARGET_IXON, TARGET_IXON, IXON, IXON },
 
3868
        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
 
3869
        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
 
3870
        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
 
3871
        { 0, 0, 0, 0 }
 
3872
};
 
3873
 
 
3874
static const bitmask_transtbl oflag_tbl[] = {
 
3875
        { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
 
3876
        { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
 
3877
        { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
 
3878
        { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
 
3879
        { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
 
3880
        { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
 
3881
        { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
 
3882
        { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
 
3883
        { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
 
3884
        { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
 
3885
        { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
 
3886
        { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
 
3887
        { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
 
3888
        { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
 
3889
        { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
 
3890
        { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
 
3891
        { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
 
3892
        { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
 
3893
        { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
 
3894
        { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
 
3895
        { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
 
3896
        { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
 
3897
        { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
 
3898
        { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
 
3899
        { 0, 0, 0, 0 }
 
3900
};
 
3901
 
 
3902
static const bitmask_transtbl cflag_tbl[] = {
 
3903
        { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
 
3904
        { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
 
3905
        { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
 
3906
        { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
 
3907
        { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
 
3908
        { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
 
3909
        { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
 
3910
        { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
 
3911
        { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
 
3912
        { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
 
3913
        { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
 
3914
        { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
 
3915
        { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
 
3916
        { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
 
3917
        { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
 
3918
        { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
 
3919
        { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
 
3920
        { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
 
3921
        { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
 
3922
        { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
 
3923
        { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
 
3924
        { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
 
3925
        { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
 
3926
        { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
 
3927
        { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
 
3928
        { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
 
3929
        { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
 
3930
        { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
 
3931
        { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
 
3932
        { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
 
3933
        { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
 
3934
        { 0, 0, 0, 0 }
 
3935
};
 
3936
 
 
3937
static const bitmask_transtbl lflag_tbl[] = {
 
3938
        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
 
3939
        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
 
3940
        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
 
3941
        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
 
3942
        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
 
3943
        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
 
3944
        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
 
3945
        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
 
3946
        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
 
3947
        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
 
3948
        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
 
3949
        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
 
3950
        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
 
3951
        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
 
3952
        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
 
3953
        { 0, 0, 0, 0 }
 
3954
};
 
3955
 
 
3956
static void target_to_host_termios (void *dst, const void *src)
 
3957
{
 
3958
    struct host_termios *host = dst;
 
3959
    const struct target_termios *target = src;
 
3960
 
 
3961
    host->c_iflag =
 
3962
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
 
3963
    host->c_oflag =
 
3964
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
 
3965
    host->c_cflag =
 
3966
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
 
3967
    host->c_lflag =
 
3968
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
 
3969
    host->c_line = target->c_line;
 
3970
 
 
3971
    memset(host->c_cc, 0, sizeof(host->c_cc));
 
3972
    host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
 
3973
    host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
 
3974
    host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
 
3975
    host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
 
3976
    host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
 
3977
    host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
 
3978
    host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
 
3979
    host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
 
3980
    host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
 
3981
    host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
 
3982
    host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
 
3983
    host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
 
3984
    host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
 
3985
    host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
 
3986
    host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
 
3987
    host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
 
3988
    host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
 
3989
}
 
3990
 
 
3991
static void host_to_target_termios (void *dst, const void *src)
 
3992
{
 
3993
    struct target_termios *target = dst;
 
3994
    const struct host_termios *host = src;
 
3995
 
 
3996
    target->c_iflag =
 
3997
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
 
3998
    target->c_oflag =
 
3999
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
 
4000
    target->c_cflag =
 
4001
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
 
4002
    target->c_lflag =
 
4003
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
 
4004
    target->c_line = host->c_line;
 
4005
 
 
4006
    memset(target->c_cc, 0, sizeof(target->c_cc));
 
4007
    target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
 
4008
    target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
 
4009
    target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
 
4010
    target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
 
4011
    target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
 
4012
    target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
 
4013
    target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
 
4014
    target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
 
4015
    target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
 
4016
    target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
 
4017
    target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
 
4018
    target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
 
4019
    target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
 
4020
    target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
 
4021
    target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
 
4022
    target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
 
4023
    target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
 
4024
}
 
4025
 
 
4026
static const StructEntry struct_termios_def = {
 
4027
    .convert = { host_to_target_termios, target_to_host_termios },
 
4028
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
 
4029
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
 
4030
};
 
4031
 
 
4032
static bitmask_transtbl mmap_flags_tbl[] = {
 
4033
        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
 
4034
        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
 
4035
        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
 
4036
        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
 
4037
        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
 
4038
        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
 
4039
        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
 
4040
        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
 
4041
        { 0, 0, 0, 0 }
 
4042
};
 
4043
 
 
4044
#if defined(TARGET_I386)
 
4045
 
 
4046
/* NOTE: there is really one LDT for all the threads */
 
4047
static uint8_t *ldt_table;
 
4048
 
 
4049
static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
 
4050
{
 
4051
    int size;
 
4052
    void *p;
 
4053
 
 
4054
    if (!ldt_table)
 
4055
        return 0;
 
4056
    size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
 
4057
    if (size > bytecount)
 
4058
        size = bytecount;
 
4059
    p = lock_user(VERIFY_WRITE, ptr, size, 0);
 
4060
    if (!p)
 
4061
        return -TARGET_EFAULT;
 
4062
    /* ??? Should this by byteswapped?  */
 
4063
    memcpy(p, ldt_table, size);
 
4064
    unlock_user(p, ptr, size);
 
4065
    return size;
 
4066
}
 
4067
 
 
4068
/* XXX: add locking support */
 
4069
static abi_long write_ldt(CPUX86State *env,
 
4070
                          abi_ulong ptr, unsigned long bytecount, int oldmode)
 
4071
{
 
4072
    struct target_modify_ldt_ldt_s ldt_info;
 
4073
    struct target_modify_ldt_ldt_s *target_ldt_info;
 
4074
    int seg_32bit, contents, read_exec_only, limit_in_pages;
 
4075
    int seg_not_present, useable, lm;
 
4076
    uint32_t *lp, entry_1, entry_2;
 
4077
 
 
4078
    if (bytecount != sizeof(ldt_info))
 
4079
        return -TARGET_EINVAL;
 
4080
    if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
 
4081
        return -TARGET_EFAULT;
 
4082
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
 
4083
    ldt_info.base_addr = tswapal(target_ldt_info->base_addr);
 
4084
    ldt_info.limit = tswap32(target_ldt_info->limit);
 
4085
    ldt_info.flags = tswap32(target_ldt_info->flags);
 
4086
    unlock_user_struct(target_ldt_info, ptr, 0);
 
4087
 
 
4088
    if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
 
4089
        return -TARGET_EINVAL;
 
4090
    seg_32bit = ldt_info.flags & 1;
 
4091
    contents = (ldt_info.flags >> 1) & 3;
 
4092
    read_exec_only = (ldt_info.flags >> 3) & 1;
 
4093
    limit_in_pages = (ldt_info.flags >> 4) & 1;
 
4094
    seg_not_present = (ldt_info.flags >> 5) & 1;
 
4095
    useable = (ldt_info.flags >> 6) & 1;
 
4096
#ifdef TARGET_ABI32
 
4097
    lm = 0;
 
4098
#else
 
4099
    lm = (ldt_info.flags >> 7) & 1;
 
4100
#endif
 
4101
    if (contents == 3) {
 
4102
        if (oldmode)
 
4103
            return -TARGET_EINVAL;
 
4104
        if (seg_not_present == 0)
 
4105
            return -TARGET_EINVAL;
 
4106
    }
 
4107
    /* allocate the LDT */
 
4108
    if (!ldt_table) {
 
4109
        env->ldt.base = target_mmap(0,
 
4110
                                    TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
 
4111
                                    PROT_READ|PROT_WRITE,
 
4112
                                    MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
 
4113
        if (env->ldt.base == -1)
 
4114
            return -TARGET_ENOMEM;
 
4115
        memset(g2h(env->ldt.base), 0,
 
4116
               TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
 
4117
        env->ldt.limit = 0xffff;
 
4118
        ldt_table = g2h(env->ldt.base);
 
4119
    }
 
4120
 
 
4121
    /* NOTE: same code as Linux kernel */
 
4122
    /* Allow LDTs to be cleared by the user. */
 
4123
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
 
4124
        if (oldmode ||
 
4125
            (contents == 0              &&
 
4126
             read_exec_only == 1        &&
 
4127
             seg_32bit == 0             &&
 
4128
             limit_in_pages == 0        &&
 
4129
             seg_not_present == 1       &&
 
4130
             useable == 0 )) {
 
4131
            entry_1 = 0;
 
4132
            entry_2 = 0;
 
4133
            goto install;
 
4134
        }
 
4135
    }
 
4136
 
 
4137
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
 
4138
        (ldt_info.limit & 0x0ffff);
 
4139
    entry_2 = (ldt_info.base_addr & 0xff000000) |
 
4140
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
 
4141
        (ldt_info.limit & 0xf0000) |
 
4142
        ((read_exec_only ^ 1) << 9) |
 
4143
        (contents << 10) |
 
4144
        ((seg_not_present ^ 1) << 15) |
 
4145
        (seg_32bit << 22) |
 
4146
        (limit_in_pages << 23) |
 
4147
        (lm << 21) |
 
4148
        0x7000;
 
4149
    if (!oldmode)
 
4150
        entry_2 |= (useable << 20);
 
4151
 
 
4152
    /* Install the new entry ...  */
 
4153
install:
 
4154
    lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
 
4155
    lp[0] = tswap32(entry_1);
 
4156
    lp[1] = tswap32(entry_2);
 
4157
    return 0;
 
4158
}
 
4159
 
 
4160
/* specific and weird i386 syscalls */
 
4161
static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
 
4162
                              unsigned long bytecount)
 
4163
{
 
4164
    abi_long ret;
 
4165
 
 
4166
    switch (func) {
 
4167
    case 0:
 
4168
        ret = read_ldt(ptr, bytecount);
 
4169
        break;
 
4170
    case 1:
 
4171
        ret = write_ldt(env, ptr, bytecount, 1);
 
4172
        break;
 
4173
    case 0x11:
 
4174
        ret = write_ldt(env, ptr, bytecount, 0);
 
4175
        break;
 
4176
    default:
 
4177
        ret = -TARGET_ENOSYS;
 
4178
        break;
 
4179
    }
 
4180
    return ret;
 
4181
}
 
4182
 
 
4183
#if defined(TARGET_I386) && defined(TARGET_ABI32)
 
4184
abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
 
4185
{
 
4186
    uint64_t *gdt_table = g2h(env->gdt.base);
 
4187
    struct target_modify_ldt_ldt_s ldt_info;
 
4188
    struct target_modify_ldt_ldt_s *target_ldt_info;
 
4189
    int seg_32bit, contents, read_exec_only, limit_in_pages;
 
4190
    int seg_not_present, useable, lm;
 
4191
    uint32_t *lp, entry_1, entry_2;
 
4192
    int i;
 
4193
 
 
4194
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
 
4195
    if (!target_ldt_info)
 
4196
        return -TARGET_EFAULT;
 
4197
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
 
4198
    ldt_info.base_addr = tswapal(target_ldt_info->base_addr);
 
4199
    ldt_info.limit = tswap32(target_ldt_info->limit);
 
4200
    ldt_info.flags = tswap32(target_ldt_info->flags);
 
4201
    if (ldt_info.entry_number == -1) {
 
4202
        for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
 
4203
            if (gdt_table[i] == 0) {
 
4204
                ldt_info.entry_number = i;
 
4205
                target_ldt_info->entry_number = tswap32(i);
 
4206
                break;
 
4207
            }
 
4208
        }
 
4209
    }
 
4210
    unlock_user_struct(target_ldt_info, ptr, 1);
 
4211
 
 
4212
    if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || 
 
4213
        ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
 
4214
           return -TARGET_EINVAL;
 
4215
    seg_32bit = ldt_info.flags & 1;
 
4216
    contents = (ldt_info.flags >> 1) & 3;
 
4217
    read_exec_only = (ldt_info.flags >> 3) & 1;
 
4218
    limit_in_pages = (ldt_info.flags >> 4) & 1;
 
4219
    seg_not_present = (ldt_info.flags >> 5) & 1;
 
4220
    useable = (ldt_info.flags >> 6) & 1;
 
4221
#ifdef TARGET_ABI32
 
4222
    lm = 0;
 
4223
#else
 
4224
    lm = (ldt_info.flags >> 7) & 1;
 
4225
#endif
 
4226
 
 
4227
    if (contents == 3) {
 
4228
        if (seg_not_present == 0)
 
4229
            return -TARGET_EINVAL;
 
4230
    }
 
4231
 
 
4232
    /* NOTE: same code as Linux kernel */
 
4233
    /* Allow LDTs to be cleared by the user. */
 
4234
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
 
4235
        if ((contents == 0             &&
 
4236
             read_exec_only == 1       &&
 
4237
             seg_32bit == 0            &&
 
4238
             limit_in_pages == 0       &&
 
4239
             seg_not_present == 1      &&
 
4240
             useable == 0 )) {
 
4241
            entry_1 = 0;
 
4242
            entry_2 = 0;
 
4243
            goto install;
 
4244
        }
 
4245
    }
 
4246
 
 
4247
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
 
4248
        (ldt_info.limit & 0x0ffff);
 
4249
    entry_2 = (ldt_info.base_addr & 0xff000000) |
 
4250
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
 
4251
        (ldt_info.limit & 0xf0000) |
 
4252
        ((read_exec_only ^ 1) << 9) |
 
4253
        (contents << 10) |
 
4254
        ((seg_not_present ^ 1) << 15) |
 
4255
        (seg_32bit << 22) |
 
4256
        (limit_in_pages << 23) |
 
4257
        (useable << 20) |
 
4258
        (lm << 21) |
 
4259
        0x7000;
 
4260
 
 
4261
    /* Install the new entry ...  */
 
4262
install:
 
4263
    lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
 
4264
    lp[0] = tswap32(entry_1);
 
4265
    lp[1] = tswap32(entry_2);
 
4266
    return 0;
 
4267
}
 
4268
 
 
4269
static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
 
4270
{
 
4271
    struct target_modify_ldt_ldt_s *target_ldt_info;
 
4272
    uint64_t *gdt_table = g2h(env->gdt.base);
 
4273
    uint32_t base_addr, limit, flags;
 
4274
    int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
 
4275
    int seg_not_present, useable, lm;
 
4276
    uint32_t *lp, entry_1, entry_2;
 
4277
 
 
4278
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
 
4279
    if (!target_ldt_info)
 
4280
        return -TARGET_EFAULT;
 
4281
    idx = tswap32(target_ldt_info->entry_number);
 
4282
    if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
 
4283
        idx > TARGET_GDT_ENTRY_TLS_MAX) {
 
4284
        unlock_user_struct(target_ldt_info, ptr, 1);
 
4285
        return -TARGET_EINVAL;
 
4286
    }
 
4287
    lp = (uint32_t *)(gdt_table + idx);
 
4288
    entry_1 = tswap32(lp[0]);
 
4289
    entry_2 = tswap32(lp[1]);
 
4290
    
 
4291
    read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
 
4292
    contents = (entry_2 >> 10) & 3;
 
4293
    seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
 
4294
    seg_32bit = (entry_2 >> 22) & 1;
 
4295
    limit_in_pages = (entry_2 >> 23) & 1;
 
4296
    useable = (entry_2 >> 20) & 1;
 
4297
#ifdef TARGET_ABI32
 
4298
    lm = 0;
 
4299
#else
 
4300
    lm = (entry_2 >> 21) & 1;
 
4301
#endif
 
4302
    flags = (seg_32bit << 0) | (contents << 1) |
 
4303
        (read_exec_only << 3) | (limit_in_pages << 4) |
 
4304
        (seg_not_present << 5) | (useable << 6) | (lm << 7);
 
4305
    limit = (entry_1 & 0xffff) | (entry_2  & 0xf0000);
 
4306
    base_addr = (entry_1 >> 16) | 
 
4307
        (entry_2 & 0xff000000) | 
 
4308
        ((entry_2 & 0xff) << 16);
 
4309
    target_ldt_info->base_addr = tswapal(base_addr);
 
4310
    target_ldt_info->limit = tswap32(limit);
 
4311
    target_ldt_info->flags = tswap32(flags);
 
4312
    unlock_user_struct(target_ldt_info, ptr, 1);
 
4313
    return 0;
 
4314
}
 
4315
#endif /* TARGET_I386 && TARGET_ABI32 */
 
4316
 
 
4317
#ifndef TARGET_ABI32
 
4318
abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
 
4319
{
 
4320
    abi_long ret = 0;
 
4321
    abi_ulong val;
 
4322
    int idx;
 
4323
 
 
4324
    switch(code) {
 
4325
    case TARGET_ARCH_SET_GS:
 
4326
    case TARGET_ARCH_SET_FS:
 
4327
        if (code == TARGET_ARCH_SET_GS)
 
4328
            idx = R_GS;
 
4329
        else
 
4330
            idx = R_FS;
 
4331
        cpu_x86_load_seg(env, idx, 0);
 
4332
        env->segs[idx].base = addr;
 
4333
        break;
 
4334
    case TARGET_ARCH_GET_GS:
 
4335
    case TARGET_ARCH_GET_FS:
 
4336
        if (code == TARGET_ARCH_GET_GS)
 
4337
            idx = R_GS;
 
4338
        else
 
4339
            idx = R_FS;
 
4340
        val = env->segs[idx].base;
 
4341
        if (put_user(val, addr, abi_ulong))
 
4342
            ret = -TARGET_EFAULT;
 
4343
        break;
 
4344
    default:
 
4345
        ret = -TARGET_EINVAL;
 
4346
        break;
 
4347
    }
 
4348
    return ret;
 
4349
}
 
4350
#endif
 
4351
 
 
4352
#endif /* defined(TARGET_I386) */
 
4353
 
 
4354
#define NEW_STACK_SIZE 0x40000
 
4355
 
 
4356
 
 
4357
static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
 
4358
typedef struct {
 
4359
    CPUArchState *env;
 
4360
    pthread_mutex_t mutex;
 
4361
    pthread_cond_t cond;
 
4362
    pthread_t thread;
 
4363
    uint32_t tid;
 
4364
    abi_ulong child_tidptr;
 
4365
    abi_ulong parent_tidptr;
 
4366
    sigset_t sigmask;
 
4367
} new_thread_info;
 
4368
 
 
4369
static void *clone_func(void *arg)
 
4370
{
 
4371
    new_thread_info *info = arg;
 
4372
    CPUArchState *env;
 
4373
    CPUState *cpu;
 
4374
    TaskState *ts;
 
4375
 
 
4376
    env = info->env;
 
4377
    cpu = ENV_GET_CPU(env);
 
4378
    thread_cpu = cpu;
 
4379
    ts = (TaskState *)env->opaque;
 
4380
    info->tid = gettid();
 
4381
    cpu->host_tid = info->tid;
 
4382
    task_settid(ts);
 
4383
    if (info->child_tidptr)
 
4384
        put_user_u32(info->tid, info->child_tidptr);
 
4385
    if (info->parent_tidptr)
 
4386
        put_user_u32(info->tid, info->parent_tidptr);
 
4387
    /* Enable signals.  */
 
4388
    sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
 
4389
    /* Signal to the parent that we're ready.  */
 
4390
    pthread_mutex_lock(&info->mutex);
 
4391
    pthread_cond_broadcast(&info->cond);
 
4392
    pthread_mutex_unlock(&info->mutex);
 
4393
    /* Wait until the parent has finshed initializing the tls state.  */
 
4394
    pthread_mutex_lock(&clone_lock);
 
4395
    pthread_mutex_unlock(&clone_lock);
 
4396
    cpu_loop(env);
 
4397
    /* never exits */
 
4398
    return NULL;
 
4399
}
 
4400
 
 
4401
/* do_fork() Must return host values and target errnos (unlike most
 
4402
   do_*() functions). */
 
4403
static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
 
4404
                   abi_ulong parent_tidptr, target_ulong newtls,
 
4405
                   abi_ulong child_tidptr)
 
4406
{
 
4407
    int ret;
 
4408
    TaskState *ts;
 
4409
    CPUArchState *new_env;
 
4410
    unsigned int nptl_flags;
 
4411
    sigset_t sigmask;
 
4412
 
 
4413
    /* Emulate vfork() with fork() */
 
4414
    if (flags & CLONE_VFORK)
 
4415
        flags &= ~(CLONE_VFORK | CLONE_VM);
 
4416
 
 
4417
    if (flags & CLONE_VM) {
 
4418
        TaskState *parent_ts = (TaskState *)env->opaque;
 
4419
        new_thread_info info;
 
4420
        pthread_attr_t attr;
 
4421
 
 
4422
        ts = g_malloc0(sizeof(TaskState));
 
4423
        init_task_state(ts);
 
4424
        /* we create a new CPU instance. */
 
4425
        new_env = cpu_copy(env);
 
4426
        /* Init regs that differ from the parent.  */
 
4427
        cpu_clone_regs(new_env, newsp);
 
4428
        new_env->opaque = ts;
 
4429
        ts->bprm = parent_ts->bprm;
 
4430
        ts->info = parent_ts->info;
 
4431
        nptl_flags = flags;
 
4432
        flags &= ~CLONE_NPTL_FLAGS2;
 
4433
 
 
4434
        if (nptl_flags & CLONE_CHILD_CLEARTID) {
 
4435
            ts->child_tidptr = child_tidptr;
 
4436
        }
 
4437
 
 
4438
        if (nptl_flags & CLONE_SETTLS)
 
4439
            cpu_set_tls (new_env, newtls);
 
4440
 
 
4441
        /* Grab a mutex so that thread setup appears atomic.  */
 
4442
        pthread_mutex_lock(&clone_lock);
 
4443
 
 
4444
        memset(&info, 0, sizeof(info));
 
4445
        pthread_mutex_init(&info.mutex, NULL);
 
4446
        pthread_mutex_lock(&info.mutex);
 
4447
        pthread_cond_init(&info.cond, NULL);
 
4448
        info.env = new_env;
 
4449
        if (nptl_flags & CLONE_CHILD_SETTID)
 
4450
            info.child_tidptr = child_tidptr;
 
4451
        if (nptl_flags & CLONE_PARENT_SETTID)
 
4452
            info.parent_tidptr = parent_tidptr;
 
4453
 
 
4454
        ret = pthread_attr_init(&attr);
 
4455
        ret = pthread_attr_setstacksize(&attr, NEW_STACK_SIZE);
 
4456
        ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
 
4457
        /* It is not safe to deliver signals until the child has finished
 
4458
           initializing, so temporarily block all signals.  */
 
4459
        sigfillset(&sigmask);
 
4460
        sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
 
4461
 
 
4462
        ret = pthread_create(&info.thread, &attr, clone_func, &info);
 
4463
        /* TODO: Free new CPU state if thread creation failed.  */
 
4464
 
 
4465
        sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
 
4466
        pthread_attr_destroy(&attr);
 
4467
        if (ret == 0) {
 
4468
            /* Wait for the child to initialize.  */
 
4469
            pthread_cond_wait(&info.cond, &info.mutex);
 
4470
            ret = info.tid;
 
4471
            if (flags & CLONE_PARENT_SETTID)
 
4472
                put_user_u32(ret, parent_tidptr);
 
4473
        } else {
 
4474
            ret = -1;
 
4475
        }
 
4476
        pthread_mutex_unlock(&info.mutex);
 
4477
        pthread_cond_destroy(&info.cond);
 
4478
        pthread_mutex_destroy(&info.mutex);
 
4479
        pthread_mutex_unlock(&clone_lock);
 
4480
    } else {
 
4481
        /* if no CLONE_VM, we consider it is a fork */
 
4482
        if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
 
4483
            return -EINVAL;
 
4484
        fork_start();
 
4485
        ret = fork();
 
4486
        if (ret == 0) {
 
4487
            /* Child Process.  */
 
4488
            cpu_clone_regs(env, newsp);
 
4489
            fork_end(1);
 
4490
            /* There is a race condition here.  The parent process could
 
4491
               theoretically read the TID in the child process before the child
 
4492
               tid is set.  This would require using either ptrace
 
4493
               (not implemented) or having *_tidptr to point at a shared memory
 
4494
               mapping.  We can't repeat the spinlock hack used above because
 
4495
               the child process gets its own copy of the lock.  */
 
4496
            if (flags & CLONE_CHILD_SETTID)
 
4497
                put_user_u32(gettid(), child_tidptr);
 
4498
            if (flags & CLONE_PARENT_SETTID)
 
4499
                put_user_u32(gettid(), parent_tidptr);
 
4500
            ts = (TaskState *)env->opaque;
 
4501
            if (flags & CLONE_SETTLS)
 
4502
                cpu_set_tls (env, newtls);
 
4503
            if (flags & CLONE_CHILD_CLEARTID)
 
4504
                ts->child_tidptr = child_tidptr;
 
4505
        } else {
 
4506
            fork_end(0);
 
4507
        }
 
4508
    }
 
4509
    return ret;
 
4510
}
 
4511
 
 
4512
/* warning : doesn't handle linux specific flags... */
 
4513
static int target_to_host_fcntl_cmd(int cmd)
 
4514
{
 
4515
    switch(cmd) {
 
4516
        case TARGET_F_DUPFD:
 
4517
        case TARGET_F_GETFD:
 
4518
        case TARGET_F_SETFD:
 
4519
        case TARGET_F_GETFL:
 
4520
        case TARGET_F_SETFL:
 
4521
            return cmd;
 
4522
        case TARGET_F_GETLK:
 
4523
            return F_GETLK;
 
4524
        case TARGET_F_SETLK:
 
4525
            return F_SETLK;
 
4526
        case TARGET_F_SETLKW:
 
4527
            return F_SETLKW;
 
4528
        case TARGET_F_GETOWN:
 
4529
            return F_GETOWN;
 
4530
        case TARGET_F_SETOWN:
 
4531
            return F_SETOWN;
 
4532
        case TARGET_F_GETSIG:
 
4533
            return F_GETSIG;
 
4534
        case TARGET_F_SETSIG:
 
4535
            return F_SETSIG;
 
4536
#if TARGET_ABI_BITS == 32
 
4537
        case TARGET_F_GETLK64:
 
4538
            return F_GETLK64;
 
4539
        case TARGET_F_SETLK64:
 
4540
            return F_SETLK64;
 
4541
        case TARGET_F_SETLKW64:
 
4542
            return F_SETLKW64;
 
4543
#endif
 
4544
        case TARGET_F_SETLEASE:
 
4545
            return F_SETLEASE;
 
4546
        case TARGET_F_GETLEASE:
 
4547
            return F_GETLEASE;
 
4548
#ifdef F_DUPFD_CLOEXEC
 
4549
        case TARGET_F_DUPFD_CLOEXEC:
 
4550
            return F_DUPFD_CLOEXEC;
 
4551
#endif
 
4552
        case TARGET_F_NOTIFY:
 
4553
            return F_NOTIFY;
 
4554
        default:
 
4555
            return -TARGET_EINVAL;
 
4556
    }
 
4557
    return -TARGET_EINVAL;
 
4558
}
 
4559
 
 
4560
#define TRANSTBL_CONVERT(a) { -1, TARGET_##a, -1, a }
 
4561
static const bitmask_transtbl flock_tbl[] = {
 
4562
    TRANSTBL_CONVERT(F_RDLCK),
 
4563
    TRANSTBL_CONVERT(F_WRLCK),
 
4564
    TRANSTBL_CONVERT(F_UNLCK),
 
4565
    TRANSTBL_CONVERT(F_EXLCK),
 
4566
    TRANSTBL_CONVERT(F_SHLCK),
 
4567
    { 0, 0, 0, 0 }
 
4568
};
 
4569
 
 
4570
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
 
4571
{
 
4572
    struct flock fl;
 
4573
    struct target_flock *target_fl;
 
4574
    struct flock64 fl64;
 
4575
    struct target_flock64 *target_fl64;
 
4576
    abi_long ret;
 
4577
    int host_cmd = target_to_host_fcntl_cmd(cmd);
 
4578
 
 
4579
    if (host_cmd == -TARGET_EINVAL)
 
4580
            return host_cmd;
 
4581
 
 
4582
    switch(cmd) {
 
4583
    case TARGET_F_GETLK:
 
4584
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
 
4585
            return -TARGET_EFAULT;
 
4586
        fl.l_type =
 
4587
                  target_to_host_bitmask(tswap16(target_fl->l_type), flock_tbl);
 
4588
        fl.l_whence = tswap16(target_fl->l_whence);
 
4589
        fl.l_start = tswapal(target_fl->l_start);
 
4590
        fl.l_len = tswapal(target_fl->l_len);
 
4591
        fl.l_pid = tswap32(target_fl->l_pid);
 
4592
        unlock_user_struct(target_fl, arg, 0);
 
4593
        ret = get_errno(fcntl(fd, host_cmd, &fl));
 
4594
        if (ret == 0) {
 
4595
            if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
 
4596
                return -TARGET_EFAULT;
 
4597
            target_fl->l_type =
 
4598
                          host_to_target_bitmask(tswap16(fl.l_type), flock_tbl);
 
4599
            target_fl->l_whence = tswap16(fl.l_whence);
 
4600
            target_fl->l_start = tswapal(fl.l_start);
 
4601
            target_fl->l_len = tswapal(fl.l_len);
 
4602
            target_fl->l_pid = tswap32(fl.l_pid);
 
4603
            unlock_user_struct(target_fl, arg, 1);
 
4604
        }
 
4605
        break;
 
4606
 
 
4607
    case TARGET_F_SETLK:
 
4608
    case TARGET_F_SETLKW:
 
4609
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
 
4610
            return -TARGET_EFAULT;
 
4611
        fl.l_type =
 
4612
                  target_to_host_bitmask(tswap16(target_fl->l_type), flock_tbl);
 
4613
        fl.l_whence = tswap16(target_fl->l_whence);
 
4614
        fl.l_start = tswapal(target_fl->l_start);
 
4615
        fl.l_len = tswapal(target_fl->l_len);
 
4616
        fl.l_pid = tswap32(target_fl->l_pid);
 
4617
        unlock_user_struct(target_fl, arg, 0);
 
4618
        ret = get_errno(fcntl(fd, host_cmd, &fl));
 
4619
        break;
 
4620
 
 
4621
    case TARGET_F_GETLK64:
 
4622
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
 
4623
            return -TARGET_EFAULT;
 
4624
        fl64.l_type =
 
4625
           target_to_host_bitmask(tswap16(target_fl64->l_type), flock_tbl) >> 1;
 
4626
        fl64.l_whence = tswap16(target_fl64->l_whence);
 
4627
        fl64.l_start = tswap64(target_fl64->l_start);
 
4628
        fl64.l_len = tswap64(target_fl64->l_len);
 
4629
        fl64.l_pid = tswap32(target_fl64->l_pid);
 
4630
        unlock_user_struct(target_fl64, arg, 0);
 
4631
        ret = get_errno(fcntl(fd, host_cmd, &fl64));
 
4632
        if (ret == 0) {
 
4633
            if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
 
4634
                return -TARGET_EFAULT;
 
4635
            target_fl64->l_type =
 
4636
                   host_to_target_bitmask(tswap16(fl64.l_type), flock_tbl) >> 1;
 
4637
            target_fl64->l_whence = tswap16(fl64.l_whence);
 
4638
            target_fl64->l_start = tswap64(fl64.l_start);
 
4639
            target_fl64->l_len = tswap64(fl64.l_len);
 
4640
            target_fl64->l_pid = tswap32(fl64.l_pid);
 
4641
            unlock_user_struct(target_fl64, arg, 1);
 
4642
        }
 
4643
        break;
 
4644
    case TARGET_F_SETLK64:
 
4645
    case TARGET_F_SETLKW64:
 
4646
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
 
4647
            return -TARGET_EFAULT;
 
4648
        fl64.l_type =
 
4649
           target_to_host_bitmask(tswap16(target_fl64->l_type), flock_tbl) >> 1;
 
4650
        fl64.l_whence = tswap16(target_fl64->l_whence);
 
4651
        fl64.l_start = tswap64(target_fl64->l_start);
 
4652
        fl64.l_len = tswap64(target_fl64->l_len);
 
4653
        fl64.l_pid = tswap32(target_fl64->l_pid);
 
4654
        unlock_user_struct(target_fl64, arg, 0);
 
4655
        ret = get_errno(fcntl(fd, host_cmd, &fl64));
 
4656
        break;
 
4657
 
 
4658
    case TARGET_F_GETFL:
 
4659
        ret = get_errno(fcntl(fd, host_cmd, arg));
 
4660
        if (ret >= 0) {
 
4661
            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
 
4662
        }
 
4663
        break;
 
4664
 
 
4665
    case TARGET_F_SETFL:
 
4666
        ret = get_errno(fcntl(fd, host_cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
 
4667
        break;
 
4668
 
 
4669
    case TARGET_F_SETOWN:
 
4670
    case TARGET_F_GETOWN:
 
4671
    case TARGET_F_SETSIG:
 
4672
    case TARGET_F_GETSIG:
 
4673
    case TARGET_F_SETLEASE:
 
4674
    case TARGET_F_GETLEASE:
 
4675
        ret = get_errno(fcntl(fd, host_cmd, arg));
 
4676
        break;
 
4677
 
 
4678
    default:
 
4679
        ret = get_errno(fcntl(fd, cmd, arg));
 
4680
        break;
 
4681
    }
 
4682
    return ret;
 
4683
}
 
4684
 
 
4685
#ifdef USE_UID16
 
4686
 
 
4687
static inline int high2lowuid(int uid)
 
4688
{
 
4689
    if (uid > 65535)
 
4690
        return 65534;
 
4691
    else
 
4692
        return uid;
 
4693
}
 
4694
 
 
4695
static inline int high2lowgid(int gid)
 
4696
{
 
4697
    if (gid > 65535)
 
4698
        return 65534;
 
4699
    else
 
4700
        return gid;
 
4701
}
 
4702
 
 
4703
static inline int low2highuid(int uid)
 
4704
{
 
4705
    if ((int16_t)uid == -1)
 
4706
        return -1;
 
4707
    else
 
4708
        return uid;
 
4709
}
 
4710
 
 
4711
static inline int low2highgid(int gid)
 
4712
{
 
4713
    if ((int16_t)gid == -1)
 
4714
        return -1;
 
4715
    else
 
4716
        return gid;
 
4717
}
 
4718
static inline int tswapid(int id)
 
4719
{
 
4720
    return tswap16(id);
 
4721
}
 
4722
#else /* !USE_UID16 */
 
4723
static inline int high2lowuid(int uid)
 
4724
{
 
4725
    return uid;
 
4726
}
 
4727
static inline int high2lowgid(int gid)
 
4728
{
 
4729
    return gid;
 
4730
}
 
4731
static inline int low2highuid(int uid)
 
4732
{
 
4733
    return uid;
 
4734
}
 
4735
static inline int low2highgid(int gid)
 
4736
{
 
4737
    return gid;
 
4738
}
 
4739
static inline int tswapid(int id)
 
4740
{
 
4741
    return tswap32(id);
 
4742
}
 
4743
#endif /* USE_UID16 */
 
4744
 
 
4745
void syscall_init(void)
 
4746
{
 
4747
    IOCTLEntry *ie;
 
4748
    const argtype *arg_type;
 
4749
    int size;
 
4750
    int i;
 
4751
 
 
4752
#define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
 
4753
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
 
4754
#include "syscall_types.h"
 
4755
#undef STRUCT
 
4756
#undef STRUCT_SPECIAL
 
4757
 
 
4758
    /* Build target_to_host_errno_table[] table from
 
4759
     * host_to_target_errno_table[]. */
 
4760
    for (i = 0; i < ERRNO_TABLE_SIZE; i++) {
 
4761
        target_to_host_errno_table[host_to_target_errno_table[i]] = i;
 
4762
    }
 
4763
 
 
4764
    /* we patch the ioctl size if necessary. We rely on the fact that
 
4765
       no ioctl has all the bits at '1' in the size field */
 
4766
    ie = ioctl_entries;
 
4767
    while (ie->target_cmd != 0) {
 
4768
        if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
 
4769
            TARGET_IOC_SIZEMASK) {
 
4770
            arg_type = ie->arg_type;
 
4771
            if (arg_type[0] != TYPE_PTR) {
 
4772
                fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
 
4773
                        ie->target_cmd);
 
4774
                exit(1);
 
4775
            }
 
4776
            arg_type++;
 
4777
            size = thunk_type_size(arg_type, 0);
 
4778
            ie->target_cmd = (ie->target_cmd &
 
4779
                              ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
 
4780
                (size << TARGET_IOC_SIZESHIFT);
 
4781
        }
 
4782
 
 
4783
        /* automatic consistency check if same arch */
 
4784
#if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
 
4785
    (defined(__x86_64__) && defined(TARGET_X86_64))
 
4786
        if (unlikely(ie->target_cmd != ie->host_cmd)) {
 
4787
            fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
 
4788
                    ie->name, ie->target_cmd, ie->host_cmd);
 
4789
        }
 
4790
#endif
 
4791
        ie++;
 
4792
    }
 
4793
}
 
4794
 
 
4795
#if TARGET_ABI_BITS == 32
 
4796
static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
 
4797
{
 
4798
#ifdef TARGET_WORDS_BIGENDIAN
 
4799
    return ((uint64_t)word0 << 32) | word1;
 
4800
#else
 
4801
    return ((uint64_t)word1 << 32) | word0;
 
4802
#endif
 
4803
}
 
4804
#else /* TARGET_ABI_BITS == 32 */
 
4805
static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
 
4806
{
 
4807
    return word0;
 
4808
}
 
4809
#endif /* TARGET_ABI_BITS != 32 */
 
4810
 
 
4811
#ifdef TARGET_NR_truncate64
 
4812
static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
 
4813
                                         abi_long arg2,
 
4814
                                         abi_long arg3,
 
4815
                                         abi_long arg4)
 
4816
{
 
4817
    if (regpairs_aligned(cpu_env)) {
 
4818
        arg2 = arg3;
 
4819
        arg3 = arg4;
 
4820
    }
 
4821
    return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
 
4822
}
 
4823
#endif
 
4824
 
 
4825
#ifdef TARGET_NR_ftruncate64
 
4826
static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
 
4827
                                          abi_long arg2,
 
4828
                                          abi_long arg3,
 
4829
                                          abi_long arg4)
 
4830
{
 
4831
    if (regpairs_aligned(cpu_env)) {
 
4832
        arg2 = arg3;
 
4833
        arg3 = arg4;
 
4834
    }
 
4835
    return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
 
4836
}
 
4837
#endif
 
4838
 
 
4839
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
 
4840
                                               abi_ulong target_addr)
 
4841
{
 
4842
    struct target_timespec *target_ts;
 
4843
 
 
4844
    if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
 
4845
        return -TARGET_EFAULT;
 
4846
    host_ts->tv_sec = tswapal(target_ts->tv_sec);
 
4847
    host_ts->tv_nsec = tswapal(target_ts->tv_nsec);
 
4848
    unlock_user_struct(target_ts, target_addr, 0);
 
4849
    return 0;
 
4850
}
 
4851
 
 
4852
static inline abi_long host_to_target_timespec(abi_ulong target_addr,
 
4853
                                               struct timespec *host_ts)
 
4854
{
 
4855
    struct target_timespec *target_ts;
 
4856
 
 
4857
    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
 
4858
        return -TARGET_EFAULT;
 
4859
    target_ts->tv_sec = tswapal(host_ts->tv_sec);
 
4860
    target_ts->tv_nsec = tswapal(host_ts->tv_nsec);
 
4861
    unlock_user_struct(target_ts, target_addr, 1);
 
4862
    return 0;
 
4863
}
 
4864
 
 
4865
#if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
 
4866
static inline abi_long host_to_target_stat64(void *cpu_env,
 
4867
                                             abi_ulong target_addr,
 
4868
                                             struct stat *host_st)
 
4869
{
 
4870
#if defined(TARGET_ARM) && defined(TARGET_ABI32)
 
4871
    if (((CPUARMState *)cpu_env)->eabi) {
 
4872
        struct target_eabi_stat64 *target_st;
 
4873
 
 
4874
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
 
4875
            return -TARGET_EFAULT;
 
4876
        memset(target_st, 0, sizeof(struct target_eabi_stat64));
 
4877
        __put_user(host_st->st_dev, &target_st->st_dev);
 
4878
        __put_user(host_st->st_ino, &target_st->st_ino);
 
4879
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
 
4880
        __put_user(host_st->st_ino, &target_st->__st_ino);
 
4881
#endif
 
4882
        __put_user(host_st->st_mode, &target_st->st_mode);
 
4883
        __put_user(host_st->st_nlink, &target_st->st_nlink);
 
4884
        __put_user(host_st->st_uid, &target_st->st_uid);
 
4885
        __put_user(host_st->st_gid, &target_st->st_gid);
 
4886
        __put_user(host_st->st_rdev, &target_st->st_rdev);
 
4887
        __put_user(host_st->st_size, &target_st->st_size);
 
4888
        __put_user(host_st->st_blksize, &target_st->st_blksize);
 
4889
        __put_user(host_st->st_blocks, &target_st->st_blocks);
 
4890
        __put_user(host_st->st_atime, &target_st->target_st_atime);
 
4891
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
 
4892
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
 
4893
        unlock_user_struct(target_st, target_addr, 1);
 
4894
    } else
 
4895
#endif
 
4896
    {
 
4897
#if defined(TARGET_HAS_STRUCT_STAT64)
 
4898
        struct target_stat64 *target_st;
 
4899
#else
 
4900
        struct target_stat *target_st;
 
4901
#endif
 
4902
 
 
4903
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
 
4904
            return -TARGET_EFAULT;
 
4905
        memset(target_st, 0, sizeof(*target_st));
 
4906
        __put_user(host_st->st_dev, &target_st->st_dev);
 
4907
        __put_user(host_st->st_ino, &target_st->st_ino);
 
4908
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
 
4909
        __put_user(host_st->st_ino, &target_st->__st_ino);
 
4910
#endif
 
4911
        __put_user(host_st->st_mode, &target_st->st_mode);
 
4912
        __put_user(host_st->st_nlink, &target_st->st_nlink);
 
4913
        __put_user(host_st->st_uid, &target_st->st_uid);
 
4914
        __put_user(host_st->st_gid, &target_st->st_gid);
 
4915
        __put_user(host_st->st_rdev, &target_st->st_rdev);
 
4916
        /* XXX: better use of kernel struct */
 
4917
        __put_user(host_st->st_size, &target_st->st_size);
 
4918
        __put_user(host_st->st_blksize, &target_st->st_blksize);
 
4919
        __put_user(host_st->st_blocks, &target_st->st_blocks);
 
4920
        __put_user(host_st->st_atime, &target_st->target_st_atime);
 
4921
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
 
4922
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
 
4923
        unlock_user_struct(target_st, target_addr, 1);
 
4924
    }
 
4925
 
 
4926
    return 0;
 
4927
}
 
4928
#endif
 
4929
 
 
4930
/* ??? Using host futex calls even when target atomic operations
 
4931
   are not really atomic probably breaks things.  However implementing
 
4932
   futexes locally would make futexes shared between multiple processes
 
4933
   tricky.  However they're probably useless because guest atomic
 
4934
   operations won't work either.  */
 
4935
static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
 
4936
                    target_ulong uaddr2, int val3)
 
4937
{
 
4938
    struct timespec ts, *pts;
 
4939
    int base_op;
 
4940
 
 
4941
    /* ??? We assume FUTEX_* constants are the same on both host
 
4942
       and target.  */
 
4943
#ifdef FUTEX_CMD_MASK
 
4944
    base_op = op & FUTEX_CMD_MASK;
 
4945
#else
 
4946
    base_op = op;
 
4947
#endif
 
4948
    switch (base_op) {
 
4949
    case FUTEX_WAIT:
 
4950
    case FUTEX_WAIT_BITSET:
 
4951
        if (timeout) {
 
4952
            pts = &ts;
 
4953
            target_to_host_timespec(pts, timeout);
 
4954
        } else {
 
4955
            pts = NULL;
 
4956
        }
 
4957
        return get_errno(sys_futex(g2h(uaddr), op, tswap32(val),
 
4958
                         pts, NULL, val3));
 
4959
    case FUTEX_WAKE:
 
4960
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
 
4961
    case FUTEX_FD:
 
4962
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
 
4963
    case FUTEX_REQUEUE:
 
4964
    case FUTEX_CMP_REQUEUE:
 
4965
    case FUTEX_WAKE_OP:
 
4966
        /* For FUTEX_REQUEUE, FUTEX_CMP_REQUEUE, and FUTEX_WAKE_OP, the
 
4967
           TIMEOUT parameter is interpreted as a uint32_t by the kernel.
 
4968
           But the prototype takes a `struct timespec *'; insert casts
 
4969
           to satisfy the compiler.  We do not need to tswap TIMEOUT
 
4970
           since it's not compared to guest memory.  */
 
4971
        pts = (struct timespec *)(uintptr_t) timeout;
 
4972
        return get_errno(sys_futex(g2h(uaddr), op, val, pts,
 
4973
                                   g2h(uaddr2),
 
4974
                                   (base_op == FUTEX_CMP_REQUEUE
 
4975
                                    ? tswap32(val3)
 
4976
                                    : val3)));
 
4977
    default:
 
4978
        return -TARGET_ENOSYS;
 
4979
    }
 
4980
}
 
4981
 
 
4982
/* Map host to target signal numbers for the wait family of syscalls.
 
4983
   Assume all other status bits are the same.  */
 
4984
int host_to_target_waitstatus(int status)
 
4985
{
 
4986
    if (WIFSIGNALED(status)) {
 
4987
        return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f);
 
4988
    }
 
4989
    if (WIFSTOPPED(status)) {
 
4990
        return (host_to_target_signal(WSTOPSIG(status)) << 8)
 
4991
               | (status & 0xff);
 
4992
    }
 
4993
    return status;
 
4994
}
 
4995
 
 
4996
static int relstr_to_int(const char *s)
 
4997
{
 
4998
    /* Convert a uname release string like "2.6.18" to an integer
 
4999
     * of the form 0x020612. (Beware that 0x020612 is *not* 2.6.12.)
 
5000
     */
 
5001
    int i, n, tmp;
 
5002
 
 
5003
    tmp = 0;
 
5004
    for (i = 0; i < 3; i++) {
 
5005
        n = 0;
 
5006
        while (*s >= '0' && *s <= '9') {
 
5007
            n *= 10;
 
5008
            n += *s - '0';
 
5009
            s++;
 
5010
        }
 
5011
        tmp = (tmp << 8) + n;
 
5012
        if (*s == '.') {
 
5013
            s++;
 
5014
        }
 
5015
    }
 
5016
    return tmp;
 
5017
}
 
5018
 
 
5019
int get_osversion(void)
 
5020
{
 
5021
    static int osversion;
 
5022
    struct new_utsname buf;
 
5023
    const char *s;
 
5024
 
 
5025
    if (osversion)
 
5026
        return osversion;
 
5027
    if (qemu_uname_release && *qemu_uname_release) {
 
5028
        s = qemu_uname_release;
 
5029
    } else {
 
5030
        if (sys_uname(&buf))
 
5031
            return 0;
 
5032
        s = buf.release;
 
5033
    }
 
5034
    osversion = relstr_to_int(s);
 
5035
    return osversion;
 
5036
}
 
5037
 
 
5038
void init_qemu_uname_release(void)
 
5039
{
 
5040
    /* Initialize qemu_uname_release for later use.
 
5041
     * If the host kernel is too old and the user hasn't asked for
 
5042
     * a specific fake version number, we might want to fake a minimum
 
5043
     * target kernel version.
 
5044
     */
 
5045
#ifdef UNAME_MINIMUM_RELEASE
 
5046
    struct new_utsname buf;
 
5047
 
 
5048
    if (qemu_uname_release && *qemu_uname_release) {
 
5049
        return;
 
5050
    }
 
5051
 
 
5052
    if (sys_uname(&buf)) {
 
5053
        return;
 
5054
    }
 
5055
 
 
5056
    if (relstr_to_int(buf.release) < relstr_to_int(UNAME_MINIMUM_RELEASE)) {
 
5057
        qemu_uname_release = UNAME_MINIMUM_RELEASE;
 
5058
    }
 
5059
#endif
 
5060
}
 
5061
 
 
5062
static int open_self_maps(void *cpu_env, int fd)
 
5063
{
 
5064
#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
 
5065
    TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
 
5066
#endif
 
5067
    FILE *fp;
 
5068
    char *line = NULL;
 
5069
    size_t len = 0;
 
5070
    ssize_t read;
 
5071
 
 
5072
    fp = fopen("/proc/self/maps", "r");
 
5073
    if (fp == NULL) {
 
5074
        return -EACCES;
 
5075
    }
 
5076
 
 
5077
    while ((read = getline(&line, &len, fp)) != -1) {
 
5078
        int fields, dev_maj, dev_min, inode;
 
5079
        uint64_t min, max, offset;
 
5080
        char flag_r, flag_w, flag_x, flag_p;
 
5081
        char path[512] = "";
 
5082
        fields = sscanf(line, "%"PRIx64"-%"PRIx64" %c%c%c%c %"PRIx64" %x:%x %d"
 
5083
                        " %512s", &min, &max, &flag_r, &flag_w, &flag_x,
 
5084
                        &flag_p, &offset, &dev_maj, &dev_min, &inode, path);
 
5085
 
 
5086
        if ((fields < 10) || (fields > 11)) {
 
5087
            continue;
 
5088
        }
 
5089
        if (!strncmp(path, "[stack]", 7)) {
 
5090
            continue;
 
5091
        }
 
5092
        if (h2g_valid(min) && h2g_valid(max)) {
 
5093
            dprintf(fd, TARGET_ABI_FMT_lx "-" TARGET_ABI_FMT_lx
 
5094
                    " %c%c%c%c %08" PRIx64 " %02x:%02x %d %s%s\n",
 
5095
                    h2g(min), h2g(max), flag_r, flag_w,
 
5096
                    flag_x, flag_p, offset, dev_maj, dev_min, inode,
 
5097
                    path[0] ? "         " : "", path);
 
5098
        }
 
5099
    }
 
5100
 
 
5101
    free(line);
 
5102
    fclose(fp);
 
5103
 
 
5104
#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
 
5105
    dprintf(fd, "%08llx-%08llx rw-p %08llx 00:00 0          [stack]\n",
 
5106
                (unsigned long long)ts->info->stack_limit,
 
5107
                (unsigned long long)(ts->info->start_stack +
 
5108
                                     (TARGET_PAGE_SIZE - 1)) & TARGET_PAGE_MASK,
 
5109
                (unsigned long long)0);
 
5110
#endif
 
5111
 
 
5112
    return 0;
 
5113
}
 
5114
 
 
5115
static int open_self_stat(void *cpu_env, int fd)
 
5116
{
 
5117
    TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
 
5118
    abi_ulong start_stack = ts->info->start_stack;
 
5119
    int i;
 
5120
 
 
5121
    for (i = 0; i < 44; i++) {
 
5122
      char buf[128];
 
5123
      int len;
 
5124
      uint64_t val = 0;
 
5125
 
 
5126
      if (i == 0) {
 
5127
        /* pid */
 
5128
        val = getpid();
 
5129
        snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
 
5130
      } else if (i == 1) {
 
5131
        /* app name */
 
5132
        snprintf(buf, sizeof(buf), "(%s) ", ts->bprm->argv[0]);
 
5133
      } else if (i == 27) {
 
5134
        /* stack bottom */
 
5135
        val = start_stack;
 
5136
        snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
 
5137
      } else {
 
5138
        /* for the rest, there is MasterCard */
 
5139
        snprintf(buf, sizeof(buf), "0%c", i == 43 ? '\n' : ' ');
 
5140
      }
 
5141
 
 
5142
      len = strlen(buf);
 
5143
      if (write(fd, buf, len) != len) {
 
5144
          return -1;
 
5145
      }
 
5146
    }
 
5147
 
 
5148
    return 0;
 
5149
}
 
5150
 
 
5151
static int open_self_auxv(void *cpu_env, int fd)
 
5152
{
 
5153
    TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
 
5154
    abi_ulong auxv = ts->info->saved_auxv;
 
5155
    abi_ulong len = ts->info->auxv_len;
 
5156
    char *ptr;
 
5157
 
 
5158
    /*
 
5159
     * Auxiliary vector is stored in target process stack.
 
5160
     * read in whole auxv vector and copy it to file
 
5161
     */
 
5162
    ptr = lock_user(VERIFY_READ, auxv, len, 0);
 
5163
    if (ptr != NULL) {
 
5164
        while (len > 0) {
 
5165
            ssize_t r;
 
5166
            r = write(fd, ptr, len);
 
5167
            if (r <= 0) {
 
5168
                break;
 
5169
            }
 
5170
            len -= r;
 
5171
            ptr += r;
 
5172
        }
 
5173
        lseek(fd, 0, SEEK_SET);
 
5174
        unlock_user(ptr, auxv, len);
 
5175
    }
 
5176
 
 
5177
    return 0;
 
5178
}
 
5179
 
 
5180
static int is_proc_myself(const char *filename, const char *entry)
 
5181
{
 
5182
    if (!strncmp(filename, "/proc/", strlen("/proc/"))) {
 
5183
        filename += strlen("/proc/");
 
5184
        if (!strncmp(filename, "self/", strlen("self/"))) {
 
5185
            filename += strlen("self/");
 
5186
        } else if (*filename >= '1' && *filename <= '9') {
 
5187
            char myself[80];
 
5188
            snprintf(myself, sizeof(myself), "%d/", getpid());
 
5189
            if (!strncmp(filename, myself, strlen(myself))) {
 
5190
                filename += strlen(myself);
 
5191
            } else {
 
5192
                return 0;
 
5193
            }
 
5194
        } else {
 
5195
            return 0;
 
5196
        }
 
5197
        if (!strcmp(filename, entry)) {
 
5198
            return 1;
 
5199
        }
 
5200
    }
 
5201
    return 0;
 
5202
}
 
5203
 
 
5204
#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
 
5205
static int is_proc(const char *filename, const char *entry)
 
5206
{
 
5207
    return strcmp(filename, entry) == 0;
 
5208
}
 
5209
 
 
5210
static int open_net_route(void *cpu_env, int fd)
 
5211
{
 
5212
    FILE *fp;
 
5213
    char *line = NULL;
 
5214
    size_t len = 0;
 
5215
    ssize_t read;
 
5216
 
 
5217
    fp = fopen("/proc/net/route", "r");
 
5218
    if (fp == NULL) {
 
5219
        return -EACCES;
 
5220
    }
 
5221
 
 
5222
    /* read header */
 
5223
 
 
5224
    read = getline(&line, &len, fp);
 
5225
    dprintf(fd, "%s", line);
 
5226
 
 
5227
    /* read routes */
 
5228
 
 
5229
    while ((read = getline(&line, &len, fp)) != -1) {
 
5230
        char iface[16];
 
5231
        uint32_t dest, gw, mask;
 
5232
        unsigned int flags, refcnt, use, metric, mtu, window, irtt;
 
5233
        sscanf(line, "%s\t%08x\t%08x\t%04x\t%d\t%d\t%d\t%08x\t%d\t%u\t%u\n",
 
5234
                     iface, &dest, &gw, &flags, &refcnt, &use, &metric,
 
5235
                     &mask, &mtu, &window, &irtt);
 
5236
        dprintf(fd, "%s\t%08x\t%08x\t%04x\t%d\t%d\t%d\t%08x\t%d\t%u\t%u\n",
 
5237
                iface, tswap32(dest), tswap32(gw), flags, refcnt, use,
 
5238
                metric, tswap32(mask), mtu, window, irtt);
 
5239
    }
 
5240
 
 
5241
    free(line);
 
5242
    fclose(fp);
 
5243
 
 
5244
    return 0;
 
5245
}
 
5246
#endif
 
5247
 
 
5248
static int do_open(void *cpu_env, const char *pathname, int flags, mode_t mode)
 
5249
{
 
5250
    struct fake_open {
 
5251
        const char *filename;
 
5252
        int (*fill)(void *cpu_env, int fd);
 
5253
        int (*cmp)(const char *s1, const char *s2);
 
5254
    };
 
5255
    const struct fake_open *fake_open;
 
5256
    static const struct fake_open fakes[] = {
 
5257
        { "maps", open_self_maps, is_proc_myself },
 
5258
        { "stat", open_self_stat, is_proc_myself },
 
5259
        { "auxv", open_self_auxv, is_proc_myself },
 
5260
#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
 
5261
        { "/proc/net/route", open_net_route, is_proc },
 
5262
#endif
 
5263
        { NULL, NULL, NULL }
 
5264
    };
 
5265
 
 
5266
    for (fake_open = fakes; fake_open->filename; fake_open++) {
 
5267
        if (fake_open->cmp(pathname, fake_open->filename)) {
 
5268
            break;
 
5269
        }
 
5270
    }
 
5271
 
 
5272
    if (fake_open->filename) {
 
5273
        const char *tmpdir;
 
5274
        char filename[PATH_MAX];
 
5275
        int fd, r;
 
5276
 
 
5277
        /* create temporary file to map stat to */
 
5278
        tmpdir = getenv("TMPDIR");
 
5279
        if (!tmpdir)
 
5280
            tmpdir = "/tmp";
 
5281
        snprintf(filename, sizeof(filename), "%s/qemu-open.XXXXXX", tmpdir);
 
5282
        fd = mkstemp(filename);
 
5283
        if (fd < 0) {
 
5284
            return fd;
 
5285
        }
 
5286
        unlink(filename);
 
5287
 
 
5288
        if ((r = fake_open->fill(cpu_env, fd))) {
 
5289
            close(fd);
 
5290
            return r;
 
5291
        }
 
5292
        lseek(fd, 0, SEEK_SET);
 
5293
 
 
5294
        return fd;
 
5295
    }
 
5296
 
 
5297
    return get_errno(open(path(pathname), flags, mode));
 
5298
}
 
5299
 
 
5300
/* do_syscall() should always have a single exit point at the end so
 
5301
   that actions, such as logging of syscall results, can be performed.
 
5302
   All errnos that do_syscall() returns must be -TARGET_<errcode>. */
 
5303
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 
5304
                    abi_long arg2, abi_long arg3, abi_long arg4,
 
5305
                    abi_long arg5, abi_long arg6, abi_long arg7,
 
5306
                    abi_long arg8)
 
5307
{
 
5308
    CPUState *cpu = ENV_GET_CPU(cpu_env);
 
5309
    abi_long ret;
 
5310
    struct stat st;
 
5311
    struct statfs stfs;
 
5312
    void *p;
 
5313
 
 
5314
#ifdef DEBUG
 
5315
    gemu_log("syscall %d", num);
 
5316
#endif
 
5317
    if(do_strace)
 
5318
        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
 
5319
 
 
5320
    switch(num) {
 
5321
    case TARGET_NR_exit:
 
5322
        /* In old applications this may be used to implement _exit(2).
 
5323
           However in threaded applictions it is used for thread termination,
 
5324
           and _exit_group is used for application termination.
 
5325
           Do thread termination if we have more then one thread.  */
 
5326
        /* FIXME: This probably breaks if a signal arrives.  We should probably
 
5327
           be disabling signals.  */
 
5328
        if (CPU_NEXT(first_cpu)) {
 
5329
            TaskState *ts;
 
5330
 
 
5331
            cpu_list_lock();
 
5332
            /* Remove the CPU from the list.  */
 
5333
            QTAILQ_REMOVE(&cpus, cpu, node);
 
5334
            cpu_list_unlock();
 
5335
            ts = ((CPUArchState *)cpu_env)->opaque;
 
5336
            if (ts->child_tidptr) {
 
5337
                put_user_u32(0, ts->child_tidptr);
 
5338
                sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
 
5339
                          NULL, NULL, 0);
 
5340
            }
 
5341
            thread_cpu = NULL;
 
5342
            object_unref(OBJECT(ENV_GET_CPU(cpu_env)));
 
5343
            g_free(ts);
 
5344
            pthread_exit(NULL);
 
5345
        }
 
5346
#ifdef TARGET_GPROF
 
5347
        _mcleanup();
 
5348
#endif
 
5349
        gdb_exit(cpu_env, arg1);
 
5350
        _exit(arg1);
 
5351
        ret = 0; /* avoid warning */
 
5352
        break;
 
5353
    case TARGET_NR_read:
 
5354
        if (arg3 == 0)
 
5355
            ret = 0;
 
5356
        else {
 
5357
            if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
 
5358
                goto efault;
 
5359
            ret = get_errno(read(arg1, p, arg3));
 
5360
            unlock_user(p, arg2, ret);
 
5361
        }
 
5362
        break;
 
5363
    case TARGET_NR_write:
 
5364
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
 
5365
            goto efault;
 
5366
        ret = get_errno(write(arg1, p, arg3));
 
5367
        unlock_user(p, arg2, 0);
 
5368
        break;
 
5369
    case TARGET_NR_open:
 
5370
        if (!(p = lock_user_string(arg1)))
 
5371
            goto efault;
 
5372
        ret = get_errno(do_open(cpu_env, p,
 
5373
                                target_to_host_bitmask(arg2, fcntl_flags_tbl),
 
5374
                                arg3));
 
5375
        unlock_user(p, arg1, 0);
 
5376
        break;
 
5377
#if defined(TARGET_NR_openat) && defined(__NR_openat)
 
5378
    case TARGET_NR_openat:
 
5379
        if (!(p = lock_user_string(arg2)))
 
5380
            goto efault;
 
5381
        ret = get_errno(sys_openat(arg1,
 
5382
                                   path(p),
 
5383
                                   target_to_host_bitmask(arg3, fcntl_flags_tbl),
 
5384
                                   arg4));
 
5385
        unlock_user(p, arg2, 0);
 
5386
        break;
 
5387
#endif
 
5388
    case TARGET_NR_close:
 
5389
        ret = get_errno(close(arg1));
 
5390
        break;
 
5391
    case TARGET_NR_brk:
 
5392
        ret = do_brk(arg1);
 
5393
        break;
 
5394
    case TARGET_NR_fork:
 
5395
        ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
 
5396
        break;
 
5397
#ifdef TARGET_NR_waitpid
 
5398
    case TARGET_NR_waitpid:
 
5399
        {
 
5400
            int status;
 
5401
            ret = get_errno(waitpid(arg1, &status, arg3));
 
5402
            if (!is_error(ret) && arg2 && ret
 
5403
                && put_user_s32(host_to_target_waitstatus(status), arg2))
 
5404
                goto efault;
 
5405
        }
 
5406
        break;
 
5407
#endif
 
5408
#ifdef TARGET_NR_waitid
 
5409
    case TARGET_NR_waitid:
 
5410
        {
 
5411
            siginfo_t info;
 
5412
            info.si_pid = 0;
 
5413
            ret = get_errno(waitid(arg1, arg2, &info, arg4));
 
5414
            if (!is_error(ret) && arg3 && info.si_pid != 0) {
 
5415
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
 
5416
                    goto efault;
 
5417
                host_to_target_siginfo(p, &info);
 
5418
                unlock_user(p, arg3, sizeof(target_siginfo_t));
 
5419
            }
 
5420
        }
 
5421
        break;
 
5422
#endif
 
5423
#ifdef TARGET_NR_creat /* not on alpha */
 
5424
    case TARGET_NR_creat:
 
5425
        if (!(p = lock_user_string(arg1)))
 
5426
            goto efault;
 
5427
        ret = get_errno(creat(p, arg2));
 
5428
        unlock_user(p, arg1, 0);
 
5429
        break;
 
5430
#endif
 
5431
    case TARGET_NR_link:
 
5432
        {
 
5433
            void * p2;
 
5434
            p = lock_user_string(arg1);
 
5435
            p2 = lock_user_string(arg2);
 
5436
            if (!p || !p2)
 
5437
                ret = -TARGET_EFAULT;
 
5438
            else
 
5439
                ret = get_errno(link(p, p2));
 
5440
            unlock_user(p2, arg2, 0);
 
5441
            unlock_user(p, arg1, 0);
 
5442
        }
 
5443
        break;
 
5444
#if defined(TARGET_NR_linkat)
 
5445
    case TARGET_NR_linkat:
 
5446
        {
 
5447
            void * p2 = NULL;
 
5448
            if (!arg2 || !arg4)
 
5449
                goto efault;
 
5450
            p  = lock_user_string(arg2);
 
5451
            p2 = lock_user_string(arg4);
 
5452
            if (!p || !p2)
 
5453
                ret = -TARGET_EFAULT;
 
5454
            else
 
5455
                ret = get_errno(linkat(arg1, p, arg3, p2, arg5));
 
5456
            unlock_user(p, arg2, 0);
 
5457
            unlock_user(p2, arg4, 0);
 
5458
        }
 
5459
        break;
 
5460
#endif
 
5461
    case TARGET_NR_unlink:
 
5462
        if (!(p = lock_user_string(arg1)))
 
5463
            goto efault;
 
5464
        ret = get_errno(unlink(p));
 
5465
        unlock_user(p, arg1, 0);
 
5466
        break;
 
5467
#if defined(TARGET_NR_unlinkat)
 
5468
    case TARGET_NR_unlinkat:
 
5469
        if (!(p = lock_user_string(arg2)))
 
5470
            goto efault;
 
5471
        ret = get_errno(unlinkat(arg1, p, arg3));
 
5472
        unlock_user(p, arg2, 0);
 
5473
        break;
 
5474
#endif
 
5475
    case TARGET_NR_execve:
 
5476
        {
 
5477
            char **argp, **envp;
 
5478
            int argc, envc;
 
5479
            abi_ulong gp;
 
5480
            abi_ulong guest_argp;
 
5481
            abi_ulong guest_envp;
 
5482
            abi_ulong addr;
 
5483
            char **q;
 
5484
            int total_size = 0;
 
5485
 
 
5486
            argc = 0;
 
5487
            guest_argp = arg2;
 
5488
            for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
 
5489
                if (get_user_ual(addr, gp))
 
5490
                    goto efault;
 
5491
                if (!addr)
 
5492
                    break;
 
5493
                argc++;
 
5494
            }
 
5495
            envc = 0;
 
5496
            guest_envp = arg3;
 
5497
            for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
 
5498
                if (get_user_ual(addr, gp))
 
5499
                    goto efault;
 
5500
                if (!addr)
 
5501
                    break;
 
5502
                envc++;
 
5503
            }
 
5504
 
 
5505
            argp = alloca((argc + 1) * sizeof(void *));
 
5506
            envp = alloca((envc + 1) * sizeof(void *));
 
5507
 
 
5508
            for (gp = guest_argp, q = argp; gp;
 
5509
                  gp += sizeof(abi_ulong), q++) {
 
5510
                if (get_user_ual(addr, gp))
 
5511
                    goto execve_efault;
 
5512
                if (!addr)
 
5513
                    break;
 
5514
                if (!(*q = lock_user_string(addr)))
 
5515
                    goto execve_efault;
 
5516
                total_size += strlen(*q) + 1;
 
5517
            }
 
5518
            *q = NULL;
 
5519
 
 
5520
            for (gp = guest_envp, q = envp; gp;
 
5521
                  gp += sizeof(abi_ulong), q++) {
 
5522
                if (get_user_ual(addr, gp))
 
5523
                    goto execve_efault;
 
5524
                if (!addr)
 
5525
                    break;
 
5526
                if (!(*q = lock_user_string(addr)))
 
5527
                    goto execve_efault;
 
5528
                total_size += strlen(*q) + 1;
 
5529
            }
 
5530
            *q = NULL;
 
5531
 
 
5532
            /* This case will not be caught by the host's execve() if its
 
5533
               page size is bigger than the target's. */
 
5534
            if (total_size > MAX_ARG_PAGES * TARGET_PAGE_SIZE) {
 
5535
                ret = -TARGET_E2BIG;
 
5536
                goto execve_end;
 
5537
            }
 
5538
            if (!(p = lock_user_string(arg1)))
 
5539
                goto execve_efault;
 
5540
            ret = get_errno(execve(p, argp, envp));
 
5541
            unlock_user(p, arg1, 0);
 
5542
 
 
5543
            goto execve_end;
 
5544
 
 
5545
        execve_efault:
 
5546
            ret = -TARGET_EFAULT;
 
5547
 
 
5548
        execve_end:
 
5549
            for (gp = guest_argp, q = argp; *q;
 
5550
                  gp += sizeof(abi_ulong), q++) {
 
5551
                if (get_user_ual(addr, gp)
 
5552
                    || !addr)
 
5553
                    break;
 
5554
                unlock_user(*q, addr, 0);
 
5555
            }
 
5556
            for (gp = guest_envp, q = envp; *q;
 
5557
                  gp += sizeof(abi_ulong), q++) {
 
5558
                if (get_user_ual(addr, gp)
 
5559
                    || !addr)
 
5560
                    break;
 
5561
                unlock_user(*q, addr, 0);
 
5562
            }
 
5563
        }
 
5564
        break;
 
5565
    case TARGET_NR_chdir:
 
5566
        if (!(p = lock_user_string(arg1)))
 
5567
            goto efault;
 
5568
        ret = get_errno(chdir(p));
 
5569
        unlock_user(p, arg1, 0);
 
5570
        break;
 
5571
#ifdef TARGET_NR_time
 
5572
    case TARGET_NR_time:
 
5573
        {
 
5574
            time_t host_time;
 
5575
            ret = get_errno(time(&host_time));
 
5576
            if (!is_error(ret)
 
5577
                && arg1
 
5578
                && put_user_sal(host_time, arg1))
 
5579
                goto efault;
 
5580
        }
 
5581
        break;
 
5582
#endif
 
5583
    case TARGET_NR_mknod:
 
5584
        if (!(p = lock_user_string(arg1)))
 
5585
            goto efault;
 
5586
        ret = get_errno(mknod(p, arg2, arg3));
 
5587
        unlock_user(p, arg1, 0);
 
5588
        break;
 
5589
#if defined(TARGET_NR_mknodat)
 
5590
    case TARGET_NR_mknodat:
 
5591
        if (!(p = lock_user_string(arg2)))
 
5592
            goto efault;
 
5593
        ret = get_errno(mknodat(arg1, p, arg3, arg4));
 
5594
        unlock_user(p, arg2, 0);
 
5595
        break;
 
5596
#endif
 
5597
    case TARGET_NR_chmod:
 
5598
        if (!(p = lock_user_string(arg1)))
 
5599
            goto efault;
 
5600
        ret = get_errno(chmod(p, arg2));
 
5601
        unlock_user(p, arg1, 0);
 
5602
        break;
 
5603
#ifdef TARGET_NR_break
 
5604
    case TARGET_NR_break:
 
5605
        goto unimplemented;
 
5606
#endif
 
5607
#ifdef TARGET_NR_oldstat
 
5608
    case TARGET_NR_oldstat:
 
5609
        goto unimplemented;
 
5610
#endif
 
5611
    case TARGET_NR_lseek:
 
5612
        ret = get_errno(lseek(arg1, arg2, arg3));
 
5613
        break;
 
5614
#if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA)
 
5615
    /* Alpha specific */
 
5616
    case TARGET_NR_getxpid:
 
5617
        ((CPUAlphaState *)cpu_env)->ir[IR_A4] = getppid();
 
5618
        ret = get_errno(getpid());
 
5619
        break;
 
5620
#endif
 
5621
#ifdef TARGET_NR_getpid
 
5622
    case TARGET_NR_getpid:
 
5623
        ret = get_errno(getpid());
 
5624
        break;
 
5625
#endif
 
5626
    case TARGET_NR_mount:
 
5627
                {
 
5628
                        /* need to look at the data field */
 
5629
                        void *p2, *p3;
 
5630
                        p = lock_user_string(arg1);
 
5631
                        p2 = lock_user_string(arg2);
 
5632
                        p3 = lock_user_string(arg3);
 
5633
                        if (!p || !p2 || !p3)
 
5634
                            ret = -TARGET_EFAULT;
 
5635
                        else {
 
5636
                            /* FIXME - arg5 should be locked, but it isn't clear how to
 
5637
                             * do that since it's not guaranteed to be a NULL-terminated
 
5638
                             * string.
 
5639
                             */
 
5640
                            if ( ! arg5 )
 
5641
                                ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, NULL));
 
5642
                            else
 
5643
                                ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
 
5644
                        }
 
5645
                        unlock_user(p, arg1, 0);
 
5646
                        unlock_user(p2, arg2, 0);
 
5647
                        unlock_user(p3, arg3, 0);
 
5648
                        break;
 
5649
                }
 
5650
#ifdef TARGET_NR_umount
 
5651
    case TARGET_NR_umount:
 
5652
        if (!(p = lock_user_string(arg1)))
 
5653
            goto efault;
 
5654
        ret = get_errno(umount(p));
 
5655
        unlock_user(p, arg1, 0);
 
5656
        break;
 
5657
#endif
 
5658
#ifdef TARGET_NR_stime /* not on alpha */
 
5659
    case TARGET_NR_stime:
 
5660
        {
 
5661
            time_t host_time;
 
5662
            if (get_user_sal(host_time, arg1))
 
5663
                goto efault;
 
5664
            ret = get_errno(stime(&host_time));
 
5665
        }
 
5666
        break;
 
5667
#endif
 
5668
    case TARGET_NR_ptrace:
 
5669
        goto unimplemented;
 
5670
#ifdef TARGET_NR_alarm /* not on alpha */
 
5671
    case TARGET_NR_alarm:
 
5672
        ret = alarm(arg1);
 
5673
        break;
 
5674
#endif
 
5675
#ifdef TARGET_NR_oldfstat
 
5676
    case TARGET_NR_oldfstat:
 
5677
        goto unimplemented;
 
5678
#endif
 
5679
#ifdef TARGET_NR_pause /* not on alpha */
 
5680
    case TARGET_NR_pause:
 
5681
        ret = get_errno(pause());
 
5682
        break;
 
5683
#endif
 
5684
#ifdef TARGET_NR_utime
 
5685
    case TARGET_NR_utime:
 
5686
        {
 
5687
            struct utimbuf tbuf, *host_tbuf;
 
5688
            struct target_utimbuf *target_tbuf;
 
5689
            if (arg2) {
 
5690
                if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
 
5691
                    goto efault;
 
5692
                tbuf.actime = tswapal(target_tbuf->actime);
 
5693
                tbuf.modtime = tswapal(target_tbuf->modtime);
 
5694
                unlock_user_struct(target_tbuf, arg2, 0);
 
5695
                host_tbuf = &tbuf;
 
5696
            } else {
 
5697
                host_tbuf = NULL;
 
5698
            }
 
5699
            if (!(p = lock_user_string(arg1)))
 
5700
                goto efault;
 
5701
            ret = get_errno(utime(p, host_tbuf));
 
5702
            unlock_user(p, arg1, 0);
 
5703
        }
 
5704
        break;
 
5705
#endif
 
5706
    case TARGET_NR_utimes:
 
5707
        {
 
5708
            struct timeval *tvp, tv[2];
 
5709
            if (arg2) {
 
5710
                if (copy_from_user_timeval(&tv[0], arg2)
 
5711
                    || copy_from_user_timeval(&tv[1],
 
5712
                                              arg2 + sizeof(struct target_timeval)))
 
5713
                    goto efault;
 
5714
                tvp = tv;
 
5715
            } else {
 
5716
                tvp = NULL;
 
5717
            }
 
5718
            if (!(p = lock_user_string(arg1)))
 
5719
                goto efault;
 
5720
            ret = get_errno(utimes(p, tvp));
 
5721
            unlock_user(p, arg1, 0);
 
5722
        }
 
5723
        break;
 
5724
#if defined(TARGET_NR_futimesat)
 
5725
    case TARGET_NR_futimesat:
 
5726
        {
 
5727
            struct timeval *tvp, tv[2];
 
5728
            if (arg3) {
 
5729
                if (copy_from_user_timeval(&tv[0], arg3)
 
5730
                    || copy_from_user_timeval(&tv[1],
 
5731
                                              arg3 + sizeof(struct target_timeval)))
 
5732
                    goto efault;
 
5733
                tvp = tv;
 
5734
            } else {
 
5735
                tvp = NULL;
 
5736
            }
 
5737
            if (!(p = lock_user_string(arg2)))
 
5738
                goto efault;
 
5739
            ret = get_errno(futimesat(arg1, path(p), tvp));
 
5740
            unlock_user(p, arg2, 0);
 
5741
        }
 
5742
        break;
 
5743
#endif
 
5744
#ifdef TARGET_NR_stty
 
5745
    case TARGET_NR_stty:
 
5746
        goto unimplemented;
 
5747
#endif
 
5748
#ifdef TARGET_NR_gtty
 
5749
    case TARGET_NR_gtty:
 
5750
        goto unimplemented;
 
5751
#endif
 
5752
    case TARGET_NR_access:
 
5753
        if (!(p = lock_user_string(arg1)))
 
5754
            goto efault;
 
5755
        ret = get_errno(access(path(p), arg2));
 
5756
        unlock_user(p, arg1, 0);
 
5757
        break;
 
5758
#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
 
5759
    case TARGET_NR_faccessat:
 
5760
        if (!(p = lock_user_string(arg2)))
 
5761
            goto efault;
 
5762
        ret = get_errno(faccessat(arg1, p, arg3, 0));
 
5763
        unlock_user(p, arg2, 0);
 
5764
        break;
 
5765
#endif
 
5766
#ifdef TARGET_NR_nice /* not on alpha */
 
5767
    case TARGET_NR_nice:
 
5768
        ret = get_errno(nice(arg1));
 
5769
        break;
 
5770
#endif
 
5771
#ifdef TARGET_NR_ftime
 
5772
    case TARGET_NR_ftime:
 
5773
        goto unimplemented;
 
5774
#endif
 
5775
    case TARGET_NR_sync:
 
5776
        sync();
 
5777
        ret = 0;
 
5778
        break;
 
5779
    case TARGET_NR_kill:
 
5780
        ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
 
5781
        break;
 
5782
    case TARGET_NR_rename:
 
5783
        {
 
5784
            void *p2;
 
5785
            p = lock_user_string(arg1);
 
5786
            p2 = lock_user_string(arg2);
 
5787
            if (!p || !p2)
 
5788
                ret = -TARGET_EFAULT;
 
5789
            else
 
5790
                ret = get_errno(rename(p, p2));
 
5791
            unlock_user(p2, arg2, 0);
 
5792
            unlock_user(p, arg1, 0);
 
5793
        }
 
5794
        break;
 
5795
#if defined(TARGET_NR_renameat)
 
5796
    case TARGET_NR_renameat:
 
5797
        {
 
5798
            void *p2;
 
5799
            p  = lock_user_string(arg2);
 
5800
            p2 = lock_user_string(arg4);
 
5801
            if (!p || !p2)
 
5802
                ret = -TARGET_EFAULT;
 
5803
            else
 
5804
                ret = get_errno(renameat(arg1, p, arg3, p2));
 
5805
            unlock_user(p2, arg4, 0);
 
5806
            unlock_user(p, arg2, 0);
 
5807
        }
 
5808
        break;
 
5809
#endif
 
5810
    case TARGET_NR_mkdir:
 
5811
        if (!(p = lock_user_string(arg1)))
 
5812
            goto efault;
 
5813
        ret = get_errno(mkdir(p, arg2));
 
5814
        unlock_user(p, arg1, 0);
 
5815
        break;
 
5816
#if defined(TARGET_NR_mkdirat)
 
5817
    case TARGET_NR_mkdirat:
 
5818
        if (!(p = lock_user_string(arg2)))
 
5819
            goto efault;
 
5820
        ret = get_errno(mkdirat(arg1, p, arg3));
 
5821
        unlock_user(p, arg2, 0);
 
5822
        break;
 
5823
#endif
 
5824
    case TARGET_NR_rmdir:
 
5825
        if (!(p = lock_user_string(arg1)))
 
5826
            goto efault;
 
5827
        ret = get_errno(rmdir(p));
 
5828
        unlock_user(p, arg1, 0);
 
5829
        break;
 
5830
    case TARGET_NR_dup:
 
5831
        ret = get_errno(dup(arg1));
 
5832
        break;
 
5833
    case TARGET_NR_pipe:
 
5834
        ret = do_pipe(cpu_env, arg1, 0, 0);
 
5835
        break;
 
5836
#ifdef TARGET_NR_pipe2
 
5837
    case TARGET_NR_pipe2:
 
5838
        ret = do_pipe(cpu_env, arg1,
 
5839
                      target_to_host_bitmask(arg2, fcntl_flags_tbl), 1);
 
5840
        break;
 
5841
#endif
 
5842
    case TARGET_NR_times:
 
5843
        {
 
5844
            struct target_tms *tmsp;
 
5845
            struct tms tms;
 
5846
            ret = get_errno(times(&tms));
 
5847
            if (arg1) {
 
5848
                tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
 
5849
                if (!tmsp)
 
5850
                    goto efault;
 
5851
                tmsp->tms_utime = tswapal(host_to_target_clock_t(tms.tms_utime));
 
5852
                tmsp->tms_stime = tswapal(host_to_target_clock_t(tms.tms_stime));
 
5853
                tmsp->tms_cutime = tswapal(host_to_target_clock_t(tms.tms_cutime));
 
5854
                tmsp->tms_cstime = tswapal(host_to_target_clock_t(tms.tms_cstime));
 
5855
            }
 
5856
            if (!is_error(ret))
 
5857
                ret = host_to_target_clock_t(ret);
 
5858
        }
 
5859
        break;
 
5860
#ifdef TARGET_NR_prof
 
5861
    case TARGET_NR_prof:
 
5862
        goto unimplemented;
 
5863
#endif
 
5864
#ifdef TARGET_NR_signal
 
5865
    case TARGET_NR_signal:
 
5866
        goto unimplemented;
 
5867
#endif
 
5868
    case TARGET_NR_acct:
 
5869
        if (arg1 == 0) {
 
5870
            ret = get_errno(acct(NULL));
 
5871
        } else {
 
5872
            if (!(p = lock_user_string(arg1)))
 
5873
                goto efault;
 
5874
            ret = get_errno(acct(path(p)));
 
5875
            unlock_user(p, arg1, 0);
 
5876
        }
 
5877
        break;
 
5878
#ifdef TARGET_NR_umount2
 
5879
    case TARGET_NR_umount2:
 
5880
        if (!(p = lock_user_string(arg1)))
 
5881
            goto efault;
 
5882
        ret = get_errno(umount2(p, arg2));
 
5883
        unlock_user(p, arg1, 0);
 
5884
        break;
 
5885
#endif
 
5886
#ifdef TARGET_NR_lock
 
5887
    case TARGET_NR_lock:
 
5888
        goto unimplemented;
 
5889
#endif
 
5890
    case TARGET_NR_ioctl:
 
5891
        ret = do_ioctl(arg1, arg2, arg3);
 
5892
        break;
 
5893
    case TARGET_NR_fcntl:
 
5894
        ret = do_fcntl(arg1, arg2, arg3);
 
5895
        break;
 
5896
#ifdef TARGET_NR_mpx
 
5897
    case TARGET_NR_mpx:
 
5898
        goto unimplemented;
 
5899
#endif
 
5900
    case TARGET_NR_setpgid:
 
5901
        ret = get_errno(setpgid(arg1, arg2));
 
5902
        break;
 
5903
#ifdef TARGET_NR_ulimit
 
5904
    case TARGET_NR_ulimit:
 
5905
        goto unimplemented;
 
5906
#endif
 
5907
#ifdef TARGET_NR_oldolduname
 
5908
    case TARGET_NR_oldolduname:
 
5909
        goto unimplemented;
 
5910
#endif
 
5911
    case TARGET_NR_umask:
 
5912
        ret = get_errno(umask(arg1));
 
5913
        break;
 
5914
    case TARGET_NR_chroot:
 
5915
        if (!(p = lock_user_string(arg1)))
 
5916
            goto efault;
 
5917
        ret = get_errno(chroot(p));
 
5918
        unlock_user(p, arg1, 0);
 
5919
        break;
 
5920
    case TARGET_NR_ustat:
 
5921
        goto unimplemented;
 
5922
    case TARGET_NR_dup2:
 
5923
        ret = get_errno(dup2(arg1, arg2));
 
5924
        break;
 
5925
#if defined(CONFIG_DUP3) && defined(TARGET_NR_dup3)
 
5926
    case TARGET_NR_dup3:
 
5927
        ret = get_errno(dup3(arg1, arg2, arg3));
 
5928
        break;
 
5929
#endif
 
5930
#ifdef TARGET_NR_getppid /* not on alpha */
 
5931
    case TARGET_NR_getppid:
 
5932
        ret = get_errno(getppid());
 
5933
        break;
 
5934
#endif
 
5935
    case TARGET_NR_getpgrp:
 
5936
        ret = get_errno(getpgrp());
 
5937
        break;
 
5938
    case TARGET_NR_setsid:
 
5939
        ret = get_errno(setsid());
 
5940
        break;
 
5941
#ifdef TARGET_NR_sigaction
 
5942
    case TARGET_NR_sigaction:
 
5943
        {
 
5944
#if defined(TARGET_ALPHA)
 
5945
            struct target_sigaction act, oact, *pact = 0;
 
5946
            struct target_old_sigaction *old_act;
 
5947
            if (arg2) {
 
5948
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
 
5949
                    goto efault;
 
5950
                act._sa_handler = old_act->_sa_handler;
 
5951
                target_siginitset(&act.sa_mask, old_act->sa_mask);
 
5952
                act.sa_flags = old_act->sa_flags;
 
5953
                act.sa_restorer = 0;
 
5954
                unlock_user_struct(old_act, arg2, 0);
 
5955
                pact = &act;
 
5956
            }
 
5957
            ret = get_errno(do_sigaction(arg1, pact, &oact));
 
5958
            if (!is_error(ret) && arg3) {
 
5959
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
 
5960
                    goto efault;
 
5961
                old_act->_sa_handler = oact._sa_handler;
 
5962
                old_act->sa_mask = oact.sa_mask.sig[0];
 
5963
                old_act->sa_flags = oact.sa_flags;
 
5964
                unlock_user_struct(old_act, arg3, 1);
 
5965
            }
 
5966
#elif defined(TARGET_MIPS)
 
5967
            struct target_sigaction act, oact, *pact, *old_act;
 
5968
 
 
5969
            if (arg2) {
 
5970
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
 
5971
                    goto efault;
 
5972
                act._sa_handler = old_act->_sa_handler;
 
5973
                target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
 
5974
                act.sa_flags = old_act->sa_flags;
 
5975
                unlock_user_struct(old_act, arg2, 0);
 
5976
                pact = &act;
 
5977
            } else {
 
5978
                pact = NULL;
 
5979
            }
 
5980
 
 
5981
            ret = get_errno(do_sigaction(arg1, pact, &oact));
 
5982
 
 
5983
            if (!is_error(ret) && arg3) {
 
5984
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
 
5985
                    goto efault;
 
5986
                old_act->_sa_handler = oact._sa_handler;
 
5987
                old_act->sa_flags = oact.sa_flags;
 
5988
                old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
 
5989
                old_act->sa_mask.sig[1] = 0;
 
5990
                old_act->sa_mask.sig[2] = 0;
 
5991
                old_act->sa_mask.sig[3] = 0;
 
5992
                unlock_user_struct(old_act, arg3, 1);
 
5993
            }
 
5994
#else
 
5995
            struct target_old_sigaction *old_act;
 
5996
            struct target_sigaction act, oact, *pact;
 
5997
            if (arg2) {
 
5998
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
 
5999
                    goto efault;
 
6000
                act._sa_handler = old_act->_sa_handler;
 
6001
                target_siginitset(&act.sa_mask, old_act->sa_mask);
 
6002
                act.sa_flags = old_act->sa_flags;
 
6003
                act.sa_restorer = old_act->sa_restorer;
 
6004
                unlock_user_struct(old_act, arg2, 0);
 
6005
                pact = &act;
 
6006
            } else {
 
6007
                pact = NULL;
 
6008
            }
 
6009
            ret = get_errno(do_sigaction(arg1, pact, &oact));
 
6010
            if (!is_error(ret) && arg3) {
 
6011
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
 
6012
                    goto efault;
 
6013
                old_act->_sa_handler = oact._sa_handler;
 
6014
                old_act->sa_mask = oact.sa_mask.sig[0];
 
6015
                old_act->sa_flags = oact.sa_flags;
 
6016
                old_act->sa_restorer = oact.sa_restorer;
 
6017
                unlock_user_struct(old_act, arg3, 1);
 
6018
            }
 
6019
#endif
 
6020
        }
 
6021
        break;
 
6022
#endif
 
6023
    case TARGET_NR_rt_sigaction:
 
6024
        {
 
6025
#if defined(TARGET_ALPHA)
 
6026
            struct target_sigaction act, oact, *pact = 0;
 
6027
            struct target_rt_sigaction *rt_act;
 
6028
            /* ??? arg4 == sizeof(sigset_t).  */
 
6029
            if (arg2) {
 
6030
                if (!lock_user_struct(VERIFY_READ, rt_act, arg2, 1))
 
6031
                    goto efault;
 
6032
                act._sa_handler = rt_act->_sa_handler;
 
6033
                act.sa_mask = rt_act->sa_mask;
 
6034
                act.sa_flags = rt_act->sa_flags;
 
6035
                act.sa_restorer = arg5;
 
6036
                unlock_user_struct(rt_act, arg2, 0);
 
6037
                pact = &act;
 
6038
            }
 
6039
            ret = get_errno(do_sigaction(arg1, pact, &oact));
 
6040
            if (!is_error(ret) && arg3) {
 
6041
                if (!lock_user_struct(VERIFY_WRITE, rt_act, arg3, 0))
 
6042
                    goto efault;
 
6043
                rt_act->_sa_handler = oact._sa_handler;
 
6044
                rt_act->sa_mask = oact.sa_mask;
 
6045
                rt_act->sa_flags = oact.sa_flags;
 
6046
                unlock_user_struct(rt_act, arg3, 1);
 
6047
            }
 
6048
#else
 
6049
            struct target_sigaction *act;
 
6050
            struct target_sigaction *oact;
 
6051
 
 
6052
            if (arg2) {
 
6053
                if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
 
6054
                    goto efault;
 
6055
            } else
 
6056
                act = NULL;
 
6057
            if (arg3) {
 
6058
                if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
 
6059
                    ret = -TARGET_EFAULT;
 
6060
                    goto rt_sigaction_fail;
 
6061
                }
 
6062
            } else
 
6063
                oact = NULL;
 
6064
            ret = get_errno(do_sigaction(arg1, act, oact));
 
6065
        rt_sigaction_fail:
 
6066
            if (act)
 
6067
                unlock_user_struct(act, arg2, 0);
 
6068
            if (oact)
 
6069
                unlock_user_struct(oact, arg3, 1);
 
6070
#endif
 
6071
        }
 
6072
        break;
 
6073
#ifdef TARGET_NR_sgetmask /* not on alpha */
 
6074
    case TARGET_NR_sgetmask:
 
6075
        {
 
6076
            sigset_t cur_set;
 
6077
            abi_ulong target_set;
 
6078
            sigprocmask(0, NULL, &cur_set);
 
6079
            host_to_target_old_sigset(&target_set, &cur_set);
 
6080
            ret = target_set;
 
6081
        }
 
6082
        break;
 
6083
#endif
 
6084
#ifdef TARGET_NR_ssetmask /* not on alpha */
 
6085
    case TARGET_NR_ssetmask:
 
6086
        {
 
6087
            sigset_t set, oset, cur_set;
 
6088
            abi_ulong target_set = arg1;
 
6089
            sigprocmask(0, NULL, &cur_set);
 
6090
            target_to_host_old_sigset(&set, &target_set);
 
6091
            sigorset(&set, &set, &cur_set);
 
6092
            sigprocmask(SIG_SETMASK, &set, &oset);
 
6093
            host_to_target_old_sigset(&target_set, &oset);
 
6094
            ret = target_set;
 
6095
        }
 
6096
        break;
 
6097
#endif
 
6098
#ifdef TARGET_NR_sigprocmask
 
6099
    case TARGET_NR_sigprocmask:
 
6100
        {
 
6101
#if defined(TARGET_ALPHA)
 
6102
            sigset_t set, oldset;
 
6103
            abi_ulong mask;
 
6104
            int how;
 
6105
 
 
6106
            switch (arg1) {
 
6107
            case TARGET_SIG_BLOCK:
 
6108
                how = SIG_BLOCK;
 
6109
                break;
 
6110
            case TARGET_SIG_UNBLOCK:
 
6111
                how = SIG_UNBLOCK;
 
6112
                break;
 
6113
            case TARGET_SIG_SETMASK:
 
6114
                how = SIG_SETMASK;
 
6115
                break;
 
6116
            default:
 
6117
                ret = -TARGET_EINVAL;
 
6118
                goto fail;
 
6119
            }
 
6120
            mask = arg2;
 
6121
            target_to_host_old_sigset(&set, &mask);
 
6122
 
 
6123
            ret = get_errno(sigprocmask(how, &set, &oldset));
 
6124
            if (!is_error(ret)) {
 
6125
                host_to_target_old_sigset(&mask, &oldset);
 
6126
                ret = mask;
 
6127
                ((CPUAlphaState *)cpu_env)->ir[IR_V0] = 0; /* force no error */
 
6128
            }
 
6129
#else
 
6130
            sigset_t set, oldset, *set_ptr;
 
6131
            int how;
 
6132
 
 
6133
            if (arg2) {
 
6134
                switch (arg1) {
 
6135
                case TARGET_SIG_BLOCK:
 
6136
                    how = SIG_BLOCK;
 
6137
                    break;
 
6138
                case TARGET_SIG_UNBLOCK:
 
6139
                    how = SIG_UNBLOCK;
 
6140
                    break;
 
6141
                case TARGET_SIG_SETMASK:
 
6142
                    how = SIG_SETMASK;
 
6143
                    break;
 
6144
                default:
 
6145
                    ret = -TARGET_EINVAL;
 
6146
                    goto fail;
 
6147
                }
 
6148
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
 
6149
                    goto efault;
 
6150
                target_to_host_old_sigset(&set, p);
 
6151
                unlock_user(p, arg2, 0);
 
6152
                set_ptr = &set;
 
6153
            } else {
 
6154
                how = 0;
 
6155
                set_ptr = NULL;
 
6156
            }
 
6157
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
 
6158
            if (!is_error(ret) && arg3) {
 
6159
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
 
6160
                    goto efault;
 
6161
                host_to_target_old_sigset(p, &oldset);
 
6162
                unlock_user(p, arg3, sizeof(target_sigset_t));
 
6163
            }
 
6164
#endif
 
6165
        }
 
6166
        break;
 
6167
#endif
 
6168
    case TARGET_NR_rt_sigprocmask:
 
6169
        {
 
6170
            int how = arg1;
 
6171
            sigset_t set, oldset, *set_ptr;
 
6172
 
 
6173
            if (arg2) {
 
6174
                switch(how) {
 
6175
                case TARGET_SIG_BLOCK:
 
6176
                    how = SIG_BLOCK;
 
6177
                    break;
 
6178
                case TARGET_SIG_UNBLOCK:
 
6179
                    how = SIG_UNBLOCK;
 
6180
                    break;
 
6181
                case TARGET_SIG_SETMASK:
 
6182
                    how = SIG_SETMASK;
 
6183
                    break;
 
6184
                default:
 
6185
                    ret = -TARGET_EINVAL;
 
6186
                    goto fail;
 
6187
                }
 
6188
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
 
6189
                    goto efault;
 
6190
                target_to_host_sigset(&set, p);
 
6191
                unlock_user(p, arg2, 0);
 
6192
                set_ptr = &set;
 
6193
            } else {
 
6194
                how = 0;
 
6195
                set_ptr = NULL;
 
6196
            }
 
6197
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
 
6198
            if (!is_error(ret) && arg3) {
 
6199
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
 
6200
                    goto efault;
 
6201
                host_to_target_sigset(p, &oldset);
 
6202
                unlock_user(p, arg3, sizeof(target_sigset_t));
 
6203
            }
 
6204
        }
 
6205
        break;
 
6206
#ifdef TARGET_NR_sigpending
 
6207
    case TARGET_NR_sigpending:
 
6208
        {
 
6209
            sigset_t set;
 
6210
            ret = get_errno(sigpending(&set));
 
6211
            if (!is_error(ret)) {
 
6212
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
 
6213
                    goto efault;
 
6214
                host_to_target_old_sigset(p, &set);
 
6215
                unlock_user(p, arg1, sizeof(target_sigset_t));
 
6216
            }
 
6217
        }
 
6218
        break;
 
6219
#endif
 
6220
    case TARGET_NR_rt_sigpending:
 
6221
        {
 
6222
            sigset_t set;
 
6223
            ret = get_errno(sigpending(&set));
 
6224
            if (!is_error(ret)) {
 
6225
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
 
6226
                    goto efault;
 
6227
                host_to_target_sigset(p, &set);
 
6228
                unlock_user(p, arg1, sizeof(target_sigset_t));
 
6229
            }
 
6230
        }
 
6231
        break;
 
6232
#ifdef TARGET_NR_sigsuspend
 
6233
    case TARGET_NR_sigsuspend:
 
6234
        {
 
6235
            sigset_t set;
 
6236
#if defined(TARGET_ALPHA)
 
6237
            abi_ulong mask = arg1;
 
6238
            target_to_host_old_sigset(&set, &mask);
 
6239
#else
 
6240
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
 
6241
                goto efault;
 
6242
            target_to_host_old_sigset(&set, p);
 
6243
            unlock_user(p, arg1, 0);
 
6244
#endif
 
6245
            ret = get_errno(sigsuspend(&set));
 
6246
        }
 
6247
        break;
 
6248
#endif
 
6249
    case TARGET_NR_rt_sigsuspend:
 
6250
        {
 
6251
            sigset_t set;
 
6252
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
 
6253
                goto efault;
 
6254
            target_to_host_sigset(&set, p);
 
6255
            unlock_user(p, arg1, 0);
 
6256
            ret = get_errno(sigsuspend(&set));
 
6257
        }
 
6258
        break;
 
6259
    case TARGET_NR_rt_sigtimedwait:
 
6260
        {
 
6261
            sigset_t set;
 
6262
            struct timespec uts, *puts;
 
6263
            siginfo_t uinfo;
 
6264
 
 
6265
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
 
6266
                goto efault;
 
6267
            target_to_host_sigset(&set, p);
 
6268
            unlock_user(p, arg1, 0);
 
6269
            if (arg3) {
 
6270
                puts = &uts;
 
6271
                target_to_host_timespec(puts, arg3);
 
6272
            } else {
 
6273
                puts = NULL;
 
6274
            }
 
6275
            ret = get_errno(sigtimedwait(&set, &uinfo, puts));
 
6276
            if (!is_error(ret) && arg2) {
 
6277
                if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
 
6278
                    goto efault;
 
6279
                host_to_target_siginfo(p, &uinfo);
 
6280
                unlock_user(p, arg2, sizeof(target_siginfo_t));
 
6281
            }
 
6282
        }
 
6283
        break;
 
6284
    case TARGET_NR_rt_sigqueueinfo:
 
6285
        {
 
6286
            siginfo_t uinfo;
 
6287
            if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
 
6288
                goto efault;
 
6289
            target_to_host_siginfo(&uinfo, p);
 
6290
            unlock_user(p, arg1, 0);
 
6291
            ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
 
6292
        }
 
6293
        break;
 
6294
#ifdef TARGET_NR_sigreturn
 
6295
    case TARGET_NR_sigreturn:
 
6296
        /* NOTE: ret is eax, so not transcoding must be done */
 
6297
        ret = do_sigreturn(cpu_env);
 
6298
        break;
 
6299
#endif
 
6300
    case TARGET_NR_rt_sigreturn:
 
6301
        /* NOTE: ret is eax, so not transcoding must be done */
 
6302
        ret = do_rt_sigreturn(cpu_env);
 
6303
        break;
 
6304
    case TARGET_NR_sethostname:
 
6305
        if (!(p = lock_user_string(arg1)))
 
6306
            goto efault;
 
6307
        ret = get_errno(sethostname(p, arg2));
 
6308
        unlock_user(p, arg1, 0);
 
6309
        break;
 
6310
    case TARGET_NR_setrlimit:
 
6311
        {
 
6312
            int resource = target_to_host_resource(arg1);
 
6313
            struct target_rlimit *target_rlim;
 
6314
            struct rlimit rlim;
 
6315
            if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
 
6316
                goto efault;
 
6317
            rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur);
 
6318
            rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max);
 
6319
            unlock_user_struct(target_rlim, arg2, 0);
 
6320
            ret = get_errno(setrlimit(resource, &rlim));
 
6321
        }
 
6322
        break;
 
6323
    case TARGET_NR_getrlimit:
 
6324
        {
 
6325
            int resource = target_to_host_resource(arg1);
 
6326
            struct target_rlimit *target_rlim;
 
6327
            struct rlimit rlim;
 
6328
 
 
6329
            ret = get_errno(getrlimit(resource, &rlim));
 
6330
            if (!is_error(ret)) {
 
6331
                if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
 
6332
                    goto efault;
 
6333
                target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
 
6334
                target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
 
6335
                unlock_user_struct(target_rlim, arg2, 1);
 
6336
            }
 
6337
        }
 
6338
        break;
 
6339
    case TARGET_NR_getrusage:
 
6340
        {
 
6341
            struct rusage rusage;
 
6342
            ret = get_errno(getrusage(arg1, &rusage));
 
6343
            if (!is_error(ret)) {
 
6344
                host_to_target_rusage(arg2, &rusage);
 
6345
            }
 
6346
        }
 
6347
        break;
 
6348
    case TARGET_NR_gettimeofday:
 
6349
        {
 
6350
            struct timeval tv;
 
6351
            ret = get_errno(gettimeofday(&tv, NULL));
 
6352
            if (!is_error(ret)) {
 
6353
                if (copy_to_user_timeval(arg1, &tv))
 
6354
                    goto efault;
 
6355
            }
 
6356
        }
 
6357
        break;
 
6358
    case TARGET_NR_settimeofday:
 
6359
        {
 
6360
            struct timeval tv;
 
6361
            if (copy_from_user_timeval(&tv, arg1))
 
6362
                goto efault;
 
6363
            ret = get_errno(settimeofday(&tv, NULL));
 
6364
        }
 
6365
        break;
 
6366
#if defined(TARGET_NR_select)
 
6367
    case TARGET_NR_select:
 
6368
#if defined(TARGET_S390X) || defined(TARGET_ALPHA)
 
6369
        ret = do_select(arg1, arg2, arg3, arg4, arg5);
 
6370
#else
 
6371
        {
 
6372
            struct target_sel_arg_struct *sel;
 
6373
            abi_ulong inp, outp, exp, tvp;
 
6374
            long nsel;
 
6375
 
 
6376
            if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
 
6377
                goto efault;
 
6378
            nsel = tswapal(sel->n);
 
6379
            inp = tswapal(sel->inp);
 
6380
            outp = tswapal(sel->outp);
 
6381
            exp = tswapal(sel->exp);
 
6382
            tvp = tswapal(sel->tvp);
 
6383
            unlock_user_struct(sel, arg1, 0);
 
6384
            ret = do_select(nsel, inp, outp, exp, tvp);
 
6385
        }
 
6386
#endif
 
6387
        break;
 
6388
#endif
 
6389
#ifdef TARGET_NR_pselect6
 
6390
    case TARGET_NR_pselect6:
 
6391
        {
 
6392
            abi_long rfd_addr, wfd_addr, efd_addr, n, ts_addr;
 
6393
            fd_set rfds, wfds, efds;
 
6394
            fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
 
6395
            struct timespec ts, *ts_ptr;
 
6396
 
 
6397
            /*
 
6398
             * The 6th arg is actually two args smashed together,
 
6399
             * so we cannot use the C library.
 
6400
             */
 
6401
            sigset_t set;
 
6402
            struct {
 
6403
                sigset_t *set;
 
6404
                size_t size;
 
6405
            } sig, *sig_ptr;
 
6406
 
 
6407
            abi_ulong arg_sigset, arg_sigsize, *arg7;
 
6408
            target_sigset_t *target_sigset;
 
6409
 
 
6410
            n = arg1;
 
6411
            rfd_addr = arg2;
 
6412
            wfd_addr = arg3;
 
6413
            efd_addr = arg4;
 
6414
            ts_addr = arg5;
 
6415
 
 
6416
            ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
 
6417
            if (ret) {
 
6418
                goto fail;
 
6419
            }
 
6420
            ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
 
6421
            if (ret) {
 
6422
                goto fail;
 
6423
            }
 
6424
            ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
 
6425
            if (ret) {
 
6426
                goto fail;
 
6427
            }
 
6428
 
 
6429
            /*
 
6430
             * This takes a timespec, and not a timeval, so we cannot
 
6431
             * use the do_select() helper ...
 
6432
             */
 
6433
            if (ts_addr) {
 
6434
                if (target_to_host_timespec(&ts, ts_addr)) {
 
6435
                    goto efault;
 
6436
                }
 
6437
                ts_ptr = &ts;
 
6438
            } else {
 
6439
                ts_ptr = NULL;
 
6440
            }
 
6441
 
 
6442
            /* Extract the two packed args for the sigset */
 
6443
            if (arg6) {
 
6444
                sig_ptr = &sig;
 
6445
                sig.size = _NSIG / 8;
 
6446
 
 
6447
                arg7 = lock_user(VERIFY_READ, arg6, sizeof(*arg7) * 2, 1);
 
6448
                if (!arg7) {
 
6449
                    goto efault;
 
6450
                }
 
6451
                arg_sigset = tswapal(arg7[0]);
 
6452
                arg_sigsize = tswapal(arg7[1]);
 
6453
                unlock_user(arg7, arg6, 0);
 
6454
 
 
6455
                if (arg_sigset) {
 
6456
                    sig.set = &set;
 
6457
                    if (arg_sigsize != sizeof(*target_sigset)) {
 
6458
                        /* Like the kernel, we enforce correct size sigsets */
 
6459
                        ret = -TARGET_EINVAL;
 
6460
                        goto fail;
 
6461
                    }
 
6462
                    target_sigset = lock_user(VERIFY_READ, arg_sigset,
 
6463
                                              sizeof(*target_sigset), 1);
 
6464
                    if (!target_sigset) {
 
6465
                        goto efault;
 
6466
                    }
 
6467
                    target_to_host_sigset(&set, target_sigset);
 
6468
                    unlock_user(target_sigset, arg_sigset, 0);
 
6469
                } else {
 
6470
                    sig.set = NULL;
 
6471
                }
 
6472
            } else {
 
6473
                sig_ptr = NULL;
 
6474
            }
 
6475
 
 
6476
            ret = get_errno(sys_pselect6(n, rfds_ptr, wfds_ptr, efds_ptr,
 
6477
                                         ts_ptr, sig_ptr));
 
6478
 
 
6479
            if (!is_error(ret)) {
 
6480
                if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
 
6481
                    goto efault;
 
6482
                if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
 
6483
                    goto efault;
 
6484
                if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
 
6485
                    goto efault;
 
6486
 
 
6487
                if (ts_addr && host_to_target_timespec(ts_addr, &ts))
 
6488
                    goto efault;
 
6489
            }
 
6490
        }
 
6491
        break;
 
6492
#endif
 
6493
    case TARGET_NR_symlink:
 
6494
        {
 
6495
            void *p2;
 
6496
            p = lock_user_string(arg1);
 
6497
            p2 = lock_user_string(arg2);
 
6498
            if (!p || !p2)
 
6499
                ret = -TARGET_EFAULT;
 
6500
            else
 
6501
                ret = get_errno(symlink(p, p2));
 
6502
            unlock_user(p2, arg2, 0);
 
6503
            unlock_user(p, arg1, 0);
 
6504
        }
 
6505
        break;
 
6506
#if defined(TARGET_NR_symlinkat)
 
6507
    case TARGET_NR_symlinkat:
 
6508
        {
 
6509
            void *p2;
 
6510
            p  = lock_user_string(arg1);
 
6511
            p2 = lock_user_string(arg3);
 
6512
            if (!p || !p2)
 
6513
                ret = -TARGET_EFAULT;
 
6514
            else
 
6515
                ret = get_errno(symlinkat(p, arg2, p2));
 
6516
            unlock_user(p2, arg3, 0);
 
6517
            unlock_user(p, arg1, 0);
 
6518
        }
 
6519
        break;
 
6520
#endif
 
6521
#ifdef TARGET_NR_oldlstat
 
6522
    case TARGET_NR_oldlstat:
 
6523
        goto unimplemented;
 
6524
#endif
 
6525
    case TARGET_NR_readlink:
 
6526
        {
 
6527
            void *p2;
 
6528
            p = lock_user_string(arg1);
 
6529
            p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
 
6530
            if (!p || !p2) {
 
6531
                ret = -TARGET_EFAULT;
 
6532
            } else if (is_proc_myself((const char *)p, "exe")) {
 
6533
                char real[PATH_MAX], *temp;
 
6534
                temp = realpath(exec_path, real);
 
6535
                ret = temp == NULL ? get_errno(-1) : strlen(real) ;
 
6536
                snprintf((char *)p2, arg3, "%s", real);
 
6537
            } else {
 
6538
                ret = get_errno(readlink(path(p), p2, arg3));
 
6539
            }
 
6540
            unlock_user(p2, arg2, ret);
 
6541
            unlock_user(p, arg1, 0);
 
6542
        }
 
6543
        break;
 
6544
#if defined(TARGET_NR_readlinkat)
 
6545
    case TARGET_NR_readlinkat:
 
6546
        {
 
6547
            void *p2;
 
6548
            p  = lock_user_string(arg2);
 
6549
            p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
 
6550
            if (!p || !p2) {
 
6551
                ret = -TARGET_EFAULT;
 
6552
            } else if (is_proc_myself((const char *)p, "exe")) {
 
6553
                char real[PATH_MAX], *temp;
 
6554
                temp = realpath(exec_path, real);
 
6555
                ret = temp == NULL ? get_errno(-1) : strlen(real) ;
 
6556
                snprintf((char *)p2, arg4, "%s", real);
 
6557
            } else {
 
6558
                ret = get_errno(readlinkat(arg1, path(p), p2, arg4));
 
6559
            }
 
6560
            unlock_user(p2, arg3, ret);
 
6561
            unlock_user(p, arg2, 0);
 
6562
        }
 
6563
        break;
 
6564
#endif
 
6565
#ifdef TARGET_NR_uselib
 
6566
    case TARGET_NR_uselib:
 
6567
        goto unimplemented;
 
6568
#endif
 
6569
#ifdef TARGET_NR_swapon
 
6570
    case TARGET_NR_swapon:
 
6571
        if (!(p = lock_user_string(arg1)))
 
6572
            goto efault;
 
6573
        ret = get_errno(swapon(p, arg2));
 
6574
        unlock_user(p, arg1, 0);
 
6575
        break;
 
6576
#endif
 
6577
    case TARGET_NR_reboot:
 
6578
        if (arg3 == LINUX_REBOOT_CMD_RESTART2) {
 
6579
           /* arg4 must be ignored in all other cases */
 
6580
           p = lock_user_string(arg4);
 
6581
           if (!p) {
 
6582
              goto efault;
 
6583
           }
 
6584
           ret = get_errno(reboot(arg1, arg2, arg3, p));
 
6585
           unlock_user(p, arg4, 0);
 
6586
        } else {
 
6587
           ret = get_errno(reboot(arg1, arg2, arg3, NULL));
 
6588
        }
 
6589
        break;
 
6590
#ifdef TARGET_NR_readdir
 
6591
    case TARGET_NR_readdir:
 
6592
        goto unimplemented;
 
6593
#endif
 
6594
#ifdef TARGET_NR_mmap
 
6595
    case TARGET_NR_mmap:
 
6596
#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || \
 
6597
    (defined(TARGET_ARM) && defined(TARGET_ABI32)) || \
 
6598
    defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) \
 
6599
    || defined(TARGET_S390X)
 
6600
        {
 
6601
            abi_ulong *v;
 
6602
            abi_ulong v1, v2, v3, v4, v5, v6;
 
6603
            if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
 
6604
                goto efault;
 
6605
            v1 = tswapal(v[0]);
 
6606
            v2 = tswapal(v[1]);
 
6607
            v3 = tswapal(v[2]);
 
6608
            v4 = tswapal(v[3]);
 
6609
            v5 = tswapal(v[4]);
 
6610
            v6 = tswapal(v[5]);
 
6611
            unlock_user(v, arg1, 0);
 
6612
            ret = get_errno(target_mmap(v1, v2, v3,
 
6613
                                        target_to_host_bitmask(v4, mmap_flags_tbl),
 
6614
                                        v5, v6));
 
6615
        }
 
6616
#else
 
6617
        ret = get_errno(target_mmap(arg1, arg2, arg3,
 
6618
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
 
6619
                                    arg5,
 
6620
                                    arg6));
 
6621
#endif
 
6622
        break;
 
6623
#endif
 
6624
#ifdef TARGET_NR_mmap2
 
6625
    case TARGET_NR_mmap2:
 
6626
#ifndef MMAP_SHIFT
 
6627
#define MMAP_SHIFT 12
 
6628
#endif
 
6629
        ret = get_errno(target_mmap(arg1, arg2, arg3,
 
6630
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
 
6631
                                    arg5,
 
6632
                                    arg6 << MMAP_SHIFT));
 
6633
        break;
 
6634
#endif
 
6635
    case TARGET_NR_munmap:
 
6636
        ret = get_errno(target_munmap(arg1, arg2));
 
6637
        break;
 
6638
    case TARGET_NR_mprotect:
 
6639
        {
 
6640
            TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
 
6641
            /* Special hack to detect libc making the stack executable.  */
 
6642
            if ((arg3 & PROT_GROWSDOWN)
 
6643
                && arg1 >= ts->info->stack_limit
 
6644
                && arg1 <= ts->info->start_stack) {
 
6645
                arg3 &= ~PROT_GROWSDOWN;
 
6646
                arg2 = arg2 + arg1 - ts->info->stack_limit;
 
6647
                arg1 = ts->info->stack_limit;
 
6648
            }
 
6649
        }
 
6650
        ret = get_errno(target_mprotect(arg1, arg2, arg3));
 
6651
        break;
 
6652
#ifdef TARGET_NR_mremap
 
6653
    case TARGET_NR_mremap:
 
6654
        ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
 
6655
        break;
 
6656
#endif
 
6657
        /* ??? msync/mlock/munlock are broken for softmmu.  */
 
6658
#ifdef TARGET_NR_msync
 
6659
    case TARGET_NR_msync:
 
6660
        ret = get_errno(msync(g2h(arg1), arg2, arg3));
 
6661
        break;
 
6662
#endif
 
6663
#ifdef TARGET_NR_mlock
 
6664
    case TARGET_NR_mlock:
 
6665
        ret = get_errno(mlock(g2h(arg1), arg2));
 
6666
        break;
 
6667
#endif
 
6668
#ifdef TARGET_NR_munlock
 
6669
    case TARGET_NR_munlock:
 
6670
        ret = get_errno(munlock(g2h(arg1), arg2));
 
6671
        break;
 
6672
#endif
 
6673
#ifdef TARGET_NR_mlockall
 
6674
    case TARGET_NR_mlockall:
 
6675
        ret = get_errno(mlockall(arg1));
 
6676
        break;
 
6677
#endif
 
6678
#ifdef TARGET_NR_munlockall
 
6679
    case TARGET_NR_munlockall:
 
6680
        ret = get_errno(munlockall());
 
6681
        break;
 
6682
#endif
 
6683
    case TARGET_NR_truncate:
 
6684
        if (!(p = lock_user_string(arg1)))
 
6685
            goto efault;
 
6686
        ret = get_errno(truncate(p, arg2));
 
6687
        unlock_user(p, arg1, 0);
 
6688
        break;
 
6689
    case TARGET_NR_ftruncate:
 
6690
        ret = get_errno(ftruncate(arg1, arg2));
 
6691
        break;
 
6692
    case TARGET_NR_fchmod:
 
6693
        ret = get_errno(fchmod(arg1, arg2));
 
6694
        break;
 
6695
#if defined(TARGET_NR_fchmodat)
 
6696
    case TARGET_NR_fchmodat:
 
6697
        if (!(p = lock_user_string(arg2)))
 
6698
            goto efault;
 
6699
        ret = get_errno(fchmodat(arg1, p, arg3, 0));
 
6700
        unlock_user(p, arg2, 0);
 
6701
        break;
 
6702
#endif
 
6703
    case TARGET_NR_getpriority:
 
6704
        /* Note that negative values are valid for getpriority, so we must
 
6705
           differentiate based on errno settings.  */
 
6706
        errno = 0;
 
6707
        ret = getpriority(arg1, arg2);
 
6708
        if (ret == -1 && errno != 0) {
 
6709
            ret = -host_to_target_errno(errno);
 
6710
            break;
 
6711
        }
 
6712
#ifdef TARGET_ALPHA
 
6713
        /* Return value is the unbiased priority.  Signal no error.  */
 
6714
        ((CPUAlphaState *)cpu_env)->ir[IR_V0] = 0;
 
6715
#else
 
6716
        /* Return value is a biased priority to avoid negative numbers.  */
 
6717
        ret = 20 - ret;
 
6718
#endif
 
6719
        break;
 
6720
    case TARGET_NR_setpriority:
 
6721
        ret = get_errno(setpriority(arg1, arg2, arg3));
 
6722
        break;
 
6723
#ifdef TARGET_NR_profil
 
6724
    case TARGET_NR_profil:
 
6725
        goto unimplemented;
 
6726
#endif
 
6727
    case TARGET_NR_statfs:
 
6728
        if (!(p = lock_user_string(arg1)))
 
6729
            goto efault;
 
6730
        ret = get_errno(statfs(path(p), &stfs));
 
6731
        unlock_user(p, arg1, 0);
 
6732
    convert_statfs:
 
6733
        if (!is_error(ret)) {
 
6734
            struct target_statfs *target_stfs;
 
6735
 
 
6736
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
 
6737
                goto efault;
 
6738
            __put_user(stfs.f_type, &target_stfs->f_type);
 
6739
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
 
6740
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
 
6741
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
 
6742
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
 
6743
            __put_user(stfs.f_files, &target_stfs->f_files);
 
6744
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
 
6745
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
 
6746
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
 
6747
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
 
6748
            __put_user(stfs.f_frsize, &target_stfs->f_frsize);
 
6749
            memset(target_stfs->f_spare, 0, sizeof(target_stfs->f_spare));
 
6750
            unlock_user_struct(target_stfs, arg2, 1);
 
6751
        }
 
6752
        break;
 
6753
    case TARGET_NR_fstatfs:
 
6754
        ret = get_errno(fstatfs(arg1, &stfs));
 
6755
        goto convert_statfs;
 
6756
#ifdef TARGET_NR_statfs64
 
6757
    case TARGET_NR_statfs64:
 
6758
        if (!(p = lock_user_string(arg1)))
 
6759
            goto efault;
 
6760
        ret = get_errno(statfs(path(p), &stfs));
 
6761
        unlock_user(p, arg1, 0);
 
6762
    convert_statfs64:
 
6763
        if (!is_error(ret)) {
 
6764
            struct target_statfs64 *target_stfs;
 
6765
 
 
6766
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
 
6767
                goto efault;
 
6768
            __put_user(stfs.f_type, &target_stfs->f_type);
 
6769
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
 
6770
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
 
6771
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
 
6772
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
 
6773
            __put_user(stfs.f_files, &target_stfs->f_files);
 
6774
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
 
6775
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
 
6776
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
 
6777
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
 
6778
            __put_user(stfs.f_frsize, &target_stfs->f_frsize);
 
6779
            memset(target_stfs->f_spare, 0, sizeof(target_stfs->f_spare));
 
6780
            unlock_user_struct(target_stfs, arg3, 1);
 
6781
        }
 
6782
        break;
 
6783
    case TARGET_NR_fstatfs64:
 
6784
        ret = get_errno(fstatfs(arg1, &stfs));
 
6785
        goto convert_statfs64;
 
6786
#endif
 
6787
#ifdef TARGET_NR_ioperm
 
6788
    case TARGET_NR_ioperm:
 
6789
        goto unimplemented;
 
6790
#endif
 
6791
#ifdef TARGET_NR_socketcall
 
6792
    case TARGET_NR_socketcall:
 
6793
        ret = do_socketcall(arg1, arg2);
 
6794
        break;
 
6795
#endif
 
6796
#ifdef TARGET_NR_accept
 
6797
    case TARGET_NR_accept:
 
6798
        ret = do_accept4(arg1, arg2, arg3, 0);
 
6799
        break;
 
6800
#endif
 
6801
#ifdef TARGET_NR_accept4
 
6802
    case TARGET_NR_accept4:
 
6803
#ifdef CONFIG_ACCEPT4
 
6804
        ret = do_accept4(arg1, arg2, arg3, arg4);
 
6805
#else
 
6806
        goto unimplemented;
 
6807
#endif
 
6808
        break;
 
6809
#endif
 
6810
#ifdef TARGET_NR_bind
 
6811
    case TARGET_NR_bind:
 
6812
        ret = do_bind(arg1, arg2, arg3);
 
6813
        break;
 
6814
#endif
 
6815
#ifdef TARGET_NR_connect
 
6816
    case TARGET_NR_connect:
 
6817
        ret = do_connect(arg1, arg2, arg3);
 
6818
        break;
 
6819
#endif
 
6820
#ifdef TARGET_NR_getpeername
 
6821
    case TARGET_NR_getpeername:
 
6822
        ret = do_getpeername(arg1, arg2, arg3);
 
6823
        break;
 
6824
#endif
 
6825
#ifdef TARGET_NR_getsockname
 
6826
    case TARGET_NR_getsockname:
 
6827
        ret = do_getsockname(arg1, arg2, arg3);
 
6828
        break;
 
6829
#endif
 
6830
#ifdef TARGET_NR_getsockopt
 
6831
    case TARGET_NR_getsockopt:
 
6832
        ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
 
6833
        break;
 
6834
#endif
 
6835
#ifdef TARGET_NR_listen
 
6836
    case TARGET_NR_listen:
 
6837
        ret = get_errno(listen(arg1, arg2));
 
6838
        break;
 
6839
#endif
 
6840
#ifdef TARGET_NR_recv
 
6841
    case TARGET_NR_recv:
 
6842
        ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
 
6843
        break;
 
6844
#endif
 
6845
#ifdef TARGET_NR_recvfrom
 
6846
    case TARGET_NR_recvfrom:
 
6847
        ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
 
6848
        break;
 
6849
#endif
 
6850
#ifdef TARGET_NR_recvmsg
 
6851
    case TARGET_NR_recvmsg:
 
6852
        ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
 
6853
        break;
 
6854
#endif
 
6855
#ifdef TARGET_NR_send
 
6856
    case TARGET_NR_send:
 
6857
        ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
 
6858
        break;
 
6859
#endif
 
6860
#ifdef TARGET_NR_sendmsg
 
6861
    case TARGET_NR_sendmsg:
 
6862
        ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
 
6863
        break;
 
6864
#endif
 
6865
#ifdef TARGET_NR_sendmmsg
 
6866
    case TARGET_NR_sendmmsg:
 
6867
        ret = do_sendmmsg(arg1, arg2, arg3, arg4);
 
6868
        break;
 
6869
#endif
 
6870
#ifdef TARGET_NR_sendto
 
6871
    case TARGET_NR_sendto:
 
6872
        ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
 
6873
        break;
 
6874
#endif
 
6875
#ifdef TARGET_NR_shutdown
 
6876
    case TARGET_NR_shutdown:
 
6877
        ret = get_errno(shutdown(arg1, arg2));
 
6878
        break;
 
6879
#endif
 
6880
#ifdef TARGET_NR_socket
 
6881
    case TARGET_NR_socket:
 
6882
        ret = do_socket(arg1, arg2, arg3);
 
6883
        break;
 
6884
#endif
 
6885
#ifdef TARGET_NR_socketpair
 
6886
    case TARGET_NR_socketpair:
 
6887
        ret = do_socketpair(arg1, arg2, arg3, arg4);
 
6888
        break;
 
6889
#endif
 
6890
#ifdef TARGET_NR_setsockopt
 
6891
    case TARGET_NR_setsockopt:
 
6892
        ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
 
6893
        break;
 
6894
#endif
 
6895
 
 
6896
    case TARGET_NR_syslog:
 
6897
        if (!(p = lock_user_string(arg2)))
 
6898
            goto efault;
 
6899
        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
 
6900
        unlock_user(p, arg2, 0);
 
6901
        break;
 
6902
 
 
6903
    case TARGET_NR_setitimer:
 
6904
        {
 
6905
            struct itimerval value, ovalue, *pvalue;
 
6906
 
 
6907
            if (arg2) {
 
6908
                pvalue = &value;
 
6909
                if (copy_from_user_timeval(&pvalue->it_interval, arg2)
 
6910
                    || copy_from_user_timeval(&pvalue->it_value,
 
6911
                                              arg2 + sizeof(struct target_timeval)))
 
6912
                    goto efault;
 
6913
            } else {
 
6914
                pvalue = NULL;
 
6915
            }
 
6916
            ret = get_errno(setitimer(arg1, pvalue, &ovalue));
 
6917
            if (!is_error(ret) && arg3) {
 
6918
                if (copy_to_user_timeval(arg3,
 
6919
                                         &ovalue.it_interval)
 
6920
                    || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
 
6921
                                            &ovalue.it_value))
 
6922
                    goto efault;
 
6923
            }
 
6924
        }
 
6925
        break;
 
6926
    case TARGET_NR_getitimer:
 
6927
        {
 
6928
            struct itimerval value;
 
6929
 
 
6930
            ret = get_errno(getitimer(arg1, &value));
 
6931
            if (!is_error(ret) && arg2) {
 
6932
                if (copy_to_user_timeval(arg2,
 
6933
                                         &value.it_interval)
 
6934
                    || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
 
6935
                                            &value.it_value))
 
6936
                    goto efault;
 
6937
            }
 
6938
        }
 
6939
        break;
 
6940
    case TARGET_NR_stat:
 
6941
        if (!(p = lock_user_string(arg1)))
 
6942
            goto efault;
 
6943
        ret = get_errno(stat(path(p), &st));
 
6944
        unlock_user(p, arg1, 0);
 
6945
        goto do_stat;
 
6946
    case TARGET_NR_lstat:
 
6947
        if (!(p = lock_user_string(arg1)))
 
6948
            goto efault;
 
6949
        ret = get_errno(lstat(path(p), &st));
 
6950
        unlock_user(p, arg1, 0);
 
6951
        goto do_stat;
 
6952
    case TARGET_NR_fstat:
 
6953
        {
 
6954
            ret = get_errno(fstat(arg1, &st));
 
6955
        do_stat:
 
6956
            if (!is_error(ret)) {
 
6957
                struct target_stat *target_st;
 
6958
 
 
6959
                if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
 
6960
                    goto efault;
 
6961
                memset(target_st, 0, sizeof(*target_st));
 
6962
                __put_user(st.st_dev, &target_st->st_dev);
 
6963
                __put_user(st.st_ino, &target_st->st_ino);
 
6964
                __put_user(st.st_mode, &target_st->st_mode);
 
6965
                __put_user(st.st_uid, &target_st->st_uid);
 
6966
                __put_user(st.st_gid, &target_st->st_gid);
 
6967
                __put_user(st.st_nlink, &target_st->st_nlink);
 
6968
                __put_user(st.st_rdev, &target_st->st_rdev);
 
6969
                __put_user(st.st_size, &target_st->st_size);
 
6970
                __put_user(st.st_blksize, &target_st->st_blksize);
 
6971
                __put_user(st.st_blocks, &target_st->st_blocks);
 
6972
                __put_user(st.st_atime, &target_st->target_st_atime);
 
6973
                __put_user(st.st_mtime, &target_st->target_st_mtime);
 
6974
                __put_user(st.st_ctime, &target_st->target_st_ctime);
 
6975
                unlock_user_struct(target_st, arg2, 1);
 
6976
            }
 
6977
        }
 
6978
        break;
 
6979
#ifdef TARGET_NR_olduname
 
6980
    case TARGET_NR_olduname:
 
6981
        goto unimplemented;
 
6982
#endif
 
6983
#ifdef TARGET_NR_iopl
 
6984
    case TARGET_NR_iopl:
 
6985
        goto unimplemented;
 
6986
#endif
 
6987
    case TARGET_NR_vhangup:
 
6988
        ret = get_errno(vhangup());
 
6989
        break;
 
6990
#ifdef TARGET_NR_idle
 
6991
    case TARGET_NR_idle:
 
6992
        goto unimplemented;
 
6993
#endif
 
6994
#ifdef TARGET_NR_syscall
 
6995
    case TARGET_NR_syscall:
 
6996
        ret = do_syscall(cpu_env, arg1 & 0xffff, arg2, arg3, arg4, arg5,
 
6997
                         arg6, arg7, arg8, 0);
 
6998
        break;
 
6999
#endif
 
7000
    case TARGET_NR_wait4:
 
7001
        {
 
7002
            int status;
 
7003
            abi_long status_ptr = arg2;
 
7004
            struct rusage rusage, *rusage_ptr;
 
7005
            abi_ulong target_rusage = arg4;
 
7006
            if (target_rusage)
 
7007
                rusage_ptr = &rusage;
 
7008
            else
 
7009
                rusage_ptr = NULL;
 
7010
            ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
 
7011
            if (!is_error(ret)) {
 
7012
                if (status_ptr && ret) {
 
7013
                    status = host_to_target_waitstatus(status);
 
7014
                    if (put_user_s32(status, status_ptr))
 
7015
                        goto efault;
 
7016
                }
 
7017
                if (target_rusage)
 
7018
                    host_to_target_rusage(target_rusage, &rusage);
 
7019
            }
 
7020
        }
 
7021
        break;
 
7022
#ifdef TARGET_NR_swapoff
 
7023
    case TARGET_NR_swapoff:
 
7024
        if (!(p = lock_user_string(arg1)))
 
7025
            goto efault;
 
7026
        ret = get_errno(swapoff(p));
 
7027
        unlock_user(p, arg1, 0);
 
7028
        break;
 
7029
#endif
 
7030
    case TARGET_NR_sysinfo:
 
7031
        {
 
7032
            struct target_sysinfo *target_value;
 
7033
            struct sysinfo value;
 
7034
            ret = get_errno(sysinfo(&value));
 
7035
            if (!is_error(ret) && arg1)
 
7036
            {
 
7037
                if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
 
7038
                    goto efault;
 
7039
                __put_user(value.uptime, &target_value->uptime);
 
7040
                __put_user(value.loads[0], &target_value->loads[0]);
 
7041
                __put_user(value.loads[1], &target_value->loads[1]);
 
7042
                __put_user(value.loads[2], &target_value->loads[2]);
 
7043
                __put_user(value.totalram, &target_value->totalram);
 
7044
                __put_user(value.freeram, &target_value->freeram);
 
7045
                __put_user(value.sharedram, &target_value->sharedram);
 
7046
                __put_user(value.bufferram, &target_value->bufferram);
 
7047
                __put_user(value.totalswap, &target_value->totalswap);
 
7048
                __put_user(value.freeswap, &target_value->freeswap);
 
7049
                __put_user(value.procs, &target_value->procs);
 
7050
                __put_user(value.totalhigh, &target_value->totalhigh);
 
7051
                __put_user(value.freehigh, &target_value->freehigh);
 
7052
                __put_user(value.mem_unit, &target_value->mem_unit);
 
7053
                unlock_user_struct(target_value, arg1, 1);
 
7054
            }
 
7055
        }
 
7056
        break;
 
7057
#ifdef TARGET_NR_ipc
 
7058
    case TARGET_NR_ipc:
 
7059
        ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
 
7060
        break;
 
7061
#endif
 
7062
#ifdef TARGET_NR_semget
 
7063
    case TARGET_NR_semget:
 
7064
        ret = get_errno(semget(arg1, arg2, arg3));
 
7065
        break;
 
7066
#endif
 
7067
#ifdef TARGET_NR_semop
 
7068
    case TARGET_NR_semop:
 
7069
        ret = do_semop(arg1, arg2, arg3);
 
7070
        break;
 
7071
#endif
 
7072
#ifdef TARGET_NR_semctl
 
7073
    case TARGET_NR_semctl:
 
7074
        ret = do_semctl(arg1, arg2, arg3, (union target_semun)(abi_ulong)arg4);
 
7075
        break;
 
7076
#endif
 
7077
#ifdef TARGET_NR_msgctl
 
7078
    case TARGET_NR_msgctl:
 
7079
        ret = do_msgctl(arg1, arg2, arg3);
 
7080
        break;
 
7081
#endif
 
7082
#ifdef TARGET_NR_msgget
 
7083
    case TARGET_NR_msgget:
 
7084
        ret = get_errno(msgget(arg1, arg2));
 
7085
        break;
 
7086
#endif
 
7087
#ifdef TARGET_NR_msgrcv
 
7088
    case TARGET_NR_msgrcv:
 
7089
        ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
 
7090
        break;
 
7091
#endif
 
7092
#ifdef TARGET_NR_msgsnd
 
7093
    case TARGET_NR_msgsnd:
 
7094
        ret = do_msgsnd(arg1, arg2, arg3, arg4);
 
7095
        break;
 
7096
#endif
 
7097
#ifdef TARGET_NR_shmget
 
7098
    case TARGET_NR_shmget:
 
7099
        ret = get_errno(shmget(arg1, arg2, arg3));
 
7100
        break;
 
7101
#endif
 
7102
#ifdef TARGET_NR_shmctl
 
7103
    case TARGET_NR_shmctl:
 
7104
        ret = do_shmctl(arg1, arg2, arg3);
 
7105
        break;
 
7106
#endif
 
7107
#ifdef TARGET_NR_shmat
 
7108
    case TARGET_NR_shmat:
 
7109
        ret = do_shmat(arg1, arg2, arg3);
 
7110
        break;
 
7111
#endif
 
7112
#ifdef TARGET_NR_shmdt
 
7113
    case TARGET_NR_shmdt:
 
7114
        ret = do_shmdt(arg1);
 
7115
        break;
 
7116
#endif
 
7117
    case TARGET_NR_fsync:
 
7118
        ret = get_errno(fsync(arg1));
 
7119
        break;
 
7120
    case TARGET_NR_clone:
 
7121
        /* Linux manages to have three different orderings for its
 
7122
         * arguments to clone(); the BACKWARDS and BACKWARDS2 defines
 
7123
         * match the kernel's CONFIG_CLONE_* settings.
 
7124
         * Microblaze is further special in that it uses a sixth
 
7125
         * implicit argument to clone for the TLS pointer.
 
7126
         */
 
7127
#if defined(TARGET_MICROBLAZE)
 
7128
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg4, arg6, arg5));
 
7129
#elif defined(TARGET_CLONE_BACKWARDS)
 
7130
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
 
7131
#elif defined(TARGET_CLONE_BACKWARDS2)
 
7132
        ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg5, arg4));
 
7133
#else
 
7134
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
 
7135
#endif
 
7136
        break;
 
7137
#ifdef __NR_exit_group
 
7138
        /* new thread calls */
 
7139
    case TARGET_NR_exit_group:
 
7140
#ifdef TARGET_GPROF
 
7141
        _mcleanup();
 
7142
#endif
 
7143
        gdb_exit(cpu_env, arg1);
 
7144
        ret = get_errno(exit_group(arg1));
 
7145
        break;
 
7146
#endif
 
7147
    case TARGET_NR_setdomainname:
 
7148
        if (!(p = lock_user_string(arg1)))
 
7149
            goto efault;
 
7150
        ret = get_errno(setdomainname(p, arg2));
 
7151
        unlock_user(p, arg1, 0);
 
7152
        break;
 
7153
    case TARGET_NR_uname:
 
7154
        /* no need to transcode because we use the linux syscall */
 
7155
        {
 
7156
            struct new_utsname * buf;
 
7157
 
 
7158
            if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
 
7159
                goto efault;
 
7160
            ret = get_errno(sys_uname(buf));
 
7161
            if (!is_error(ret)) {
 
7162
                /* Overrite the native machine name with whatever is being
 
7163
                   emulated. */
 
7164
                strcpy (buf->machine, cpu_to_uname_machine(cpu_env));
 
7165
                /* Allow the user to override the reported release.  */
 
7166
                if (qemu_uname_release && *qemu_uname_release)
 
7167
                  strcpy (buf->release, qemu_uname_release);
 
7168
            }
 
7169
            unlock_user_struct(buf, arg1, 1);
 
7170
        }
 
7171
        break;
 
7172
#ifdef TARGET_I386
 
7173
    case TARGET_NR_modify_ldt:
 
7174
        ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
 
7175
        break;
 
7176
#if !defined(TARGET_X86_64)
 
7177
    case TARGET_NR_vm86old:
 
7178
        goto unimplemented;
 
7179
    case TARGET_NR_vm86:
 
7180
        ret = do_vm86(cpu_env, arg1, arg2);
 
7181
        break;
 
7182
#endif
 
7183
#endif
 
7184
    case TARGET_NR_adjtimex:
 
7185
        goto unimplemented;
 
7186
#ifdef TARGET_NR_create_module
 
7187
    case TARGET_NR_create_module:
 
7188
#endif
 
7189
    case TARGET_NR_init_module:
 
7190
    case TARGET_NR_delete_module:
 
7191
#ifdef TARGET_NR_get_kernel_syms
 
7192
    case TARGET_NR_get_kernel_syms:
 
7193
#endif
 
7194
        goto unimplemented;
 
7195
    case TARGET_NR_quotactl:
 
7196
        goto unimplemented;
 
7197
    case TARGET_NR_getpgid:
 
7198
        ret = get_errno(getpgid(arg1));
 
7199
        break;
 
7200
    case TARGET_NR_fchdir:
 
7201
        ret = get_errno(fchdir(arg1));
 
7202
        break;
 
7203
#ifdef TARGET_NR_bdflush /* not on x86_64 */
 
7204
    case TARGET_NR_bdflush:
 
7205
        goto unimplemented;
 
7206
#endif
 
7207
#ifdef TARGET_NR_sysfs
 
7208
    case TARGET_NR_sysfs:
 
7209
        goto unimplemented;
 
7210
#endif
 
7211
    case TARGET_NR_personality:
 
7212
        ret = get_errno(personality(arg1));
 
7213
        break;
 
7214
#ifdef TARGET_NR_afs_syscall
 
7215
    case TARGET_NR_afs_syscall:
 
7216
        goto unimplemented;
 
7217
#endif
 
7218
#ifdef TARGET_NR__llseek /* Not on alpha */
 
7219
    case TARGET_NR__llseek:
 
7220
        {
 
7221
            int64_t res;
 
7222
#if !defined(__NR_llseek)
 
7223
            res = lseek(arg1, ((uint64_t)arg2 << 32) | arg3, arg5);
 
7224
            if (res == -1) {
 
7225
                ret = get_errno(res);
 
7226
            } else {
 
7227
                ret = 0;
 
7228
            }
 
7229
#else
 
7230
            ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
 
7231
#endif
 
7232
            if ((ret == 0) && put_user_s64(res, arg4)) {
 
7233
                goto efault;
 
7234
            }
 
7235
        }
 
7236
        break;
 
7237
#endif
 
7238
    case TARGET_NR_getdents:
 
7239
#ifdef __NR_getdents
 
7240
#if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
 
7241
        {
 
7242
            struct target_dirent *target_dirp;
 
7243
            struct linux_dirent *dirp;
 
7244
            abi_long count = arg3;
 
7245
 
 
7246
            dirp = malloc(count);
 
7247
            if (!dirp) {
 
7248
                ret = -TARGET_ENOMEM;
 
7249
                goto fail;
 
7250
            }
 
7251
 
 
7252
            ret = get_errno(sys_getdents(arg1, dirp, count));
 
7253
            if (!is_error(ret)) {
 
7254
                struct linux_dirent *de;
 
7255
                struct target_dirent *tde;
 
7256
                int len = ret;
 
7257
                int reclen, treclen;
 
7258
                int count1, tnamelen;
 
7259
 
 
7260
                count1 = 0;
 
7261
                de = dirp;
 
7262
                if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
 
7263
                    goto efault;
 
7264
                tde = target_dirp;
 
7265
                while (len > 0) {
 
7266
                    reclen = de->d_reclen;
 
7267
                    tnamelen = reclen - offsetof(struct linux_dirent, d_name);
 
7268
                    assert(tnamelen >= 0);
 
7269
                    treclen = tnamelen + offsetof(struct target_dirent, d_name);
 
7270
                    assert(count1 + treclen <= count);
 
7271
                    tde->d_reclen = tswap16(treclen);
 
7272
                    tde->d_ino = tswapal(de->d_ino);
 
7273
                    tde->d_off = tswapal(de->d_off);
 
7274
                    memcpy(tde->d_name, de->d_name, tnamelen);
 
7275
                    de = (struct linux_dirent *)((char *)de + reclen);
 
7276
                    len -= reclen;
 
7277
                    tde = (struct target_dirent *)((char *)tde + treclen);
 
7278
                    count1 += treclen;
 
7279
                }
 
7280
                ret = count1;
 
7281
                unlock_user(target_dirp, arg2, ret);
 
7282
            }
 
7283
            free(dirp);
 
7284
        }
 
7285
#else
 
7286
        {
 
7287
            struct linux_dirent *dirp;
 
7288
            abi_long count = arg3;
 
7289
 
 
7290
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
 
7291
                goto efault;
 
7292
            ret = get_errno(sys_getdents(arg1, dirp, count));
 
7293
            if (!is_error(ret)) {
 
7294
                struct linux_dirent *de;
 
7295
                int len = ret;
 
7296
                int reclen;
 
7297
                de = dirp;
 
7298
                while (len > 0) {
 
7299
                    reclen = de->d_reclen;
 
7300
                    if (reclen > len)
 
7301
                        break;
 
7302
                    de->d_reclen = tswap16(reclen);
 
7303
                    tswapls(&de->d_ino);
 
7304
                    tswapls(&de->d_off);
 
7305
                    de = (struct linux_dirent *)((char *)de + reclen);
 
7306
                    len -= reclen;
 
7307
                }
 
7308
            }
 
7309
            unlock_user(dirp, arg2, ret);
 
7310
        }
 
7311
#endif
 
7312
#else
 
7313
        /* Implement getdents in terms of getdents64 */
 
7314
        {
 
7315
            struct linux_dirent64 *dirp;
 
7316
            abi_long count = arg3;
 
7317
 
 
7318
            dirp = lock_user(VERIFY_WRITE, arg2, count, 0);
 
7319
            if (!dirp) {
 
7320
                goto efault;
 
7321
            }
 
7322
            ret = get_errno(sys_getdents64(arg1, dirp, count));
 
7323
            if (!is_error(ret)) {
 
7324
                /* Convert the dirent64 structs to target dirent.  We do this
 
7325
                 * in-place, since we can guarantee that a target_dirent is no
 
7326
                 * larger than a dirent64; however this means we have to be
 
7327
                 * careful to read everything before writing in the new format.
 
7328
                 */
 
7329
                struct linux_dirent64 *de;
 
7330
                struct target_dirent *tde;
 
7331
                int len = ret;
 
7332
                int tlen = 0;
 
7333
 
 
7334
                de = dirp;
 
7335
                tde = (struct target_dirent *)dirp;
 
7336
                while (len > 0) {
 
7337
                    int namelen, treclen;
 
7338
                    int reclen = de->d_reclen;
 
7339
                    uint64_t ino = de->d_ino;
 
7340
                    int64_t off = de->d_off;
 
7341
                    uint8_t type = de->d_type;
 
7342
 
 
7343
                    namelen = strlen(de->d_name);
 
7344
                    treclen = offsetof(struct target_dirent, d_name)
 
7345
                        + namelen + 2;
 
7346
                    treclen = QEMU_ALIGN_UP(treclen, sizeof(abi_long));
 
7347
 
 
7348
                    memmove(tde->d_name, de->d_name, namelen + 1);
 
7349
                    tde->d_ino = tswapal(ino);
 
7350
                    tde->d_off = tswapal(off);
 
7351
                    tde->d_reclen = tswap16(treclen);
 
7352
                    /* The target_dirent type is in what was formerly a padding
 
7353
                     * byte at the end of the structure:
 
7354
                     */
 
7355
                    *(((char *)tde) + treclen - 1) = type;
 
7356
 
 
7357
                    de = (struct linux_dirent64 *)((char *)de + reclen);
 
7358
                    tde = (struct target_dirent *)((char *)tde + treclen);
 
7359
                    len -= reclen;
 
7360
                    tlen += treclen;
 
7361
                }
 
7362
                ret = tlen;
 
7363
            }
 
7364
            unlock_user(dirp, arg2, ret);
 
7365
        }
 
7366
#endif
 
7367
        break;
 
7368
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
 
7369
    case TARGET_NR_getdents64:
 
7370
        {
 
7371
            struct linux_dirent64 *dirp;
 
7372
            abi_long count = arg3;
 
7373
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
 
7374
                goto efault;
 
7375
            ret = get_errno(sys_getdents64(arg1, dirp, count));
 
7376
            if (!is_error(ret)) {
 
7377
                struct linux_dirent64 *de;
 
7378
                int len = ret;
 
7379
                int reclen;
 
7380
                de = dirp;
 
7381
                while (len > 0) {
 
7382
                    reclen = de->d_reclen;
 
7383
                    if (reclen > len)
 
7384
                        break;
 
7385
                    de->d_reclen = tswap16(reclen);
 
7386
                    tswap64s((uint64_t *)&de->d_ino);
 
7387
                    tswap64s((uint64_t *)&de->d_off);
 
7388
                    de = (struct linux_dirent64 *)((char *)de + reclen);
 
7389
                    len -= reclen;
 
7390
                }
 
7391
            }
 
7392
            unlock_user(dirp, arg2, ret);
 
7393
        }
 
7394
        break;
 
7395
#endif /* TARGET_NR_getdents64 */
 
7396
#if defined(TARGET_NR__newselect)
 
7397
    case TARGET_NR__newselect:
 
7398
        ret = do_select(arg1, arg2, arg3, arg4, arg5);
 
7399
        break;
 
7400
#endif
 
7401
#if defined(TARGET_NR_poll) || defined(TARGET_NR_ppoll)
 
7402
# ifdef TARGET_NR_poll
 
7403
    case TARGET_NR_poll:
 
7404
# endif
 
7405
# ifdef TARGET_NR_ppoll
 
7406
    case TARGET_NR_ppoll:
 
7407
# endif
 
7408
        {
 
7409
            struct target_pollfd *target_pfd;
 
7410
            unsigned int nfds = arg2;
 
7411
            int timeout = arg3;
 
7412
            struct pollfd *pfd;
 
7413
            unsigned int i;
 
7414
 
 
7415
            target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
 
7416
            if (!target_pfd)
 
7417
                goto efault;
 
7418
 
 
7419
            pfd = alloca(sizeof(struct pollfd) * nfds);
 
7420
            for(i = 0; i < nfds; i++) {
 
7421
                pfd[i].fd = tswap32(target_pfd[i].fd);
 
7422
                pfd[i].events = tswap16(target_pfd[i].events);
 
7423
            }
 
7424
 
 
7425
# ifdef TARGET_NR_ppoll
 
7426
            if (num == TARGET_NR_ppoll) {
 
7427
                struct timespec _timeout_ts, *timeout_ts = &_timeout_ts;
 
7428
                target_sigset_t *target_set;
 
7429
                sigset_t _set, *set = &_set;
 
7430
 
 
7431
                if (arg3) {
 
7432
                    if (target_to_host_timespec(timeout_ts, arg3)) {
 
7433
                        unlock_user(target_pfd, arg1, 0);
 
7434
                        goto efault;
 
7435
                    }
 
7436
                } else {
 
7437
                    timeout_ts = NULL;
 
7438
                }
 
7439
 
 
7440
                if (arg4) {
 
7441
                    target_set = lock_user(VERIFY_READ, arg4, sizeof(target_sigset_t), 1);
 
7442
                    if (!target_set) {
 
7443
                        unlock_user(target_pfd, arg1, 0);
 
7444
                        goto efault;
 
7445
                    }
 
7446
                    target_to_host_sigset(set, target_set);
 
7447
                } else {
 
7448
                    set = NULL;
 
7449
                }
 
7450
 
 
7451
                ret = get_errno(sys_ppoll(pfd, nfds, timeout_ts, set, _NSIG/8));
 
7452
 
 
7453
                if (!is_error(ret) && arg3) {
 
7454
                    host_to_target_timespec(arg3, timeout_ts);
 
7455
                }
 
7456
                if (arg4) {
 
7457
                    unlock_user(target_set, arg4, 0);
 
7458
                }
 
7459
            } else
 
7460
# endif
 
7461
                ret = get_errno(poll(pfd, nfds, timeout));
 
7462
 
 
7463
            if (!is_error(ret)) {
 
7464
                for(i = 0; i < nfds; i++) {
 
7465
                    target_pfd[i].revents = tswap16(pfd[i].revents);
 
7466
                }
 
7467
            }
 
7468
            unlock_user(target_pfd, arg1, sizeof(struct target_pollfd) * nfds);
 
7469
        }
 
7470
        break;
 
7471
#endif
 
7472
    case TARGET_NR_flock:
 
7473
        /* NOTE: the flock constant seems to be the same for every
 
7474
           Linux platform */
 
7475
        ret = get_errno(flock(arg1, arg2));
 
7476
        break;
 
7477
    case TARGET_NR_readv:
 
7478
        {
 
7479
            struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 0);
 
7480
            if (vec != NULL) {
 
7481
                ret = get_errno(readv(arg1, vec, arg3));
 
7482
                unlock_iovec(vec, arg2, arg3, 1);
 
7483
            } else {
 
7484
                ret = -host_to_target_errno(errno);
 
7485
            }
 
7486
        }
 
7487
        break;
 
7488
    case TARGET_NR_writev:
 
7489
        {
 
7490
            struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
 
7491
            if (vec != NULL) {
 
7492
                ret = get_errno(writev(arg1, vec, arg3));
 
7493
                unlock_iovec(vec, arg2, arg3, 0);
 
7494
            } else {
 
7495
                ret = -host_to_target_errno(errno);
 
7496
            }
 
7497
        }
 
7498
        break;
 
7499
    case TARGET_NR_getsid:
 
7500
        ret = get_errno(getsid(arg1));
 
7501
        break;
 
7502
#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
 
7503
    case TARGET_NR_fdatasync:
 
7504
        ret = get_errno(fdatasync(arg1));
 
7505
        break;
 
7506
#endif
 
7507
    case TARGET_NR__sysctl:
 
7508
        /* We don't implement this, but ENOTDIR is always a safe
 
7509
           return value. */
 
7510
        ret = -TARGET_ENOTDIR;
 
7511
        break;
 
7512
    case TARGET_NR_sched_getaffinity:
 
7513
        {
 
7514
            unsigned int mask_size;
 
7515
            unsigned long *mask;
 
7516
 
 
7517
            /*
 
7518
             * sched_getaffinity needs multiples of ulong, so need to take
 
7519
             * care of mismatches between target ulong and host ulong sizes.
 
7520
             */
 
7521
            if (arg2 & (sizeof(abi_ulong) - 1)) {
 
7522
                ret = -TARGET_EINVAL;
 
7523
                break;
 
7524
            }
 
7525
            mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
 
7526
 
 
7527
            mask = alloca(mask_size);
 
7528
            ret = get_errno(sys_sched_getaffinity(arg1, mask_size, mask));
 
7529
 
 
7530
            if (!is_error(ret)) {
 
7531
                if (copy_to_user(arg3, mask, ret)) {
 
7532
                    goto efault;
 
7533
                }
 
7534
            }
 
7535
        }
 
7536
        break;
 
7537
    case TARGET_NR_sched_setaffinity:
 
7538
        {
 
7539
            unsigned int mask_size;
 
7540
            unsigned long *mask;
 
7541
 
 
7542
            /*
 
7543
             * sched_setaffinity needs multiples of ulong, so need to take
 
7544
             * care of mismatches between target ulong and host ulong sizes.
 
7545
             */
 
7546
            if (arg2 & (sizeof(abi_ulong) - 1)) {
 
7547
                ret = -TARGET_EINVAL;
 
7548
                break;
 
7549
            }
 
7550
            mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
 
7551
 
 
7552
            mask = alloca(mask_size);
 
7553
            if (!lock_user_struct(VERIFY_READ, p, arg3, 1)) {
 
7554
                goto efault;
 
7555
            }
 
7556
            memcpy(mask, p, arg2);
 
7557
            unlock_user_struct(p, arg2, 0);
 
7558
 
 
7559
            ret = get_errno(sys_sched_setaffinity(arg1, mask_size, mask));
 
7560
        }
 
7561
        break;
 
7562
    case TARGET_NR_sched_setparam:
 
7563
        {
 
7564
            struct sched_param *target_schp;
 
7565
            struct sched_param schp;
 
7566
 
 
7567
            if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
 
7568
                goto efault;
 
7569
            schp.sched_priority = tswap32(target_schp->sched_priority);
 
7570
            unlock_user_struct(target_schp, arg2, 0);
 
7571
            ret = get_errno(sched_setparam(arg1, &schp));
 
7572
        }
 
7573
        break;
 
7574
    case TARGET_NR_sched_getparam:
 
7575
        {
 
7576
            struct sched_param *target_schp;
 
7577
            struct sched_param schp;
 
7578
            ret = get_errno(sched_getparam(arg1, &schp));
 
7579
            if (!is_error(ret)) {
 
7580
                if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
 
7581
                    goto efault;
 
7582
                target_schp->sched_priority = tswap32(schp.sched_priority);
 
7583
                unlock_user_struct(target_schp, arg2, 1);
 
7584
            }
 
7585
        }
 
7586
        break;
 
7587
    case TARGET_NR_sched_setscheduler:
 
7588
        {
 
7589
            struct sched_param *target_schp;
 
7590
            struct sched_param schp;
 
7591
            if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
 
7592
                goto efault;
 
7593
            schp.sched_priority = tswap32(target_schp->sched_priority);
 
7594
            unlock_user_struct(target_schp, arg3, 0);
 
7595
            ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
 
7596
        }
 
7597
        break;
 
7598
    case TARGET_NR_sched_getscheduler:
 
7599
        ret = get_errno(sched_getscheduler(arg1));
 
7600
        break;
 
7601
    case TARGET_NR_sched_yield:
 
7602
        ret = get_errno(sched_yield());
 
7603
        break;
 
7604
    case TARGET_NR_sched_get_priority_max:
 
7605
        ret = get_errno(sched_get_priority_max(arg1));
 
7606
        break;
 
7607
    case TARGET_NR_sched_get_priority_min:
 
7608
        ret = get_errno(sched_get_priority_min(arg1));
 
7609
        break;
 
7610
    case TARGET_NR_sched_rr_get_interval:
 
7611
        {
 
7612
            struct timespec ts;
 
7613
            ret = get_errno(sched_rr_get_interval(arg1, &ts));
 
7614
            if (!is_error(ret)) {
 
7615
                host_to_target_timespec(arg2, &ts);
 
7616
            }
 
7617
        }
 
7618
        break;
 
7619
    case TARGET_NR_nanosleep:
 
7620
        {
 
7621
            struct timespec req, rem;
 
7622
            target_to_host_timespec(&req, arg1);
 
7623
            ret = get_errno(nanosleep(&req, &rem));
 
7624
            if (is_error(ret) && arg2) {
 
7625
                host_to_target_timespec(arg2, &rem);
 
7626
            }
 
7627
        }
 
7628
        break;
 
7629
#ifdef TARGET_NR_query_module
 
7630
    case TARGET_NR_query_module:
 
7631
        goto unimplemented;
 
7632
#endif
 
7633
#ifdef TARGET_NR_nfsservctl
 
7634
    case TARGET_NR_nfsservctl:
 
7635
        goto unimplemented;
 
7636
#endif
 
7637
    case TARGET_NR_prctl:
 
7638
        switch (arg1) {
 
7639
        case PR_GET_PDEATHSIG:
 
7640
        {
 
7641
            int deathsig;
 
7642
            ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
 
7643
            if (!is_error(ret) && arg2
 
7644
                && put_user_ual(deathsig, arg2)) {
 
7645
                goto efault;
 
7646
            }
 
7647
            break;
 
7648
        }
 
7649
#ifdef PR_GET_NAME
 
7650
        case PR_GET_NAME:
 
7651
        {
 
7652
            void *name = lock_user(VERIFY_WRITE, arg2, 16, 1);
 
7653
            if (!name) {
 
7654
                goto efault;
 
7655
            }
 
7656
            ret = get_errno(prctl(arg1, (unsigned long)name,
 
7657
                                  arg3, arg4, arg5));
 
7658
            unlock_user(name, arg2, 16);
 
7659
            break;
 
7660
        }
 
7661
        case PR_SET_NAME:
 
7662
        {
 
7663
            void *name = lock_user(VERIFY_READ, arg2, 16, 1);
 
7664
            if (!name) {
 
7665
                goto efault;
 
7666
            }
 
7667
            ret = get_errno(prctl(arg1, (unsigned long)name,
 
7668
                                  arg3, arg4, arg5));
 
7669
            unlock_user(name, arg2, 0);
 
7670
            break;
 
7671
        }
 
7672
#endif
 
7673
        default:
 
7674
            /* Most prctl options have no pointer arguments */
 
7675
            ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
 
7676
            break;
 
7677
        }
 
7678
        break;
 
7679
#ifdef TARGET_NR_arch_prctl
 
7680
    case TARGET_NR_arch_prctl:
 
7681
#if defined(TARGET_I386) && !defined(TARGET_ABI32)
 
7682
        ret = do_arch_prctl(cpu_env, arg1, arg2);
 
7683
        break;
 
7684
#else
 
7685
        goto unimplemented;
 
7686
#endif
 
7687
#endif
 
7688
#ifdef TARGET_NR_pread64
 
7689
    case TARGET_NR_pread64:
 
7690
        if (regpairs_aligned(cpu_env)) {
 
7691
            arg4 = arg5;
 
7692
            arg5 = arg6;
 
7693
        }
 
7694
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
 
7695
            goto efault;
 
7696
        ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
 
7697
        unlock_user(p, arg2, ret);
 
7698
        break;
 
7699
    case TARGET_NR_pwrite64:
 
7700
        if (regpairs_aligned(cpu_env)) {
 
7701
            arg4 = arg5;
 
7702
            arg5 = arg6;
 
7703
        }
 
7704
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
 
7705
            goto efault;
 
7706
        ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
 
7707
        unlock_user(p, arg2, 0);
 
7708
        break;
 
7709
#endif
 
7710
    case TARGET_NR_getcwd:
 
7711
        if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
 
7712
            goto efault;
 
7713
        ret = get_errno(sys_getcwd1(p, arg2));
 
7714
        unlock_user(p, arg1, ret);
 
7715
        break;
 
7716
    case TARGET_NR_capget:
 
7717
        goto unimplemented;
 
7718
    case TARGET_NR_capset:
 
7719
        goto unimplemented;
 
7720
    case TARGET_NR_sigaltstack:
 
7721
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
 
7722
    defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA) || \
 
7723
    defined(TARGET_M68K) || defined(TARGET_S390X) || defined(TARGET_OPENRISC)
 
7724
        ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUArchState *)cpu_env));
 
7725
        break;
 
7726
#else
 
7727
        goto unimplemented;
 
7728
#endif
 
7729
 
 
7730
#ifdef CONFIG_SENDFILE
 
7731
    case TARGET_NR_sendfile:
 
7732
    {
 
7733
        off_t *offp = NULL;
 
7734
        off_t off;
 
7735
        if (arg3) {
 
7736
            ret = get_user_sal(off, arg3);
 
7737
            if (is_error(ret)) {
 
7738
                break;
 
7739
            }
 
7740
            offp = &off;
 
7741
        }
 
7742
        ret = get_errno(sendfile(arg1, arg2, offp, arg4));
 
7743
        if (!is_error(ret) && arg3) {
 
7744
            abi_long ret2 = put_user_sal(off, arg3);
 
7745
            if (is_error(ret2)) {
 
7746
                ret = ret2;
 
7747
            }
 
7748
        }
 
7749
        break;
 
7750
    }
 
7751
#ifdef TARGET_NR_sendfile64
 
7752
    case TARGET_NR_sendfile64:
 
7753
    {
 
7754
        off_t *offp = NULL;
 
7755
        off_t off;
 
7756
        if (arg3) {
 
7757
            ret = get_user_s64(off, arg3);
 
7758
            if (is_error(ret)) {
 
7759
                break;
 
7760
            }
 
7761
            offp = &off;
 
7762
        }
 
7763
        ret = get_errno(sendfile(arg1, arg2, offp, arg4));
 
7764
        if (!is_error(ret) && arg3) {
 
7765
            abi_long ret2 = put_user_s64(off, arg3);
 
7766
            if (is_error(ret2)) {
 
7767
                ret = ret2;
 
7768
            }
 
7769
        }
 
7770
        break;
 
7771
    }
 
7772
#endif
 
7773
#else
 
7774
    case TARGET_NR_sendfile:
 
7775
#ifdef TARGET_NR_sendfile64
 
7776
    case TARGET_NR_sendfile64:
 
7777
#endif
 
7778
        goto unimplemented;
 
7779
#endif
 
7780
 
 
7781
#ifdef TARGET_NR_getpmsg
 
7782
    case TARGET_NR_getpmsg:
 
7783
        goto unimplemented;
 
7784
#endif
 
7785
#ifdef TARGET_NR_putpmsg
 
7786
    case TARGET_NR_putpmsg:
 
7787
        goto unimplemented;
 
7788
#endif
 
7789
#ifdef TARGET_NR_vfork
 
7790
    case TARGET_NR_vfork:
 
7791
        ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
 
7792
                        0, 0, 0, 0));
 
7793
        break;
 
7794
#endif
 
7795
#ifdef TARGET_NR_ugetrlimit
 
7796
    case TARGET_NR_ugetrlimit:
 
7797
    {
 
7798
        struct rlimit rlim;
 
7799
        int resource = target_to_host_resource(arg1);
 
7800
        ret = get_errno(getrlimit(resource, &rlim));
 
7801
        if (!is_error(ret)) {
 
7802
            struct target_rlimit *target_rlim;
 
7803
            if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
 
7804
                goto efault;
 
7805
            target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
 
7806
            target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
 
7807
            unlock_user_struct(target_rlim, arg2, 1);
 
7808
        }
 
7809
        break;
 
7810
    }
 
7811
#endif
 
7812
#ifdef TARGET_NR_truncate64
 
7813
    case TARGET_NR_truncate64:
 
7814
        if (!(p = lock_user_string(arg1)))
 
7815
            goto efault;
 
7816
        ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
 
7817
        unlock_user(p, arg1, 0);
 
7818
        break;
 
7819
#endif
 
7820
#ifdef TARGET_NR_ftruncate64
 
7821
    case TARGET_NR_ftruncate64:
 
7822
        ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
 
7823
        break;
 
7824
#endif
 
7825
#ifdef TARGET_NR_stat64
 
7826
    case TARGET_NR_stat64:
 
7827
        if (!(p = lock_user_string(arg1)))
 
7828
            goto efault;
 
7829
        ret = get_errno(stat(path(p), &st));
 
7830
        unlock_user(p, arg1, 0);
 
7831
        if (!is_error(ret))
 
7832
            ret = host_to_target_stat64(cpu_env, arg2, &st);
 
7833
        break;
 
7834
#endif
 
7835
#ifdef TARGET_NR_lstat64
 
7836
    case TARGET_NR_lstat64:
 
7837
        if (!(p = lock_user_string(arg1)))
 
7838
            goto efault;
 
7839
        ret = get_errno(lstat(path(p), &st));
 
7840
        unlock_user(p, arg1, 0);
 
7841
        if (!is_error(ret))
 
7842
            ret = host_to_target_stat64(cpu_env, arg2, &st);
 
7843
        break;
 
7844
#endif
 
7845
#ifdef TARGET_NR_fstat64
 
7846
    case TARGET_NR_fstat64:
 
7847
        ret = get_errno(fstat(arg1, &st));
 
7848
        if (!is_error(ret))
 
7849
            ret = host_to_target_stat64(cpu_env, arg2, &st);
 
7850
        break;
 
7851
#endif
 
7852
#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat))
 
7853
#ifdef TARGET_NR_fstatat64
 
7854
    case TARGET_NR_fstatat64:
 
7855
#endif
 
7856
#ifdef TARGET_NR_newfstatat
 
7857
    case TARGET_NR_newfstatat:
 
7858
#endif
 
7859
        if (!(p = lock_user_string(arg2)))
 
7860
            goto efault;
 
7861
        ret = get_errno(fstatat(arg1, path(p), &st, arg4));
 
7862
        if (!is_error(ret))
 
7863
            ret = host_to_target_stat64(cpu_env, arg3, &st);
 
7864
        break;
 
7865
#endif
 
7866
    case TARGET_NR_lchown:
 
7867
        if (!(p = lock_user_string(arg1)))
 
7868
            goto efault;
 
7869
        ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
 
7870
        unlock_user(p, arg1, 0);
 
7871
        break;
 
7872
#ifdef TARGET_NR_getuid
 
7873
    case TARGET_NR_getuid:
 
7874
        ret = get_errno(high2lowuid(getuid()));
 
7875
        break;
 
7876
#endif
 
7877
#ifdef TARGET_NR_getgid
 
7878
    case TARGET_NR_getgid:
 
7879
        ret = get_errno(high2lowgid(getgid()));
 
7880
        break;
 
7881
#endif
 
7882
#ifdef TARGET_NR_geteuid
 
7883
    case TARGET_NR_geteuid:
 
7884
        ret = get_errno(high2lowuid(geteuid()));
 
7885
        break;
 
7886
#endif
 
7887
#ifdef TARGET_NR_getegid
 
7888
    case TARGET_NR_getegid:
 
7889
        ret = get_errno(high2lowgid(getegid()));
 
7890
        break;
 
7891
#endif
 
7892
    case TARGET_NR_setreuid:
 
7893
        ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
 
7894
        break;
 
7895
    case TARGET_NR_setregid:
 
7896
        ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
 
7897
        break;
 
7898
    case TARGET_NR_getgroups:
 
7899
        {
 
7900
            int gidsetsize = arg1;
 
7901
            target_id *target_grouplist;
 
7902
            gid_t *grouplist;
 
7903
            int i;
 
7904
 
 
7905
            grouplist = alloca(gidsetsize * sizeof(gid_t));
 
7906
            ret = get_errno(getgroups(gidsetsize, grouplist));
 
7907
            if (gidsetsize == 0)
 
7908
                break;
 
7909
            if (!is_error(ret)) {
 
7910
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * sizeof(target_id), 0);
 
7911
                if (!target_grouplist)
 
7912
                    goto efault;
 
7913
                for(i = 0;i < ret; i++)
 
7914
                    target_grouplist[i] = tswapid(high2lowgid(grouplist[i]));
 
7915
                unlock_user(target_grouplist, arg2, gidsetsize * sizeof(target_id));
 
7916
            }
 
7917
        }
 
7918
        break;
 
7919
    case TARGET_NR_setgroups:
 
7920
        {
 
7921
            int gidsetsize = arg1;
 
7922
            target_id *target_grouplist;
 
7923
            gid_t *grouplist = NULL;
 
7924
            int i;
 
7925
            if (gidsetsize) {
 
7926
                grouplist = alloca(gidsetsize * sizeof(gid_t));
 
7927
                target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * sizeof(target_id), 1);
 
7928
                if (!target_grouplist) {
 
7929
                    ret = -TARGET_EFAULT;
 
7930
                    goto fail;
 
7931
                }
 
7932
                for (i = 0; i < gidsetsize; i++) {
 
7933
                    grouplist[i] = low2highgid(tswapid(target_grouplist[i]));
 
7934
                }
 
7935
                unlock_user(target_grouplist, arg2, 0);
 
7936
            }
 
7937
            ret = get_errno(setgroups(gidsetsize, grouplist));
 
7938
        }
 
7939
        break;
 
7940
    case TARGET_NR_fchown:
 
7941
        ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
 
7942
        break;
 
7943
#if defined(TARGET_NR_fchownat)
 
7944
    case TARGET_NR_fchownat:
 
7945
        if (!(p = lock_user_string(arg2))) 
 
7946
            goto efault;
 
7947
        ret = get_errno(fchownat(arg1, p, low2highuid(arg3),
 
7948
                                 low2highgid(arg4), arg5));
 
7949
        unlock_user(p, arg2, 0);
 
7950
        break;
 
7951
#endif
 
7952
#ifdef TARGET_NR_setresuid
 
7953
    case TARGET_NR_setresuid:
 
7954
        ret = get_errno(setresuid(low2highuid(arg1),
 
7955
                                  low2highuid(arg2),
 
7956
                                  low2highuid(arg3)));
 
7957
        break;
 
7958
#endif
 
7959
#ifdef TARGET_NR_getresuid
 
7960
    case TARGET_NR_getresuid:
 
7961
        {
 
7962
            uid_t ruid, euid, suid;
 
7963
            ret = get_errno(getresuid(&ruid, &euid, &suid));
 
7964
            if (!is_error(ret)) {
 
7965
                if (put_user_u16(high2lowuid(ruid), arg1)
 
7966
                    || put_user_u16(high2lowuid(euid), arg2)
 
7967
                    || put_user_u16(high2lowuid(suid), arg3))
 
7968
                    goto efault;
 
7969
            }
 
7970
        }
 
7971
        break;
 
7972
#endif
 
7973
#ifdef TARGET_NR_getresgid
 
7974
    case TARGET_NR_setresgid:
 
7975
        ret = get_errno(setresgid(low2highgid(arg1),
 
7976
                                  low2highgid(arg2),
 
7977
                                  low2highgid(arg3)));
 
7978
        break;
 
7979
#endif
 
7980
#ifdef TARGET_NR_getresgid
 
7981
    case TARGET_NR_getresgid:
 
7982
        {
 
7983
            gid_t rgid, egid, sgid;
 
7984
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
 
7985
            if (!is_error(ret)) {
 
7986
                if (put_user_u16(high2lowgid(rgid), arg1)
 
7987
                    || put_user_u16(high2lowgid(egid), arg2)
 
7988
                    || put_user_u16(high2lowgid(sgid), arg3))
 
7989
                    goto efault;
 
7990
            }
 
7991
        }
 
7992
        break;
 
7993
#endif
 
7994
    case TARGET_NR_chown:
 
7995
        if (!(p = lock_user_string(arg1)))
 
7996
            goto efault;
 
7997
        ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
 
7998
        unlock_user(p, arg1, 0);
 
7999
        break;
 
8000
    case TARGET_NR_setuid:
 
8001
        ret = get_errno(setuid(low2highuid(arg1)));
 
8002
        break;
 
8003
    case TARGET_NR_setgid:
 
8004
        ret = get_errno(setgid(low2highgid(arg1)));
 
8005
        break;
 
8006
    case TARGET_NR_setfsuid:
 
8007
        ret = get_errno(setfsuid(arg1));
 
8008
        break;
 
8009
    case TARGET_NR_setfsgid:
 
8010
        ret = get_errno(setfsgid(arg1));
 
8011
        break;
 
8012
 
 
8013
#ifdef TARGET_NR_lchown32
 
8014
    case TARGET_NR_lchown32:
 
8015
        if (!(p = lock_user_string(arg1)))
 
8016
            goto efault;
 
8017
        ret = get_errno(lchown(p, arg2, arg3));
 
8018
        unlock_user(p, arg1, 0);
 
8019
        break;
 
8020
#endif
 
8021
#ifdef TARGET_NR_getuid32
 
8022
    case TARGET_NR_getuid32:
 
8023
        ret = get_errno(getuid());
 
8024
        break;
 
8025
#endif
 
8026
 
 
8027
#if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
 
8028
   /* Alpha specific */
 
8029
    case TARGET_NR_getxuid:
 
8030
         {
 
8031
            uid_t euid;
 
8032
            euid=geteuid();
 
8033
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
 
8034
         }
 
8035
        ret = get_errno(getuid());
 
8036
        break;
 
8037
#endif
 
8038
#if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
 
8039
   /* Alpha specific */
 
8040
    case TARGET_NR_getxgid:
 
8041
         {
 
8042
            uid_t egid;
 
8043
            egid=getegid();
 
8044
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
 
8045
         }
 
8046
        ret = get_errno(getgid());
 
8047
        break;
 
8048
#endif
 
8049
#if defined(TARGET_NR_osf_getsysinfo) && defined(TARGET_ALPHA)
 
8050
    /* Alpha specific */
 
8051
    case TARGET_NR_osf_getsysinfo:
 
8052
        ret = -TARGET_EOPNOTSUPP;
 
8053
        switch (arg1) {
 
8054
          case TARGET_GSI_IEEE_FP_CONTROL:
 
8055
            {
 
8056
                uint64_t swcr, fpcr = cpu_alpha_load_fpcr (cpu_env);
 
8057
 
 
8058
                /* Copied from linux ieee_fpcr_to_swcr.  */
 
8059
                swcr = (fpcr >> 35) & SWCR_STATUS_MASK;
 
8060
                swcr |= (fpcr >> 36) & SWCR_MAP_DMZ;
 
8061
                swcr |= (~fpcr >> 48) & (SWCR_TRAP_ENABLE_INV
 
8062
                                        | SWCR_TRAP_ENABLE_DZE
 
8063
                                        | SWCR_TRAP_ENABLE_OVF);
 
8064
                swcr |= (~fpcr >> 57) & (SWCR_TRAP_ENABLE_UNF
 
8065
                                        | SWCR_TRAP_ENABLE_INE);
 
8066
                swcr |= (fpcr >> 47) & SWCR_MAP_UMZ;
 
8067
                swcr |= (~fpcr >> 41) & SWCR_TRAP_ENABLE_DNO;
 
8068
 
 
8069
                if (put_user_u64 (swcr, arg2))
 
8070
                        goto efault;
 
8071
                ret = 0;
 
8072
            }
 
8073
            break;
 
8074
 
 
8075
          /* case GSI_IEEE_STATE_AT_SIGNAL:
 
8076
             -- Not implemented in linux kernel.
 
8077
             case GSI_UACPROC:
 
8078
             -- Retrieves current unaligned access state; not much used.
 
8079
             case GSI_PROC_TYPE:
 
8080
             -- Retrieves implver information; surely not used.
 
8081
             case GSI_GET_HWRPB:
 
8082
             -- Grabs a copy of the HWRPB; surely not used.
 
8083
          */
 
8084
        }
 
8085
        break;
 
8086
#endif
 
8087
#if defined(TARGET_NR_osf_setsysinfo) && defined(TARGET_ALPHA)
 
8088
    /* Alpha specific */
 
8089
    case TARGET_NR_osf_setsysinfo:
 
8090
        ret = -TARGET_EOPNOTSUPP;
 
8091
        switch (arg1) {
 
8092
          case TARGET_SSI_IEEE_FP_CONTROL:
 
8093
            {
 
8094
                uint64_t swcr, fpcr, orig_fpcr;
 
8095
 
 
8096
                if (get_user_u64 (swcr, arg2)) {
 
8097
                    goto efault;
 
8098
                }
 
8099
                orig_fpcr = cpu_alpha_load_fpcr(cpu_env);
 
8100
                fpcr = orig_fpcr & FPCR_DYN_MASK;
 
8101
 
 
8102
                /* Copied from linux ieee_swcr_to_fpcr.  */
 
8103
                fpcr |= (swcr & SWCR_STATUS_MASK) << 35;
 
8104
                fpcr |= (swcr & SWCR_MAP_DMZ) << 36;
 
8105
                fpcr |= (~swcr & (SWCR_TRAP_ENABLE_INV
 
8106
                                  | SWCR_TRAP_ENABLE_DZE
 
8107
                                  | SWCR_TRAP_ENABLE_OVF)) << 48;
 
8108
                fpcr |= (~swcr & (SWCR_TRAP_ENABLE_UNF
 
8109
                                  | SWCR_TRAP_ENABLE_INE)) << 57;
 
8110
                fpcr |= (swcr & SWCR_MAP_UMZ ? FPCR_UNDZ | FPCR_UNFD : 0);
 
8111
                fpcr |= (~swcr & SWCR_TRAP_ENABLE_DNO) << 41;
 
8112
 
 
8113
                cpu_alpha_store_fpcr(cpu_env, fpcr);
 
8114
                ret = 0;
 
8115
            }
 
8116
            break;
 
8117
 
 
8118
          case TARGET_SSI_IEEE_RAISE_EXCEPTION:
 
8119
            {
 
8120
                uint64_t exc, fpcr, orig_fpcr;
 
8121
                int si_code;
 
8122
 
 
8123
                if (get_user_u64(exc, arg2)) {
 
8124
                    goto efault;
 
8125
                }
 
8126
 
 
8127
                orig_fpcr = cpu_alpha_load_fpcr(cpu_env);
 
8128
 
 
8129
                /* We only add to the exception status here.  */
 
8130
                fpcr = orig_fpcr | ((exc & SWCR_STATUS_MASK) << 35);
 
8131
 
 
8132
                cpu_alpha_store_fpcr(cpu_env, fpcr);
 
8133
                ret = 0;
 
8134
 
 
8135
                /* Old exceptions are not signaled.  */
 
8136
                fpcr &= ~(orig_fpcr & FPCR_STATUS_MASK);
 
8137
 
 
8138
                /* If any exceptions set by this call,
 
8139
                   and are unmasked, send a signal.  */
 
8140
                si_code = 0;
 
8141
                if ((fpcr & (FPCR_INE | FPCR_INED)) == FPCR_INE) {
 
8142
                    si_code = TARGET_FPE_FLTRES;
 
8143
                }
 
8144
                if ((fpcr & (FPCR_UNF | FPCR_UNFD)) == FPCR_UNF) {
 
8145
                    si_code = TARGET_FPE_FLTUND;
 
8146
                }
 
8147
                if ((fpcr & (FPCR_OVF | FPCR_OVFD)) == FPCR_OVF) {
 
8148
                    si_code = TARGET_FPE_FLTOVF;
 
8149
                }
 
8150
                if ((fpcr & (FPCR_DZE | FPCR_DZED)) == FPCR_DZE) {
 
8151
                    si_code = TARGET_FPE_FLTDIV;
 
8152
                }
 
8153
                if ((fpcr & (FPCR_INV | FPCR_INVD)) == FPCR_INV) {
 
8154
                    si_code = TARGET_FPE_FLTINV;
 
8155
                }
 
8156
                if (si_code != 0) {
 
8157
                    target_siginfo_t info;
 
8158
                    info.si_signo = SIGFPE;
 
8159
                    info.si_errno = 0;
 
8160
                    info.si_code = si_code;
 
8161
                    info._sifields._sigfault._addr
 
8162
                        = ((CPUArchState *)cpu_env)->pc;
 
8163
                    queue_signal((CPUArchState *)cpu_env, info.si_signo, &info);
 
8164
                }
 
8165
            }
 
8166
            break;
 
8167
 
 
8168
          /* case SSI_NVPAIRS:
 
8169
             -- Used with SSIN_UACPROC to enable unaligned accesses.
 
8170
             case SSI_IEEE_STATE_AT_SIGNAL:
 
8171
             case SSI_IEEE_IGNORE_STATE_AT_SIGNAL:
 
8172
             -- Not implemented in linux kernel
 
8173
          */
 
8174
        }
 
8175
        break;
 
8176
#endif
 
8177
#ifdef TARGET_NR_osf_sigprocmask
 
8178
    /* Alpha specific.  */
 
8179
    case TARGET_NR_osf_sigprocmask:
 
8180
        {
 
8181
            abi_ulong mask;
 
8182
            int how;
 
8183
            sigset_t set, oldset;
 
8184
 
 
8185
            switch(arg1) {
 
8186
            case TARGET_SIG_BLOCK:
 
8187
                how = SIG_BLOCK;
 
8188
                break;
 
8189
            case TARGET_SIG_UNBLOCK:
 
8190
                how = SIG_UNBLOCK;
 
8191
                break;
 
8192
            case TARGET_SIG_SETMASK:
 
8193
                how = SIG_SETMASK;
 
8194
                break;
 
8195
            default:
 
8196
                ret = -TARGET_EINVAL;
 
8197
                goto fail;
 
8198
            }
 
8199
            mask = arg2;
 
8200
            target_to_host_old_sigset(&set, &mask);
 
8201
            sigprocmask(how, &set, &oldset);
 
8202
            host_to_target_old_sigset(&mask, &oldset);
 
8203
            ret = mask;
 
8204
        }
 
8205
        break;
 
8206
#endif
 
8207
 
 
8208
#ifdef TARGET_NR_getgid32
 
8209
    case TARGET_NR_getgid32:
 
8210
        ret = get_errno(getgid());
 
8211
        break;
 
8212
#endif
 
8213
#ifdef TARGET_NR_geteuid32
 
8214
    case TARGET_NR_geteuid32:
 
8215
        ret = get_errno(geteuid());
 
8216
        break;
 
8217
#endif
 
8218
#ifdef TARGET_NR_getegid32
 
8219
    case TARGET_NR_getegid32:
 
8220
        ret = get_errno(getegid());
 
8221
        break;
 
8222
#endif
 
8223
#ifdef TARGET_NR_setreuid32
 
8224
    case TARGET_NR_setreuid32:
 
8225
        ret = get_errno(setreuid(arg1, arg2));
 
8226
        break;
 
8227
#endif
 
8228
#ifdef TARGET_NR_setregid32
 
8229
    case TARGET_NR_setregid32:
 
8230
        ret = get_errno(setregid(arg1, arg2));
 
8231
        break;
 
8232
#endif
 
8233
#ifdef TARGET_NR_getgroups32
 
8234
    case TARGET_NR_getgroups32:
 
8235
        {
 
8236
            int gidsetsize = arg1;
 
8237
            uint32_t *target_grouplist;
 
8238
            gid_t *grouplist;
 
8239
            int i;
 
8240
 
 
8241
            grouplist = alloca(gidsetsize * sizeof(gid_t));
 
8242
            ret = get_errno(getgroups(gidsetsize, grouplist));
 
8243
            if (gidsetsize == 0)
 
8244
                break;
 
8245
            if (!is_error(ret)) {
 
8246
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
 
8247
                if (!target_grouplist) {
 
8248
                    ret = -TARGET_EFAULT;
 
8249
                    goto fail;
 
8250
                }
 
8251
                for(i = 0;i < ret; i++)
 
8252
                    target_grouplist[i] = tswap32(grouplist[i]);
 
8253
                unlock_user(target_grouplist, arg2, gidsetsize * 4);
 
8254
            }
 
8255
        }
 
8256
        break;
 
8257
#endif
 
8258
#ifdef TARGET_NR_setgroups32
 
8259
    case TARGET_NR_setgroups32:
 
8260
        {
 
8261
            int gidsetsize = arg1;
 
8262
            uint32_t *target_grouplist;
 
8263
            gid_t *grouplist;
 
8264
            int i;
 
8265
 
 
8266
            grouplist = alloca(gidsetsize * sizeof(gid_t));
 
8267
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
 
8268
            if (!target_grouplist) {
 
8269
                ret = -TARGET_EFAULT;
 
8270
                goto fail;
 
8271
            }
 
8272
            for(i = 0;i < gidsetsize; i++)
 
8273
                grouplist[i] = tswap32(target_grouplist[i]);
 
8274
            unlock_user(target_grouplist, arg2, 0);
 
8275
            ret = get_errno(setgroups(gidsetsize, grouplist));
 
8276
        }
 
8277
        break;
 
8278
#endif
 
8279
#ifdef TARGET_NR_fchown32
 
8280
    case TARGET_NR_fchown32:
 
8281
        ret = get_errno(fchown(arg1, arg2, arg3));
 
8282
        break;
 
8283
#endif
 
8284
#ifdef TARGET_NR_setresuid32
 
8285
    case TARGET_NR_setresuid32:
 
8286
        ret = get_errno(setresuid(arg1, arg2, arg3));
 
8287
        break;
 
8288
#endif
 
8289
#ifdef TARGET_NR_getresuid32
 
8290
    case TARGET_NR_getresuid32:
 
8291
        {
 
8292
            uid_t ruid, euid, suid;
 
8293
            ret = get_errno(getresuid(&ruid, &euid, &suid));
 
8294
            if (!is_error(ret)) {
 
8295
                if (put_user_u32(ruid, arg1)
 
8296
                    || put_user_u32(euid, arg2)
 
8297
                    || put_user_u32(suid, arg3))
 
8298
                    goto efault;
 
8299
            }
 
8300
        }
 
8301
        break;
 
8302
#endif
 
8303
#ifdef TARGET_NR_setresgid32
 
8304
    case TARGET_NR_setresgid32:
 
8305
        ret = get_errno(setresgid(arg1, arg2, arg3));
 
8306
        break;
 
8307
#endif
 
8308
#ifdef TARGET_NR_getresgid32
 
8309
    case TARGET_NR_getresgid32:
 
8310
        {
 
8311
            gid_t rgid, egid, sgid;
 
8312
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
 
8313
            if (!is_error(ret)) {
 
8314
                if (put_user_u32(rgid, arg1)
 
8315
                    || put_user_u32(egid, arg2)
 
8316
                    || put_user_u32(sgid, arg3))
 
8317
                    goto efault;
 
8318
            }
 
8319
        }
 
8320
        break;
 
8321
#endif
 
8322
#ifdef TARGET_NR_chown32
 
8323
    case TARGET_NR_chown32:
 
8324
        if (!(p = lock_user_string(arg1)))
 
8325
            goto efault;
 
8326
        ret = get_errno(chown(p, arg2, arg3));
 
8327
        unlock_user(p, arg1, 0);
 
8328
        break;
 
8329
#endif
 
8330
#ifdef TARGET_NR_setuid32
 
8331
    case TARGET_NR_setuid32:
 
8332
        ret = get_errno(setuid(arg1));
 
8333
        break;
 
8334
#endif
 
8335
#ifdef TARGET_NR_setgid32
 
8336
    case TARGET_NR_setgid32:
 
8337
        ret = get_errno(setgid(arg1));
 
8338
        break;
 
8339
#endif
 
8340
#ifdef TARGET_NR_setfsuid32
 
8341
    case TARGET_NR_setfsuid32:
 
8342
        ret = get_errno(setfsuid(arg1));
 
8343
        break;
 
8344
#endif
 
8345
#ifdef TARGET_NR_setfsgid32
 
8346
    case TARGET_NR_setfsgid32:
 
8347
        ret = get_errno(setfsgid(arg1));
 
8348
        break;
 
8349
#endif
 
8350
 
 
8351
    case TARGET_NR_pivot_root:
 
8352
        goto unimplemented;
 
8353
#ifdef TARGET_NR_mincore
 
8354
    case TARGET_NR_mincore:
 
8355
        {
 
8356
            void *a;
 
8357
            ret = -TARGET_EFAULT;
 
8358
            if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
 
8359
                goto efault;
 
8360
            if (!(p = lock_user_string(arg3)))
 
8361
                goto mincore_fail;
 
8362
            ret = get_errno(mincore(a, arg2, p));
 
8363
            unlock_user(p, arg3, ret);
 
8364
            mincore_fail:
 
8365
            unlock_user(a, arg1, 0);
 
8366
        }
 
8367
        break;
 
8368
#endif
 
8369
#ifdef TARGET_NR_arm_fadvise64_64
 
8370
    case TARGET_NR_arm_fadvise64_64:
 
8371
        {
 
8372
                /*
 
8373
                 * arm_fadvise64_64 looks like fadvise64_64 but
 
8374
                 * with different argument order
 
8375
                 */
 
8376
                abi_long temp;
 
8377
                temp = arg3;
 
8378
                arg3 = arg4;
 
8379
                arg4 = temp;
 
8380
        }
 
8381
#endif
 
8382
#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64) || defined(TARGET_NR_fadvise64)
 
8383
#ifdef TARGET_NR_fadvise64_64
 
8384
    case TARGET_NR_fadvise64_64:
 
8385
#endif
 
8386
#ifdef TARGET_NR_fadvise64
 
8387
    case TARGET_NR_fadvise64:
 
8388
#endif
 
8389
#ifdef TARGET_S390X
 
8390
        switch (arg4) {
 
8391
        case 4: arg4 = POSIX_FADV_NOREUSE + 1; break; /* make sure it's an invalid value */
 
8392
        case 5: arg4 = POSIX_FADV_NOREUSE + 2; break; /* ditto */
 
8393
        case 6: arg4 = POSIX_FADV_DONTNEED; break;
 
8394
        case 7: arg4 = POSIX_FADV_NOREUSE; break;
 
8395
        default: break;
 
8396
        }
 
8397
#endif
 
8398
        ret = -posix_fadvise(arg1, arg2, arg3, arg4);
 
8399
        break;
 
8400
#endif
 
8401
#ifdef TARGET_NR_madvise
 
8402
    case TARGET_NR_madvise:
 
8403
        /* A straight passthrough may not be safe because qemu sometimes
 
8404
           turns private file-backed mappings into anonymous mappings.
 
8405
           This will break MADV_DONTNEED.
 
8406
           This is a hint, so ignoring and returning success is ok.  */
 
8407
        ret = get_errno(0);
 
8408
        break;
 
8409
#endif
 
8410
#if TARGET_ABI_BITS == 32
 
8411
    case TARGET_NR_fcntl64:
 
8412
    {
 
8413
        int cmd;
 
8414
        struct flock64 fl;
 
8415
        struct target_flock64 *target_fl;
 
8416
#ifdef TARGET_ARM
 
8417
        struct target_eabi_flock64 *target_efl;
 
8418
#endif
 
8419
 
 
8420
        cmd = target_to_host_fcntl_cmd(arg2);
 
8421
        if (cmd == -TARGET_EINVAL) {
 
8422
            ret = cmd;
 
8423
            break;
 
8424
        }
 
8425
 
 
8426
        switch(arg2) {
 
8427
        case TARGET_F_GETLK64:
 
8428
#ifdef TARGET_ARM
 
8429
            if (((CPUARMState *)cpu_env)->eabi) {
 
8430
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
 
8431
                    goto efault;
 
8432
                fl.l_type = tswap16(target_efl->l_type);
 
8433
                fl.l_whence = tswap16(target_efl->l_whence);
 
8434
                fl.l_start = tswap64(target_efl->l_start);
 
8435
                fl.l_len = tswap64(target_efl->l_len);
 
8436
                fl.l_pid = tswap32(target_efl->l_pid);
 
8437
                unlock_user_struct(target_efl, arg3, 0);
 
8438
            } else
 
8439
#endif
 
8440
            {
 
8441
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
 
8442
                    goto efault;
 
8443
                fl.l_type = tswap16(target_fl->l_type);
 
8444
                fl.l_whence = tswap16(target_fl->l_whence);
 
8445
                fl.l_start = tswap64(target_fl->l_start);
 
8446
                fl.l_len = tswap64(target_fl->l_len);
 
8447
                fl.l_pid = tswap32(target_fl->l_pid);
 
8448
                unlock_user_struct(target_fl, arg3, 0);
 
8449
            }
 
8450
            ret = get_errno(fcntl(arg1, cmd, &fl));
 
8451
            if (ret == 0) {
 
8452
#ifdef TARGET_ARM
 
8453
                if (((CPUARMState *)cpu_env)->eabi) {
 
8454
                    if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) 
 
8455
                        goto efault;
 
8456
                    target_efl->l_type = tswap16(fl.l_type);
 
8457
                    target_efl->l_whence = tswap16(fl.l_whence);
 
8458
                    target_efl->l_start = tswap64(fl.l_start);
 
8459
                    target_efl->l_len = tswap64(fl.l_len);
 
8460
                    target_efl->l_pid = tswap32(fl.l_pid);
 
8461
                    unlock_user_struct(target_efl, arg3, 1);
 
8462
                } else
 
8463
#endif
 
8464
                {
 
8465
                    if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) 
 
8466
                        goto efault;
 
8467
                    target_fl->l_type = tswap16(fl.l_type);
 
8468
                    target_fl->l_whence = tswap16(fl.l_whence);
 
8469
                    target_fl->l_start = tswap64(fl.l_start);
 
8470
                    target_fl->l_len = tswap64(fl.l_len);
 
8471
                    target_fl->l_pid = tswap32(fl.l_pid);
 
8472
                    unlock_user_struct(target_fl, arg3, 1);
 
8473
                }
 
8474
            }
 
8475
            break;
 
8476
 
 
8477
        case TARGET_F_SETLK64:
 
8478
        case TARGET_F_SETLKW64:
 
8479
#ifdef TARGET_ARM
 
8480
            if (((CPUARMState *)cpu_env)->eabi) {
 
8481
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
 
8482
                    goto efault;
 
8483
                fl.l_type = tswap16(target_efl->l_type);
 
8484
                fl.l_whence = tswap16(target_efl->l_whence);
 
8485
                fl.l_start = tswap64(target_efl->l_start);
 
8486
                fl.l_len = tswap64(target_efl->l_len);
 
8487
                fl.l_pid = tswap32(target_efl->l_pid);
 
8488
                unlock_user_struct(target_efl, arg3, 0);
 
8489
            } else
 
8490
#endif
 
8491
            {
 
8492
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
 
8493
                    goto efault;
 
8494
                fl.l_type = tswap16(target_fl->l_type);
 
8495
                fl.l_whence = tswap16(target_fl->l_whence);
 
8496
                fl.l_start = tswap64(target_fl->l_start);
 
8497
                fl.l_len = tswap64(target_fl->l_len);
 
8498
                fl.l_pid = tswap32(target_fl->l_pid);
 
8499
                unlock_user_struct(target_fl, arg3, 0);
 
8500
            }
 
8501
            ret = get_errno(fcntl(arg1, cmd, &fl));
 
8502
            break;
 
8503
        default:
 
8504
            ret = do_fcntl(arg1, arg2, arg3);
 
8505
            break;
 
8506
        }
 
8507
        break;
 
8508
    }
 
8509
#endif
 
8510
#ifdef TARGET_NR_cacheflush
 
8511
    case TARGET_NR_cacheflush:
 
8512
        /* self-modifying code is handled automatically, so nothing needed */
 
8513
        ret = 0;
 
8514
        break;
 
8515
#endif
 
8516
#ifdef TARGET_NR_security
 
8517
    case TARGET_NR_security:
 
8518
        goto unimplemented;
 
8519
#endif
 
8520
#ifdef TARGET_NR_getpagesize
 
8521
    case TARGET_NR_getpagesize:
 
8522
        ret = TARGET_PAGE_SIZE;
 
8523
        break;
 
8524
#endif
 
8525
    case TARGET_NR_gettid:
 
8526
        ret = get_errno(gettid());
 
8527
        break;
 
8528
#ifdef TARGET_NR_readahead
 
8529
    case TARGET_NR_readahead:
 
8530
#if TARGET_ABI_BITS == 32
 
8531
        if (regpairs_aligned(cpu_env)) {
 
8532
            arg2 = arg3;
 
8533
            arg3 = arg4;
 
8534
            arg4 = arg5;
 
8535
        }
 
8536
        ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
 
8537
#else
 
8538
        ret = get_errno(readahead(arg1, arg2, arg3));
 
8539
#endif
 
8540
        break;
 
8541
#endif
 
8542
#ifdef CONFIG_ATTR
 
8543
#ifdef TARGET_NR_setxattr
 
8544
    case TARGET_NR_listxattr:
 
8545
    case TARGET_NR_llistxattr:
 
8546
    {
 
8547
        void *p, *b = 0;
 
8548
        if (arg2) {
 
8549
            b = lock_user(VERIFY_WRITE, arg2, arg3, 0);
 
8550
            if (!b) {
 
8551
                ret = -TARGET_EFAULT;
 
8552
                break;
 
8553
            }
 
8554
        }
 
8555
        p = lock_user_string(arg1);
 
8556
        if (p) {
 
8557
            if (num == TARGET_NR_listxattr) {
 
8558
                ret = get_errno(listxattr(p, b, arg3));
 
8559
            } else {
 
8560
                ret = get_errno(llistxattr(p, b, arg3));
 
8561
            }
 
8562
        } else {
 
8563
            ret = -TARGET_EFAULT;
 
8564
        }
 
8565
        unlock_user(p, arg1, 0);
 
8566
        unlock_user(b, arg2, arg3);
 
8567
        break;
 
8568
    }
 
8569
    case TARGET_NR_flistxattr:
 
8570
    {
 
8571
        void *b = 0;
 
8572
        if (arg2) {
 
8573
            b = lock_user(VERIFY_WRITE, arg2, arg3, 0);
 
8574
            if (!b) {
 
8575
                ret = -TARGET_EFAULT;
 
8576
                break;
 
8577
            }
 
8578
        }
 
8579
        ret = get_errno(flistxattr(arg1, b, arg3));
 
8580
        unlock_user(b, arg2, arg3);
 
8581
        break;
 
8582
    }
 
8583
    case TARGET_NR_setxattr:
 
8584
    case TARGET_NR_lsetxattr:
 
8585
        {
 
8586
            void *p, *n, *v = 0;
 
8587
            if (arg3) {
 
8588
                v = lock_user(VERIFY_READ, arg3, arg4, 1);
 
8589
                if (!v) {
 
8590
                    ret = -TARGET_EFAULT;
 
8591
                    break;
 
8592
                }
 
8593
            }
 
8594
            p = lock_user_string(arg1);
 
8595
            n = lock_user_string(arg2);
 
8596
            if (p && n) {
 
8597
                if (num == TARGET_NR_setxattr) {
 
8598
                    ret = get_errno(setxattr(p, n, v, arg4, arg5));
 
8599
                } else {
 
8600
                    ret = get_errno(lsetxattr(p, n, v, arg4, arg5));
 
8601
                }
 
8602
            } else {
 
8603
                ret = -TARGET_EFAULT;
 
8604
            }
 
8605
            unlock_user(p, arg1, 0);
 
8606
            unlock_user(n, arg2, 0);
 
8607
            unlock_user(v, arg3, 0);
 
8608
        }
 
8609
        break;
 
8610
    case TARGET_NR_fsetxattr:
 
8611
        {
 
8612
            void *n, *v = 0;
 
8613
            if (arg3) {
 
8614
                v = lock_user(VERIFY_READ, arg3, arg4, 1);
 
8615
                if (!v) {
 
8616
                    ret = -TARGET_EFAULT;
 
8617
                    break;
 
8618
                }
 
8619
            }
 
8620
            n = lock_user_string(arg2);
 
8621
            if (n) {
 
8622
                ret = get_errno(fsetxattr(arg1, n, v, arg4, arg5));
 
8623
            } else {
 
8624
                ret = -TARGET_EFAULT;
 
8625
            }
 
8626
            unlock_user(n, arg2, 0);
 
8627
            unlock_user(v, arg3, 0);
 
8628
        }
 
8629
        break;
 
8630
    case TARGET_NR_getxattr:
 
8631
    case TARGET_NR_lgetxattr:
 
8632
        {
 
8633
            void *p, *n, *v = 0;
 
8634
            if (arg3) {
 
8635
                v = lock_user(VERIFY_WRITE, arg3, arg4, 0);
 
8636
                if (!v) {
 
8637
                    ret = -TARGET_EFAULT;
 
8638
                    break;
 
8639
                }
 
8640
            }
 
8641
            p = lock_user_string(arg1);
 
8642
            n = lock_user_string(arg2);
 
8643
            if (p && n) {
 
8644
                if (num == TARGET_NR_getxattr) {
 
8645
                    ret = get_errno(getxattr(p, n, v, arg4));
 
8646
                } else {
 
8647
                    ret = get_errno(lgetxattr(p, n, v, arg4));
 
8648
                }
 
8649
            } else {
 
8650
                ret = -TARGET_EFAULT;
 
8651
            }
 
8652
            unlock_user(p, arg1, 0);
 
8653
            unlock_user(n, arg2, 0);
 
8654
            unlock_user(v, arg3, arg4);
 
8655
        }
 
8656
        break;
 
8657
    case TARGET_NR_fgetxattr:
 
8658
        {
 
8659
            void *n, *v = 0;
 
8660
            if (arg3) {
 
8661
                v = lock_user(VERIFY_WRITE, arg3, arg4, 0);
 
8662
                if (!v) {
 
8663
                    ret = -TARGET_EFAULT;
 
8664
                    break;
 
8665
                }
 
8666
            }
 
8667
            n = lock_user_string(arg2);
 
8668
            if (n) {
 
8669
                ret = get_errno(fgetxattr(arg1, n, v, arg4));
 
8670
            } else {
 
8671
                ret = -TARGET_EFAULT;
 
8672
            }
 
8673
            unlock_user(n, arg2, 0);
 
8674
            unlock_user(v, arg3, arg4);
 
8675
        }
 
8676
        break;
 
8677
    case TARGET_NR_removexattr:
 
8678
    case TARGET_NR_lremovexattr:
 
8679
        {
 
8680
            void *p, *n;
 
8681
            p = lock_user_string(arg1);
 
8682
            n = lock_user_string(arg2);
 
8683
            if (p && n) {
 
8684
                if (num == TARGET_NR_removexattr) {
 
8685
                    ret = get_errno(removexattr(p, n));
 
8686
                } else {
 
8687
                    ret = get_errno(lremovexattr(p, n));
 
8688
                }
 
8689
            } else {
 
8690
                ret = -TARGET_EFAULT;
 
8691
            }
 
8692
            unlock_user(p, arg1, 0);
 
8693
            unlock_user(n, arg2, 0);
 
8694
        }
 
8695
        break;
 
8696
    case TARGET_NR_fremovexattr:
 
8697
        {
 
8698
            void *n;
 
8699
            n = lock_user_string(arg2);
 
8700
            if (n) {
 
8701
                ret = get_errno(fremovexattr(arg1, n));
 
8702
            } else {
 
8703
                ret = -TARGET_EFAULT;
 
8704
            }
 
8705
            unlock_user(n, arg2, 0);
 
8706
        }
 
8707
        break;
 
8708
#endif
 
8709
#endif /* CONFIG_ATTR */
 
8710
#ifdef TARGET_NR_set_thread_area
 
8711
    case TARGET_NR_set_thread_area:
 
8712
#if defined(TARGET_MIPS)
 
8713
      ((CPUMIPSState *) cpu_env)->tls_value = arg1;
 
8714
      ret = 0;
 
8715
      break;
 
8716
#elif defined(TARGET_CRIS)
 
8717
      if (arg1 & 0xff)
 
8718
          ret = -TARGET_EINVAL;
 
8719
      else {
 
8720
          ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
 
8721
          ret = 0;
 
8722
      }
 
8723
      break;
 
8724
#elif defined(TARGET_I386) && defined(TARGET_ABI32)
 
8725
      ret = do_set_thread_area(cpu_env, arg1);
 
8726
      break;
 
8727
#elif defined(TARGET_M68K)
 
8728
      {
 
8729
          TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
 
8730
          ts->tp_value = arg1;
 
8731
          ret = 0;
 
8732
          break;
 
8733
      }
 
8734
#else
 
8735
      goto unimplemented_nowarn;
 
8736
#endif
 
8737
#endif
 
8738
#ifdef TARGET_NR_get_thread_area
 
8739
    case TARGET_NR_get_thread_area:
 
8740
#if defined(TARGET_I386) && defined(TARGET_ABI32)
 
8741
        ret = do_get_thread_area(cpu_env, arg1);
 
8742
        break;
 
8743
#elif defined(TARGET_M68K)
 
8744
        {
 
8745
            TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
 
8746
            ret = ts->tp_value;
 
8747
            break;
 
8748
        }
 
8749
#else
 
8750
        goto unimplemented_nowarn;
 
8751
#endif
 
8752
#endif
 
8753
#ifdef TARGET_NR_getdomainname
 
8754
    case TARGET_NR_getdomainname:
 
8755
        goto unimplemented_nowarn;
 
8756
#endif
 
8757
 
 
8758
#ifdef TARGET_NR_clock_gettime
 
8759
    case TARGET_NR_clock_gettime:
 
8760
    {
 
8761
        struct timespec ts;
 
8762
        ret = get_errno(clock_gettime(arg1, &ts));
 
8763
        if (!is_error(ret)) {
 
8764
            host_to_target_timespec(arg2, &ts);
 
8765
        }
 
8766
        break;
 
8767
    }
 
8768
#endif
 
8769
#ifdef TARGET_NR_clock_getres
 
8770
    case TARGET_NR_clock_getres:
 
8771
    {
 
8772
        struct timespec ts;
 
8773
        ret = get_errno(clock_getres(arg1, &ts));
 
8774
        if (!is_error(ret)) {
 
8775
            host_to_target_timespec(arg2, &ts);
 
8776
        }
 
8777
        break;
 
8778
    }
 
8779
#endif
 
8780
#ifdef TARGET_NR_clock_nanosleep
 
8781
    case TARGET_NR_clock_nanosleep:
 
8782
    {
 
8783
        struct timespec ts;
 
8784
        target_to_host_timespec(&ts, arg3);
 
8785
        ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
 
8786
        if (arg4)
 
8787
            host_to_target_timespec(arg4, &ts);
 
8788
        break;
 
8789
    }
 
8790
#endif
 
8791
 
 
8792
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
 
8793
    case TARGET_NR_set_tid_address:
 
8794
        ret = get_errno(set_tid_address((int *)g2h(arg1)));
 
8795
        break;
 
8796
#endif
 
8797
 
 
8798
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
 
8799
    case TARGET_NR_tkill:
 
8800
        ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
 
8801
        break;
 
8802
#endif
 
8803
 
 
8804
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
 
8805
    case TARGET_NR_tgkill:
 
8806
        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
 
8807
                        target_to_host_signal(arg3)));
 
8808
        break;
 
8809
#endif
 
8810
 
 
8811
#ifdef TARGET_NR_set_robust_list
 
8812
    case TARGET_NR_set_robust_list:
 
8813
    case TARGET_NR_get_robust_list:
 
8814
        /* The ABI for supporting robust futexes has userspace pass
 
8815
         * the kernel a pointer to a linked list which is updated by
 
8816
         * userspace after the syscall; the list is walked by the kernel
 
8817
         * when the thread exits. Since the linked list in QEMU guest
 
8818
         * memory isn't a valid linked list for the host and we have
 
8819
         * no way to reliably intercept the thread-death event, we can't
 
8820
         * support these. Silently return ENOSYS so that guest userspace
 
8821
         * falls back to a non-robust futex implementation (which should
 
8822
         * be OK except in the corner case of the guest crashing while
 
8823
         * holding a mutex that is shared with another process via
 
8824
         * shared memory).
 
8825
         */
 
8826
        goto unimplemented_nowarn;
 
8827
#endif
 
8828
 
 
8829
#if defined(TARGET_NR_utimensat)
 
8830
    case TARGET_NR_utimensat:
 
8831
        {
 
8832
            struct timespec *tsp, ts[2];
 
8833
            if (!arg3) {
 
8834
                tsp = NULL;
 
8835
            } else {
 
8836
                target_to_host_timespec(ts, arg3);
 
8837
                target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
 
8838
                tsp = ts;
 
8839
            }
 
8840
            if (!arg2)
 
8841
                ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4));
 
8842
            else {
 
8843
                if (!(p = lock_user_string(arg2))) {
 
8844
                    ret = -TARGET_EFAULT;
 
8845
                    goto fail;
 
8846
                }
 
8847
                ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4));
 
8848
                unlock_user(p, arg2, 0);
 
8849
            }
 
8850
        }
 
8851
        break;
 
8852
#endif
 
8853
    case TARGET_NR_futex:
 
8854
        ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
 
8855
        break;
 
8856
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
 
8857
    case TARGET_NR_inotify_init:
 
8858
        ret = get_errno(sys_inotify_init());
 
8859
        break;
 
8860
#endif
 
8861
#ifdef CONFIG_INOTIFY1
 
8862
#if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
 
8863
    case TARGET_NR_inotify_init1:
 
8864
        ret = get_errno(sys_inotify_init1(arg1));
 
8865
        break;
 
8866
#endif
 
8867
#endif
 
8868
#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
 
8869
    case TARGET_NR_inotify_add_watch:
 
8870
        p = lock_user_string(arg2);
 
8871
        ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
 
8872
        unlock_user(p, arg2, 0);
 
8873
        break;
 
8874
#endif
 
8875
#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
 
8876
    case TARGET_NR_inotify_rm_watch:
 
8877
        ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
 
8878
        break;
 
8879
#endif
 
8880
 
 
8881
#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
 
8882
    case TARGET_NR_mq_open:
 
8883
        {
 
8884
            struct mq_attr posix_mq_attr;
 
8885
 
 
8886
            p = lock_user_string(arg1 - 1);
 
8887
            if (arg4 != 0)
 
8888
                copy_from_user_mq_attr (&posix_mq_attr, arg4);
 
8889
            ret = get_errno(mq_open(p, arg2, arg3, &posix_mq_attr));
 
8890
            unlock_user (p, arg1, 0);
 
8891
        }
 
8892
        break;
 
8893
 
 
8894
    case TARGET_NR_mq_unlink:
 
8895
        p = lock_user_string(arg1 - 1);
 
8896
        ret = get_errno(mq_unlink(p));
 
8897
        unlock_user (p, arg1, 0);
 
8898
        break;
 
8899
 
 
8900
    case TARGET_NR_mq_timedsend:
 
8901
        {
 
8902
            struct timespec ts;
 
8903
 
 
8904
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
 
8905
            if (arg5 != 0) {
 
8906
                target_to_host_timespec(&ts, arg5);
 
8907
                ret = get_errno(mq_timedsend(arg1, p, arg3, arg4, &ts));
 
8908
                host_to_target_timespec(arg5, &ts);
 
8909
            }
 
8910
            else
 
8911
                ret = get_errno(mq_send(arg1, p, arg3, arg4));
 
8912
            unlock_user (p, arg2, arg3);
 
8913
        }
 
8914
        break;
 
8915
 
 
8916
    case TARGET_NR_mq_timedreceive:
 
8917
        {
 
8918
            struct timespec ts;
 
8919
            unsigned int prio;
 
8920
 
 
8921
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
 
8922
            if (arg5 != 0) {
 
8923
                target_to_host_timespec(&ts, arg5);
 
8924
                ret = get_errno(mq_timedreceive(arg1, p, arg3, &prio, &ts));
 
8925
                host_to_target_timespec(arg5, &ts);
 
8926
            }
 
8927
            else
 
8928
                ret = get_errno(mq_receive(arg1, p, arg3, &prio));
 
8929
            unlock_user (p, arg2, arg3);
 
8930
            if (arg4 != 0)
 
8931
                put_user_u32(prio, arg4);
 
8932
        }
 
8933
        break;
 
8934
 
 
8935
    /* Not implemented for now... */
 
8936
/*     case TARGET_NR_mq_notify: */
 
8937
/*         break; */
 
8938
 
 
8939
    case TARGET_NR_mq_getsetattr:
 
8940
        {
 
8941
            struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
 
8942
            ret = 0;
 
8943
            if (arg3 != 0) {
 
8944
                ret = mq_getattr(arg1, &posix_mq_attr_out);
 
8945
                copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
 
8946
            }
 
8947
            if (arg2 != 0) {
 
8948
                copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
 
8949
                ret |= mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_attr_out);
 
8950
            }
 
8951
 
 
8952
        }
 
8953
        break;
 
8954
#endif
 
8955
 
 
8956
#ifdef CONFIG_SPLICE
 
8957
#ifdef TARGET_NR_tee
 
8958
    case TARGET_NR_tee:
 
8959
        {
 
8960
            ret = get_errno(tee(arg1,arg2,arg3,arg4));
 
8961
        }
 
8962
        break;
 
8963
#endif
 
8964
#ifdef TARGET_NR_splice
 
8965
    case TARGET_NR_splice:
 
8966
        {
 
8967
            loff_t loff_in, loff_out;
 
8968
            loff_t *ploff_in = NULL, *ploff_out = NULL;
 
8969
            if(arg2) {
 
8970
                get_user_u64(loff_in, arg2);
 
8971
                ploff_in = &loff_in;
 
8972
            }
 
8973
            if(arg4) {
 
8974
                get_user_u64(loff_out, arg2);
 
8975
                ploff_out = &loff_out;
 
8976
            }
 
8977
            ret = get_errno(splice(arg1, ploff_in, arg3, ploff_out, arg5, arg6));
 
8978
        }
 
8979
        break;
 
8980
#endif
 
8981
#ifdef TARGET_NR_vmsplice
 
8982
        case TARGET_NR_vmsplice:
 
8983
        {
 
8984
            struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
 
8985
            if (vec != NULL) {
 
8986
                ret = get_errno(vmsplice(arg1, vec, arg3, arg4));
 
8987
                unlock_iovec(vec, arg2, arg3, 0);
 
8988
            } else {
 
8989
                ret = -host_to_target_errno(errno);
 
8990
            }
 
8991
        }
 
8992
        break;
 
8993
#endif
 
8994
#endif /* CONFIG_SPLICE */
 
8995
#ifdef CONFIG_EVENTFD
 
8996
#if defined(TARGET_NR_eventfd)
 
8997
    case TARGET_NR_eventfd:
 
8998
        ret = get_errno(eventfd(arg1, 0));
 
8999
        break;
 
9000
#endif
 
9001
#if defined(TARGET_NR_eventfd2)
 
9002
    case TARGET_NR_eventfd2:
 
9003
    {
 
9004
        int host_flags = arg2 & (~(TARGET_O_NONBLOCK | TARGET_O_CLOEXEC));
 
9005
        if (arg2 & TARGET_O_NONBLOCK) {
 
9006
            host_flags |= O_NONBLOCK;
 
9007
        }
 
9008
        if (arg2 & TARGET_O_CLOEXEC) {
 
9009
            host_flags |= O_CLOEXEC;
 
9010
        }
 
9011
        ret = get_errno(eventfd(arg1, host_flags));
 
9012
        break;
 
9013
    }
 
9014
#endif
 
9015
#endif /* CONFIG_EVENTFD  */
 
9016
#if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate)
 
9017
    case TARGET_NR_fallocate:
 
9018
#if TARGET_ABI_BITS == 32
 
9019
        ret = get_errno(fallocate(arg1, arg2, target_offset64(arg3, arg4),
 
9020
                                  target_offset64(arg5, arg6)));
 
9021
#else
 
9022
        ret = get_errno(fallocate(arg1, arg2, arg3, arg4));
 
9023
#endif
 
9024
        break;
 
9025
#endif
 
9026
#if defined(CONFIG_SYNC_FILE_RANGE)
 
9027
#if defined(TARGET_NR_sync_file_range)
 
9028
    case TARGET_NR_sync_file_range:
 
9029
#if TARGET_ABI_BITS == 32
 
9030
#if defined(TARGET_MIPS)
 
9031
        ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
 
9032
                                        target_offset64(arg5, arg6), arg7));
 
9033
#else
 
9034
        ret = get_errno(sync_file_range(arg1, target_offset64(arg2, arg3),
 
9035
                                        target_offset64(arg4, arg5), arg6));
 
9036
#endif /* !TARGET_MIPS */
 
9037
#else
 
9038
        ret = get_errno(sync_file_range(arg1, arg2, arg3, arg4));
 
9039
#endif
 
9040
        break;
 
9041
#endif
 
9042
#if defined(TARGET_NR_sync_file_range2)
 
9043
    case TARGET_NR_sync_file_range2:
 
9044
        /* This is like sync_file_range but the arguments are reordered */
 
9045
#if TARGET_ABI_BITS == 32
 
9046
        ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
 
9047
                                        target_offset64(arg5, arg6), arg2));
 
9048
#else
 
9049
        ret = get_errno(sync_file_range(arg1, arg3, arg4, arg2));
 
9050
#endif
 
9051
        break;
 
9052
#endif
 
9053
#endif
 
9054
#if defined(CONFIG_EPOLL)
 
9055
#if defined(TARGET_NR_epoll_create)
 
9056
    case TARGET_NR_epoll_create:
 
9057
        ret = get_errno(epoll_create(arg1));
 
9058
        break;
 
9059
#endif
 
9060
#if defined(TARGET_NR_epoll_create1) && defined(CONFIG_EPOLL_CREATE1)
 
9061
    case TARGET_NR_epoll_create1:
 
9062
        ret = get_errno(epoll_create1(arg1));
 
9063
        break;
 
9064
#endif
 
9065
#if defined(TARGET_NR_epoll_ctl)
 
9066
    case TARGET_NR_epoll_ctl:
 
9067
    {
 
9068
        struct epoll_event ep;
 
9069
        struct epoll_event *epp = 0;
 
9070
        if (arg4) {
 
9071
            struct target_epoll_event *target_ep;
 
9072
            if (!lock_user_struct(VERIFY_READ, target_ep, arg4, 1)) {
 
9073
                goto efault;
 
9074
            }
 
9075
            ep.events = tswap32(target_ep->events);
 
9076
            /* The epoll_data_t union is just opaque data to the kernel,
 
9077
             * so we transfer all 64 bits across and need not worry what
 
9078
             * actual data type it is.
 
9079
             */
 
9080
            ep.data.u64 = tswap64(target_ep->data.u64);
 
9081
            unlock_user_struct(target_ep, arg4, 0);
 
9082
            epp = &ep;
 
9083
        }
 
9084
        ret = get_errno(epoll_ctl(arg1, arg2, arg3, epp));
 
9085
        break;
 
9086
    }
 
9087
#endif
 
9088
 
 
9089
#if defined(TARGET_NR_epoll_pwait) && defined(CONFIG_EPOLL_PWAIT)
 
9090
#define IMPLEMENT_EPOLL_PWAIT
 
9091
#endif
 
9092
#if defined(TARGET_NR_epoll_wait) || defined(IMPLEMENT_EPOLL_PWAIT)
 
9093
#if defined(TARGET_NR_epoll_wait)
 
9094
    case TARGET_NR_epoll_wait:
 
9095
#endif
 
9096
#if defined(IMPLEMENT_EPOLL_PWAIT)
 
9097
    case TARGET_NR_epoll_pwait:
 
9098
#endif
 
9099
    {
 
9100
        struct target_epoll_event *target_ep;
 
9101
        struct epoll_event *ep;
 
9102
        int epfd = arg1;
 
9103
        int maxevents = arg3;
 
9104
        int timeout = arg4;
 
9105
 
 
9106
        target_ep = lock_user(VERIFY_WRITE, arg2,
 
9107
                              maxevents * sizeof(struct target_epoll_event), 1);
 
9108
        if (!target_ep) {
 
9109
            goto efault;
 
9110
        }
 
9111
 
 
9112
        ep = alloca(maxevents * sizeof(struct epoll_event));
 
9113
 
 
9114
        switch (num) {
 
9115
#if defined(IMPLEMENT_EPOLL_PWAIT)
 
9116
        case TARGET_NR_epoll_pwait:
 
9117
        {
 
9118
            target_sigset_t *target_set;
 
9119
            sigset_t _set, *set = &_set;
 
9120
 
 
9121
            if (arg5) {
 
9122
                target_set = lock_user(VERIFY_READ, arg5,
 
9123
                                       sizeof(target_sigset_t), 1);
 
9124
                if (!target_set) {
 
9125
                    unlock_user(target_ep, arg2, 0);
 
9126
                    goto efault;
 
9127
                }
 
9128
                target_to_host_sigset(set, target_set);
 
9129
                unlock_user(target_set, arg5, 0);
 
9130
            } else {
 
9131
                set = NULL;
 
9132
            }
 
9133
 
 
9134
            ret = get_errno(epoll_pwait(epfd, ep, maxevents, timeout, set));
 
9135
            break;
 
9136
        }
 
9137
#endif
 
9138
#if defined(TARGET_NR_epoll_wait)
 
9139
        case TARGET_NR_epoll_wait:
 
9140
            ret = get_errno(epoll_wait(epfd, ep, maxevents, timeout));
 
9141
            break;
 
9142
#endif
 
9143
        default:
 
9144
            ret = -TARGET_ENOSYS;
 
9145
        }
 
9146
        if (!is_error(ret)) {
 
9147
            int i;
 
9148
            for (i = 0; i < ret; i++) {
 
9149
                target_ep[i].events = tswap32(ep[i].events);
 
9150
                target_ep[i].data.u64 = tswap64(ep[i].data.u64);
 
9151
            }
 
9152
        }
 
9153
        unlock_user(target_ep, arg2, ret * sizeof(struct target_epoll_event));
 
9154
        break;
 
9155
    }
 
9156
#endif
 
9157
#endif
 
9158
#ifdef TARGET_NR_prlimit64
 
9159
    case TARGET_NR_prlimit64:
 
9160
    {
 
9161
        /* args: pid, resource number, ptr to new rlimit, ptr to old rlimit */
 
9162
        struct target_rlimit64 *target_rnew, *target_rold;
 
9163
        struct host_rlimit64 rnew, rold, *rnewp = 0;
 
9164
        if (arg3) {
 
9165
            if (!lock_user_struct(VERIFY_READ, target_rnew, arg3, 1)) {
 
9166
                goto efault;
 
9167
            }
 
9168
            rnew.rlim_cur = tswap64(target_rnew->rlim_cur);
 
9169
            rnew.rlim_max = tswap64(target_rnew->rlim_max);
 
9170
            unlock_user_struct(target_rnew, arg3, 0);
 
9171
            rnewp = &rnew;
 
9172
        }
 
9173
 
 
9174
        ret = get_errno(sys_prlimit64(arg1, arg2, rnewp, arg4 ? &rold : 0));
 
9175
        if (!is_error(ret) && arg4) {
 
9176
            if (!lock_user_struct(VERIFY_WRITE, target_rold, arg4, 1)) {
 
9177
                goto efault;
 
9178
            }
 
9179
            target_rold->rlim_cur = tswap64(rold.rlim_cur);
 
9180
            target_rold->rlim_max = tswap64(rold.rlim_max);
 
9181
            unlock_user_struct(target_rold, arg4, 1);
 
9182
        }
 
9183
        break;
 
9184
    }
 
9185
#endif
 
9186
#ifdef TARGET_NR_gethostname
 
9187
    case TARGET_NR_gethostname:
 
9188
    {
 
9189
        char *name = lock_user(VERIFY_WRITE, arg1, arg2, 0);
 
9190
        if (name) {
 
9191
            ret = get_errno(gethostname(name, arg2));
 
9192
            unlock_user(name, arg1, arg2);
 
9193
        } else {
 
9194
            ret = -TARGET_EFAULT;
 
9195
        }
 
9196
        break;
 
9197
    }
 
9198
#endif
 
9199
#ifdef TARGET_NR_atomic_cmpxchg_32
 
9200
    case TARGET_NR_atomic_cmpxchg_32:
 
9201
    {
 
9202
        /* should use start_exclusive from main.c */
 
9203
        abi_ulong mem_value;
 
9204
        if (get_user_u32(mem_value, arg6)) {
 
9205
            target_siginfo_t info;
 
9206
            info.si_signo = SIGSEGV;
 
9207
            info.si_errno = 0;
 
9208
            info.si_code = TARGET_SEGV_MAPERR;
 
9209
            info._sifields._sigfault._addr = arg6;
 
9210
            queue_signal((CPUArchState *)cpu_env, info.si_signo, &info);
 
9211
            ret = 0xdeadbeef;
 
9212
 
 
9213
        }
 
9214
        if (mem_value == arg2)
 
9215
            put_user_u32(arg1, arg6);
 
9216
        ret = mem_value;
 
9217
        break;
 
9218
    }
 
9219
#endif
 
9220
#ifdef TARGET_NR_atomic_barrier
 
9221
    case TARGET_NR_atomic_barrier:
 
9222
    {
 
9223
        /* Like the kernel implementation and the qemu arm barrier, no-op this? */
 
9224
        break;
 
9225
    }
 
9226
#endif
 
9227
    default:
 
9228
    unimplemented:
 
9229
        gemu_log("qemu: Unsupported syscall: %d\n", num);
 
9230
#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
 
9231
    unimplemented_nowarn:
 
9232
#endif
 
9233
        ret = -TARGET_ENOSYS;
 
9234
        break;
 
9235
    }
 
9236
fail:
 
9237
#ifdef DEBUG
 
9238
    gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
 
9239
#endif
 
9240
    if(do_strace)
 
9241
        print_syscall_ret(num, ret);
 
9242
    return ret;
 
9243
efault:
 
9244
    ret = -TARGET_EFAULT;
 
9245
    goto fail;
 
9246
}