Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ 6ad0a1ed

History | View | Annotate | Download (231.1 kB)

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