Statistics
| Branch: | Revision:

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

History | View | Annotate | Download (251.9 kB)

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