Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ 4f690853

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