linux-user: return EINVAL on incorrect sockaddr
[qemu/mini2440/sniper_sniper_test.git] / linux-user / syscall.c
blob8296e5e43f83d864a84ef40a8fe95d6bc5d64d37
1 /*
2 * Linux syscalls
4 * Copyright (c) 2003 Fabrice Bellard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 * MA 02110-1301, USA.
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <stdarg.h>
24 #include <string.h>
25 #include <elf.h>
26 #include <endian.h>
27 #include <errno.h>
28 #include <unistd.h>
29 #include <fcntl.h>
30 #include <time.h>
31 #include <limits.h>
32 #include <sys/types.h>
33 #include <sys/ipc.h>
34 #include <sys/msg.h>
35 #include <sys/wait.h>
36 #include <sys/time.h>
37 #include <sys/stat.h>
38 #include <sys/mount.h>
39 #include <sys/prctl.h>
40 #include <sys/resource.h>
41 #include <sys/mman.h>
42 #include <sys/swap.h>
43 #include <signal.h>
44 #include <sched.h>
45 #include <sys/socket.h>
46 #include <sys/uio.h>
47 #include <sys/poll.h>
48 #include <sys/times.h>
49 #include <sys/shm.h>
50 #include <sys/sem.h>
51 #include <sys/statfs.h>
52 #include <utime.h>
53 #include <sys/sysinfo.h>
54 //#include <sys/user.h>
55 #include <netinet/ip.h>
56 #include <netinet/tcp.h>
57 #include <qemu-common.h>
58 #ifdef HAVE_GPROF
59 #include <sys/gmon.h>
60 #endif
62 #define termios host_termios
63 #define winsize host_winsize
64 #define termio host_termio
65 #define sgttyb host_sgttyb /* same as target */
66 #define tchars host_tchars /* same as target */
67 #define ltchars host_ltchars /* same as target */
69 #include <linux/termios.h>
70 #include <linux/unistd.h>
71 #include <linux/utsname.h>
72 #include <linux/cdrom.h>
73 #include <linux/hdreg.h>
74 #include <linux/soundcard.h>
75 #include <linux/kd.h>
76 #include <linux/mtio.h>
77 #include "linux_loop.h"
79 #include "qemu.h"
80 #include "qemu-common.h"
82 #if defined(USE_NPTL)
83 #include <linux/futex.h>
84 #define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
85 CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
86 #else
87 /* XXX: Hardcode the above values. */
88 #define CLONE_NPTL_FLAGS2 0
89 #endif
91 //#define DEBUG
93 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \
94 || defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS)
95 /* 16 bit uid wrappers emulation */
96 #define USE_UID16
97 #endif
99 //#include <linux/msdos_fs.h>
100 #define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct linux_dirent [2])
101 #define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct linux_dirent [2])
104 #undef _syscall0
105 #undef _syscall1
106 #undef _syscall2
107 #undef _syscall3
108 #undef _syscall4
109 #undef _syscall5
110 #undef _syscall6
112 #define _syscall0(type,name) \
113 static type name (void) \
115 return syscall(__NR_##name); \
118 #define _syscall1(type,name,type1,arg1) \
119 static type name (type1 arg1) \
121 return syscall(__NR_##name, arg1); \
124 #define _syscall2(type,name,type1,arg1,type2,arg2) \
125 static type name (type1 arg1,type2 arg2) \
127 return syscall(__NR_##name, arg1, arg2); \
130 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
131 static type name (type1 arg1,type2 arg2,type3 arg3) \
133 return syscall(__NR_##name, arg1, arg2, arg3); \
136 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
137 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4) \
139 return syscall(__NR_##name, arg1, arg2, arg3, arg4); \
142 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
143 type5,arg5) \
144 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
146 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5); \
150 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
151 type5,arg5,type6,arg6) \
152 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \
153 type6 arg6) \
155 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6); \
159 #define __NR_sys_exit __NR_exit
160 #define __NR_sys_uname __NR_uname
161 #define __NR_sys_faccessat __NR_faccessat
162 #define __NR_sys_fchmodat __NR_fchmodat
163 #define __NR_sys_fchownat __NR_fchownat
164 #define __NR_sys_fstatat64 __NR_fstatat64
165 #define __NR_sys_futimesat __NR_futimesat
166 #define __NR_sys_getcwd1 __NR_getcwd
167 #define __NR_sys_getdents __NR_getdents
168 #define __NR_sys_getdents64 __NR_getdents64
169 #define __NR_sys_getpriority __NR_getpriority
170 #define __NR_sys_linkat __NR_linkat
171 #define __NR_sys_mkdirat __NR_mkdirat
172 #define __NR_sys_mknodat __NR_mknodat
173 #define __NR_sys_openat __NR_openat
174 #define __NR_sys_readlinkat __NR_readlinkat
175 #define __NR_sys_renameat __NR_renameat
176 #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
177 #define __NR_sys_symlinkat __NR_symlinkat
178 #define __NR_sys_syslog __NR_syslog
179 #define __NR_sys_tgkill __NR_tgkill
180 #define __NR_sys_tkill __NR_tkill
181 #define __NR_sys_unlinkat __NR_unlinkat
182 #define __NR_sys_utimensat __NR_utimensat
183 #define __NR_sys_futex __NR_futex
184 #define __NR_sys_inotify_init __NR_inotify_init
185 #define __NR_sys_inotify_add_watch __NR_inotify_add_watch
186 #define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
188 #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
189 #define __NR__llseek __NR_lseek
190 #endif
192 #ifdef __NR_gettid
193 _syscall0(int, gettid)
194 #else
195 /* This is a replacement for the host gettid() and must return a host
196 errno. */
197 static int gettid(void) {
198 return -ENOSYS;
200 #endif
201 _syscall1(int,sys_exit,int,status)
202 _syscall1(int,sys_uname,struct new_utsname *,buf)
203 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
204 _syscall4(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode,int,flags)
205 #endif
206 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
207 _syscall4(int,sys_fchmodat,int,dirfd,const char *,pathname,
208 mode_t,mode,int,flags)
209 #endif
210 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) && defined(USE_UID16)
211 _syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
212 uid_t,owner,gid_t,group,int,flags)
213 #endif
214 #if defined(TARGET_NR_fstatat64) && defined(__NR_fstatat64)
215 _syscall4(int,sys_fstatat64,int,dirfd,const char *,pathname,
216 struct stat *,buf,int,flags)
217 #endif
218 #if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
219 _syscall3(int,sys_futimesat,int,dirfd,const char *,pathname,
220 const struct timeval *,times)
221 #endif
222 _syscall2(int,sys_getcwd1,char *,buf,size_t,size)
223 #if TARGET_ABI_BITS == 32
224 _syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
225 #endif
226 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
227 _syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
228 #endif
229 _syscall2(int, sys_getpriority, int, which, int, who);
230 #if !defined (__x86_64__)
231 _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo,
232 loff_t *, res, uint, wh);
233 #endif
234 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
235 _syscall5(int,sys_linkat,int,olddirfd,const char *,oldpath,
236 int,newdirfd,const char *,newpath,int,flags)
237 #endif
238 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
239 _syscall3(int,sys_mkdirat,int,dirfd,const char *,pathname,mode_t,mode)
240 #endif
241 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
242 _syscall4(int,sys_mknodat,int,dirfd,const char *,pathname,
243 mode_t,mode,dev_t,dev)
244 #endif
245 #if defined(TARGET_NR_openat) && defined(__NR_openat)
246 _syscall4(int,sys_openat,int,dirfd,const char *,pathname,int,flags,mode_t,mode)
247 #endif
248 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
249 _syscall4(int,sys_readlinkat,int,dirfd,const char *,pathname,
250 char *,buf,size_t,bufsize)
251 #endif
252 #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
253 _syscall4(int,sys_renameat,int,olddirfd,const char *,oldpath,
254 int,newdirfd,const char *,newpath)
255 #endif
256 _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
257 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
258 _syscall3(int,sys_symlinkat,const char *,oldpath,
259 int,newdirfd,const char *,newpath)
260 #endif
261 _syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
262 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
263 _syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
264 #endif
265 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
266 _syscall2(int,sys_tkill,int,tid,int,sig)
267 #endif
268 #ifdef __NR_exit_group
269 _syscall1(int,exit_group,int,error_code)
270 #endif
271 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
272 _syscall1(int,set_tid_address,int *,tidptr)
273 #endif
274 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
275 _syscall3(int,sys_unlinkat,int,dirfd,const char *,pathname,int,flags)
276 #endif
277 #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
278 _syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
279 const struct timespec *,tsp,int,flags)
280 #endif
281 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
282 _syscall0(int,sys_inotify_init)
283 #endif
284 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
285 _syscall3(int,sys_inotify_add_watch,int,fd,const char *,pathname,uint32_t,mask)
286 #endif
287 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
288 _syscall2(int,sys_inotify_rm_watch,int,fd,uint32_t,wd)
289 #endif
290 #if defined(USE_NPTL)
291 #if defined(TARGET_NR_futex) && defined(__NR_futex)
292 _syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
293 const struct timespec *,timeout,int *,uaddr2,int,val3)
294 #endif
295 #endif
297 extern int personality(int);
298 extern int flock(int, int);
299 extern int setfsuid(int);
300 extern int setfsgid(int);
301 extern int setgroups(int, gid_t *);
303 #define ERRNO_TABLE_SIZE 1200
305 /* target_to_host_errno_table[] is initialized from
306 * host_to_target_errno_table[] in syscall_init(). */
307 static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
311 * This list is the union of errno values overridden in asm-<arch>/errno.h
312 * minus the errnos that are not actually generic to all archs.
314 static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
315 [EIDRM] = TARGET_EIDRM,
316 [ECHRNG] = TARGET_ECHRNG,
317 [EL2NSYNC] = TARGET_EL2NSYNC,
318 [EL3HLT] = TARGET_EL3HLT,
319 [EL3RST] = TARGET_EL3RST,
320 [ELNRNG] = TARGET_ELNRNG,
321 [EUNATCH] = TARGET_EUNATCH,
322 [ENOCSI] = TARGET_ENOCSI,
323 [EL2HLT] = TARGET_EL2HLT,
324 [EDEADLK] = TARGET_EDEADLK,
325 [ENOLCK] = TARGET_ENOLCK,
326 [EBADE] = TARGET_EBADE,
327 [EBADR] = TARGET_EBADR,
328 [EXFULL] = TARGET_EXFULL,
329 [ENOANO] = TARGET_ENOANO,
330 [EBADRQC] = TARGET_EBADRQC,
331 [EBADSLT] = TARGET_EBADSLT,
332 [EBFONT] = TARGET_EBFONT,
333 [ENOSTR] = TARGET_ENOSTR,
334 [ENODATA] = TARGET_ENODATA,
335 [ETIME] = TARGET_ETIME,
336 [ENOSR] = TARGET_ENOSR,
337 [ENONET] = TARGET_ENONET,
338 [ENOPKG] = TARGET_ENOPKG,
339 [EREMOTE] = TARGET_EREMOTE,
340 [ENOLINK] = TARGET_ENOLINK,
341 [EADV] = TARGET_EADV,
342 [ESRMNT] = TARGET_ESRMNT,
343 [ECOMM] = TARGET_ECOMM,
344 [EPROTO] = TARGET_EPROTO,
345 [EDOTDOT] = TARGET_EDOTDOT,
346 [EMULTIHOP] = TARGET_EMULTIHOP,
347 [EBADMSG] = TARGET_EBADMSG,
348 [ENAMETOOLONG] = TARGET_ENAMETOOLONG,
349 [EOVERFLOW] = TARGET_EOVERFLOW,
350 [ENOTUNIQ] = TARGET_ENOTUNIQ,
351 [EBADFD] = TARGET_EBADFD,
352 [EREMCHG] = TARGET_EREMCHG,
353 [ELIBACC] = TARGET_ELIBACC,
354 [ELIBBAD] = TARGET_ELIBBAD,
355 [ELIBSCN] = TARGET_ELIBSCN,
356 [ELIBMAX] = TARGET_ELIBMAX,
357 [ELIBEXEC] = TARGET_ELIBEXEC,
358 [EILSEQ] = TARGET_EILSEQ,
359 [ENOSYS] = TARGET_ENOSYS,
360 [ELOOP] = TARGET_ELOOP,
361 [ERESTART] = TARGET_ERESTART,
362 [ESTRPIPE] = TARGET_ESTRPIPE,
363 [ENOTEMPTY] = TARGET_ENOTEMPTY,
364 [EUSERS] = TARGET_EUSERS,
365 [ENOTSOCK] = TARGET_ENOTSOCK,
366 [EDESTADDRREQ] = TARGET_EDESTADDRREQ,
367 [EMSGSIZE] = TARGET_EMSGSIZE,
368 [EPROTOTYPE] = TARGET_EPROTOTYPE,
369 [ENOPROTOOPT] = TARGET_ENOPROTOOPT,
370 [EPROTONOSUPPORT] = TARGET_EPROTONOSUPPORT,
371 [ESOCKTNOSUPPORT] = TARGET_ESOCKTNOSUPPORT,
372 [EOPNOTSUPP] = TARGET_EOPNOTSUPP,
373 [EPFNOSUPPORT] = TARGET_EPFNOSUPPORT,
374 [EAFNOSUPPORT] = TARGET_EAFNOSUPPORT,
375 [EADDRINUSE] = TARGET_EADDRINUSE,
376 [EADDRNOTAVAIL] = TARGET_EADDRNOTAVAIL,
377 [ENETDOWN] = TARGET_ENETDOWN,
378 [ENETUNREACH] = TARGET_ENETUNREACH,
379 [ENETRESET] = TARGET_ENETRESET,
380 [ECONNABORTED] = TARGET_ECONNABORTED,
381 [ECONNRESET] = TARGET_ECONNRESET,
382 [ENOBUFS] = TARGET_ENOBUFS,
383 [EISCONN] = TARGET_EISCONN,
384 [ENOTCONN] = TARGET_ENOTCONN,
385 [EUCLEAN] = TARGET_EUCLEAN,
386 [ENOTNAM] = TARGET_ENOTNAM,
387 [ENAVAIL] = TARGET_ENAVAIL,
388 [EISNAM] = TARGET_EISNAM,
389 [EREMOTEIO] = TARGET_EREMOTEIO,
390 [ESHUTDOWN] = TARGET_ESHUTDOWN,
391 [ETOOMANYREFS] = TARGET_ETOOMANYREFS,
392 [ETIMEDOUT] = TARGET_ETIMEDOUT,
393 [ECONNREFUSED] = TARGET_ECONNREFUSED,
394 [EHOSTDOWN] = TARGET_EHOSTDOWN,
395 [EHOSTUNREACH] = TARGET_EHOSTUNREACH,
396 [EALREADY] = TARGET_EALREADY,
397 [EINPROGRESS] = TARGET_EINPROGRESS,
398 [ESTALE] = TARGET_ESTALE,
399 [ECANCELED] = TARGET_ECANCELED,
400 [ENOMEDIUM] = TARGET_ENOMEDIUM,
401 [EMEDIUMTYPE] = TARGET_EMEDIUMTYPE,
402 #ifdef ENOKEY
403 [ENOKEY] = TARGET_ENOKEY,
404 #endif
405 #ifdef EKEYEXPIRED
406 [EKEYEXPIRED] = TARGET_EKEYEXPIRED,
407 #endif
408 #ifdef EKEYREVOKED
409 [EKEYREVOKED] = TARGET_EKEYREVOKED,
410 #endif
411 #ifdef EKEYREJECTED
412 [EKEYREJECTED] = TARGET_EKEYREJECTED,
413 #endif
414 #ifdef EOWNERDEAD
415 [EOWNERDEAD] = TARGET_EOWNERDEAD,
416 #endif
417 #ifdef ENOTRECOVERABLE
418 [ENOTRECOVERABLE] = TARGET_ENOTRECOVERABLE,
419 #endif
422 static inline int host_to_target_errno(int err)
424 if(host_to_target_errno_table[err])
425 return host_to_target_errno_table[err];
426 return err;
429 static inline int target_to_host_errno(int err)
431 if (target_to_host_errno_table[err])
432 return target_to_host_errno_table[err];
433 return err;
436 static inline abi_long get_errno(abi_long ret)
438 if (ret == -1)
439 return -host_to_target_errno(errno);
440 else
441 return ret;
444 static inline int is_error(abi_long ret)
446 return (abi_ulong)ret >= (abi_ulong)(-4096);
449 char *target_strerror(int err)
451 return strerror(target_to_host_errno(err));
454 static abi_ulong target_brk;
455 static abi_ulong target_original_brk;
457 void target_set_brk(abi_ulong new_brk)
459 target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
462 /* do_brk() must return target values and target errnos. */
463 abi_long do_brk(abi_ulong new_brk)
465 abi_ulong brk_page;
466 abi_long mapped_addr;
467 int new_alloc_size;
469 if (!new_brk)
470 return target_brk;
471 if (new_brk < target_original_brk)
472 return target_brk;
474 brk_page = HOST_PAGE_ALIGN(target_brk);
476 /* If the new brk is less than this, set it and we're done... */
477 if (new_brk < brk_page) {
478 target_brk = new_brk;
479 return target_brk;
482 /* We need to allocate more memory after the brk... */
483 new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
484 mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
485 PROT_READ|PROT_WRITE,
486 MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
488 if (!is_error(mapped_addr))
489 target_brk = new_brk;
491 return target_brk;
494 static inline abi_long copy_from_user_fdset(fd_set *fds,
495 abi_ulong target_fds_addr,
496 int n)
498 int i, nw, j, k;
499 abi_ulong b, *target_fds;
501 nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
502 if (!(target_fds = lock_user(VERIFY_READ,
503 target_fds_addr,
504 sizeof(abi_ulong) * nw,
505 1)))
506 return -TARGET_EFAULT;
508 FD_ZERO(fds);
509 k = 0;
510 for (i = 0; i < nw; i++) {
511 /* grab the abi_ulong */
512 __get_user(b, &target_fds[i]);
513 for (j = 0; j < TARGET_ABI_BITS; j++) {
514 /* check the bit inside the abi_ulong */
515 if ((b >> j) & 1)
516 FD_SET(k, fds);
517 k++;
521 unlock_user(target_fds, target_fds_addr, 0);
523 return 0;
526 static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
527 const fd_set *fds,
528 int n)
530 int i, nw, j, k;
531 abi_long v;
532 abi_ulong *target_fds;
534 nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
535 if (!(target_fds = lock_user(VERIFY_WRITE,
536 target_fds_addr,
537 sizeof(abi_ulong) * nw,
538 0)))
539 return -TARGET_EFAULT;
541 k = 0;
542 for (i = 0; i < nw; i++) {
543 v = 0;
544 for (j = 0; j < TARGET_ABI_BITS; j++) {
545 v |= ((FD_ISSET(k, fds) != 0) << j);
546 k++;
548 __put_user(v, &target_fds[i]);
551 unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
553 return 0;
556 #if defined(__alpha__)
557 #define HOST_HZ 1024
558 #else
559 #define HOST_HZ 100
560 #endif
562 static inline abi_long host_to_target_clock_t(long ticks)
564 #if HOST_HZ == TARGET_HZ
565 return ticks;
566 #else
567 return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
568 #endif
571 static inline abi_long host_to_target_rusage(abi_ulong target_addr,
572 const struct rusage *rusage)
574 struct target_rusage *target_rusage;
576 if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
577 return -TARGET_EFAULT;
578 target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
579 target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
580 target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
581 target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec);
582 target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss);
583 target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss);
584 target_rusage->ru_idrss = tswapl(rusage->ru_idrss);
585 target_rusage->ru_isrss = tswapl(rusage->ru_isrss);
586 target_rusage->ru_minflt = tswapl(rusage->ru_minflt);
587 target_rusage->ru_majflt = tswapl(rusage->ru_majflt);
588 target_rusage->ru_nswap = tswapl(rusage->ru_nswap);
589 target_rusage->ru_inblock = tswapl(rusage->ru_inblock);
590 target_rusage->ru_oublock = tswapl(rusage->ru_oublock);
591 target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd);
592 target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv);
593 target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);
594 target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
595 target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
596 unlock_user_struct(target_rusage, target_addr, 1);
598 return 0;
601 static inline abi_long copy_from_user_timeval(struct timeval *tv,
602 abi_ulong target_tv_addr)
604 struct target_timeval *target_tv;
606 if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
607 return -TARGET_EFAULT;
609 __get_user(tv->tv_sec, &target_tv->tv_sec);
610 __get_user(tv->tv_usec, &target_tv->tv_usec);
612 unlock_user_struct(target_tv, target_tv_addr, 0);
614 return 0;
617 static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
618 const struct timeval *tv)
620 struct target_timeval *target_tv;
622 if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
623 return -TARGET_EFAULT;
625 __put_user(tv->tv_sec, &target_tv->tv_sec);
626 __put_user(tv->tv_usec, &target_tv->tv_usec);
628 unlock_user_struct(target_tv, target_tv_addr, 1);
630 return 0;
634 /* do_select() must return target values and target errnos. */
635 static abi_long do_select(int n,
636 abi_ulong rfd_addr, abi_ulong wfd_addr,
637 abi_ulong efd_addr, abi_ulong target_tv_addr)
639 fd_set rfds, wfds, efds;
640 fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
641 struct timeval tv, *tv_ptr;
642 abi_long ret;
644 if (rfd_addr) {
645 if (copy_from_user_fdset(&rfds, rfd_addr, n))
646 return -TARGET_EFAULT;
647 rfds_ptr = &rfds;
648 } else {
649 rfds_ptr = NULL;
651 if (wfd_addr) {
652 if (copy_from_user_fdset(&wfds, wfd_addr, n))
653 return -TARGET_EFAULT;
654 wfds_ptr = &wfds;
655 } else {
656 wfds_ptr = NULL;
658 if (efd_addr) {
659 if (copy_from_user_fdset(&efds, efd_addr, n))
660 return -TARGET_EFAULT;
661 efds_ptr = &efds;
662 } else {
663 efds_ptr = NULL;
666 if (target_tv_addr) {
667 if (copy_from_user_timeval(&tv, target_tv_addr))
668 return -TARGET_EFAULT;
669 tv_ptr = &tv;
670 } else {
671 tv_ptr = NULL;
674 ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
676 if (!is_error(ret)) {
677 if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
678 return -TARGET_EFAULT;
679 if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
680 return -TARGET_EFAULT;
681 if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
682 return -TARGET_EFAULT;
684 if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
685 return -TARGET_EFAULT;
688 return ret;
691 static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
692 abi_ulong target_addr,
693 socklen_t len)
695 struct target_sockaddr *target_saddr;
697 target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
698 if (!target_saddr)
699 return -TARGET_EFAULT;
700 memcpy(addr, target_saddr, len);
701 addr->sa_family = tswap16(target_saddr->sa_family);
702 unlock_user(target_saddr, target_addr, 0);
704 return 0;
707 static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
708 struct sockaddr *addr,
709 socklen_t len)
711 struct target_sockaddr *target_saddr;
713 target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
714 if (!target_saddr)
715 return -TARGET_EFAULT;
716 memcpy(target_saddr, addr, len);
717 target_saddr->sa_family = tswap16(addr->sa_family);
718 unlock_user(target_saddr, target_addr, len);
720 return 0;
723 /* ??? Should this also swap msgh->name? */
724 static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
725 struct target_msghdr *target_msgh)
727 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
728 abi_long msg_controllen;
729 abi_ulong target_cmsg_addr;
730 struct target_cmsghdr *target_cmsg;
731 socklen_t space = 0;
733 msg_controllen = tswapl(target_msgh->msg_controllen);
734 if (msg_controllen < sizeof (struct target_cmsghdr))
735 goto the_end;
736 target_cmsg_addr = tswapl(target_msgh->msg_control);
737 target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
738 if (!target_cmsg)
739 return -TARGET_EFAULT;
741 while (cmsg && target_cmsg) {
742 void *data = CMSG_DATA(cmsg);
743 void *target_data = TARGET_CMSG_DATA(target_cmsg);
745 int len = tswapl(target_cmsg->cmsg_len)
746 - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
748 space += CMSG_SPACE(len);
749 if (space > msgh->msg_controllen) {
750 space -= CMSG_SPACE(len);
751 gemu_log("Host cmsg overflow\n");
752 break;
755 cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
756 cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
757 cmsg->cmsg_len = CMSG_LEN(len);
759 if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
760 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
761 memcpy(data, target_data, len);
762 } else {
763 int *fd = (int *)data;
764 int *target_fd = (int *)target_data;
765 int i, numfds = len / sizeof(int);
767 for (i = 0; i < numfds; i++)
768 fd[i] = tswap32(target_fd[i]);
771 cmsg = CMSG_NXTHDR(msgh, cmsg);
772 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
774 unlock_user(target_cmsg, target_cmsg_addr, 0);
775 the_end:
776 msgh->msg_controllen = space;
777 return 0;
780 /* ??? Should this also swap msgh->name? */
781 static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
782 struct msghdr *msgh)
784 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
785 abi_long msg_controllen;
786 abi_ulong target_cmsg_addr;
787 struct target_cmsghdr *target_cmsg;
788 socklen_t space = 0;
790 msg_controllen = tswapl(target_msgh->msg_controllen);
791 if (msg_controllen < sizeof (struct target_cmsghdr))
792 goto the_end;
793 target_cmsg_addr = tswapl(target_msgh->msg_control);
794 target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
795 if (!target_cmsg)
796 return -TARGET_EFAULT;
798 while (cmsg && target_cmsg) {
799 void *data = CMSG_DATA(cmsg);
800 void *target_data = TARGET_CMSG_DATA(target_cmsg);
802 int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
804 space += TARGET_CMSG_SPACE(len);
805 if (space > msg_controllen) {
806 space -= TARGET_CMSG_SPACE(len);
807 gemu_log("Target cmsg overflow\n");
808 break;
811 target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
812 target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
813 target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
815 if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
816 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
817 memcpy(target_data, data, len);
818 } else {
819 int *fd = (int *)data;
820 int *target_fd = (int *)target_data;
821 int i, numfds = len / sizeof(int);
823 for (i = 0; i < numfds; i++)
824 target_fd[i] = tswap32(fd[i]);
827 cmsg = CMSG_NXTHDR(msgh, cmsg);
828 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
830 unlock_user(target_cmsg, target_cmsg_addr, space);
831 the_end:
832 target_msgh->msg_controllen = tswapl(space);
833 return 0;
836 /* do_setsockopt() Must return target values and target errnos. */
837 static abi_long do_setsockopt(int sockfd, int level, int optname,
838 abi_ulong optval_addr, socklen_t optlen)
840 abi_long ret;
841 int val;
843 switch(level) {
844 case SOL_TCP:
845 /* TCP options all take an 'int' value. */
846 if (optlen < sizeof(uint32_t))
847 return -TARGET_EINVAL;
849 if (get_user_u32(val, optval_addr))
850 return -TARGET_EFAULT;
851 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
852 break;
853 case SOL_IP:
854 switch(optname) {
855 case IP_TOS:
856 case IP_TTL:
857 case IP_HDRINCL:
858 case IP_ROUTER_ALERT:
859 case IP_RECVOPTS:
860 case IP_RETOPTS:
861 case IP_PKTINFO:
862 case IP_MTU_DISCOVER:
863 case IP_RECVERR:
864 case IP_RECVTOS:
865 #ifdef IP_FREEBIND
866 case IP_FREEBIND:
867 #endif
868 case IP_MULTICAST_TTL:
869 case IP_MULTICAST_LOOP:
870 val = 0;
871 if (optlen >= sizeof(uint32_t)) {
872 if (get_user_u32(val, optval_addr))
873 return -TARGET_EFAULT;
874 } else if (optlen >= 1) {
875 if (get_user_u8(val, optval_addr))
876 return -TARGET_EFAULT;
878 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
879 break;
880 default:
881 goto unimplemented;
883 break;
884 case TARGET_SOL_SOCKET:
885 switch (optname) {
886 /* Options with 'int' argument. */
887 case TARGET_SO_DEBUG:
888 optname = SO_DEBUG;
889 break;
890 case TARGET_SO_REUSEADDR:
891 optname = SO_REUSEADDR;
892 break;
893 case TARGET_SO_TYPE:
894 optname = SO_TYPE;
895 break;
896 case TARGET_SO_ERROR:
897 optname = SO_ERROR;
898 break;
899 case TARGET_SO_DONTROUTE:
900 optname = SO_DONTROUTE;
901 break;
902 case TARGET_SO_BROADCAST:
903 optname = SO_BROADCAST;
904 break;
905 case TARGET_SO_SNDBUF:
906 optname = SO_SNDBUF;
907 break;
908 case TARGET_SO_RCVBUF:
909 optname = SO_RCVBUF;
910 break;
911 case TARGET_SO_KEEPALIVE:
912 optname = SO_KEEPALIVE;
913 break;
914 case TARGET_SO_OOBINLINE:
915 optname = SO_OOBINLINE;
916 break;
917 case TARGET_SO_NO_CHECK:
918 optname = SO_NO_CHECK;
919 break;
920 case TARGET_SO_PRIORITY:
921 optname = SO_PRIORITY;
922 break;
923 #ifdef SO_BSDCOMPAT
924 case TARGET_SO_BSDCOMPAT:
925 optname = SO_BSDCOMPAT;
926 break;
927 #endif
928 case TARGET_SO_PASSCRED:
929 optname = SO_PASSCRED;
930 break;
931 case TARGET_SO_TIMESTAMP:
932 optname = SO_TIMESTAMP;
933 break;
934 case TARGET_SO_RCVLOWAT:
935 optname = SO_RCVLOWAT;
936 break;
937 case TARGET_SO_RCVTIMEO:
938 optname = SO_RCVTIMEO;
939 break;
940 case TARGET_SO_SNDTIMEO:
941 optname = SO_SNDTIMEO;
942 break;
943 break;
944 default:
945 goto unimplemented;
947 if (optlen < sizeof(uint32_t))
948 return -TARGET_EINVAL;
950 if (get_user_u32(val, optval_addr))
951 return -TARGET_EFAULT;
952 ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
953 break;
954 default:
955 unimplemented:
956 gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
957 ret = -TARGET_ENOPROTOOPT;
959 return ret;
962 /* do_getsockopt() Must return target values and target errnos. */
963 static abi_long do_getsockopt(int sockfd, int level, int optname,
964 abi_ulong optval_addr, abi_ulong optlen)
966 abi_long ret;
967 int len, val;
968 socklen_t lv;
970 switch(level) {
971 case TARGET_SOL_SOCKET:
972 level = SOL_SOCKET;
973 switch (optname) {
974 case TARGET_SO_LINGER:
975 case TARGET_SO_RCVTIMEO:
976 case TARGET_SO_SNDTIMEO:
977 case TARGET_SO_PEERCRED:
978 case TARGET_SO_PEERNAME:
979 /* These don't just return a single integer */
980 goto unimplemented;
981 default:
982 goto int_case;
984 break;
985 case SOL_TCP:
986 /* TCP options all take an 'int' value. */
987 int_case:
988 if (get_user_u32(len, optlen))
989 return -TARGET_EFAULT;
990 if (len < 0)
991 return -TARGET_EINVAL;
992 lv = sizeof(int);
993 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
994 if (ret < 0)
995 return ret;
996 val = tswap32(val);
997 if (len > lv)
998 len = lv;
999 if (len == 4) {
1000 if (put_user_u32(val, optval_addr))
1001 return -TARGET_EFAULT;
1002 } else {
1003 if (put_user_u8(val, optval_addr))
1004 return -TARGET_EFAULT;
1006 if (put_user_u32(len, optlen))
1007 return -TARGET_EFAULT;
1008 break;
1009 case SOL_IP:
1010 switch(optname) {
1011 case IP_TOS:
1012 case IP_TTL:
1013 case IP_HDRINCL:
1014 case IP_ROUTER_ALERT:
1015 case IP_RECVOPTS:
1016 case IP_RETOPTS:
1017 case IP_PKTINFO:
1018 case IP_MTU_DISCOVER:
1019 case IP_RECVERR:
1020 case IP_RECVTOS:
1021 #ifdef IP_FREEBIND
1022 case IP_FREEBIND:
1023 #endif
1024 case IP_MULTICAST_TTL:
1025 case IP_MULTICAST_LOOP:
1026 if (get_user_u32(len, optlen))
1027 return -TARGET_EFAULT;
1028 if (len < 0)
1029 return -TARGET_EINVAL;
1030 lv = sizeof(int);
1031 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1032 if (ret < 0)
1033 return ret;
1034 if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
1035 len = 1;
1036 if (put_user_u32(len, optlen)
1037 || put_user_u8(val, optval_addr))
1038 return -TARGET_EFAULT;
1039 } else {
1040 if (len > sizeof(int))
1041 len = sizeof(int);
1042 if (put_user_u32(len, optlen)
1043 || put_user_u32(val, optval_addr))
1044 return -TARGET_EFAULT;
1046 break;
1047 default:
1048 ret = -TARGET_ENOPROTOOPT;
1049 break;
1051 break;
1052 default:
1053 unimplemented:
1054 gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1055 level, optname);
1056 ret = -TARGET_EOPNOTSUPP;
1057 break;
1059 return ret;
1062 /* FIXME
1063 * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1064 * other lock functions have a return code of 0 for failure.
1066 static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1067 int count, int copy)
1069 struct target_iovec *target_vec;
1070 abi_ulong base;
1071 int i;
1073 target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1074 if (!target_vec)
1075 return -TARGET_EFAULT;
1076 for(i = 0;i < count; i++) {
1077 base = tswapl(target_vec[i].iov_base);
1078 vec[i].iov_len = tswapl(target_vec[i].iov_len);
1079 if (vec[i].iov_len != 0) {
1080 vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
1081 /* Don't check lock_user return value. We must call writev even
1082 if a element has invalid base address. */
1083 } else {
1084 /* zero length pointer is ignored */
1085 vec[i].iov_base = NULL;
1088 unlock_user (target_vec, target_addr, 0);
1089 return 0;
1092 static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1093 int count, int copy)
1095 struct target_iovec *target_vec;
1096 abi_ulong base;
1097 int i;
1099 target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1100 if (!target_vec)
1101 return -TARGET_EFAULT;
1102 for(i = 0;i < count; i++) {
1103 if (target_vec[i].iov_base) {
1104 base = tswapl(target_vec[i].iov_base);
1105 unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1108 unlock_user (target_vec, target_addr, 0);
1110 return 0;
1113 /* do_socket() Must return target values and target errnos. */
1114 static abi_long do_socket(int domain, int type, int protocol)
1116 #if defined(TARGET_MIPS)
1117 switch(type) {
1118 case TARGET_SOCK_DGRAM:
1119 type = SOCK_DGRAM;
1120 break;
1121 case TARGET_SOCK_STREAM:
1122 type = SOCK_STREAM;
1123 break;
1124 case TARGET_SOCK_RAW:
1125 type = SOCK_RAW;
1126 break;
1127 case TARGET_SOCK_RDM:
1128 type = SOCK_RDM;
1129 break;
1130 case TARGET_SOCK_SEQPACKET:
1131 type = SOCK_SEQPACKET;
1132 break;
1133 case TARGET_SOCK_PACKET:
1134 type = SOCK_PACKET;
1135 break;
1137 #endif
1138 if (domain == PF_NETLINK)
1139 return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1140 return get_errno(socket(domain, type, protocol));
1143 /* MAX_SOCK_ADDR from linux/net/socket.c */
1144 #define MAX_SOCK_ADDR 128
1146 /* do_bind() Must return target values and target errnos. */
1147 static abi_long do_bind(int sockfd, abi_ulong target_addr,
1148 socklen_t addrlen)
1150 void *addr;
1152 if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
1153 return -TARGET_EINVAL;
1155 addr = alloca(addrlen);
1157 target_to_host_sockaddr(addr, target_addr, addrlen);
1158 return get_errno(bind(sockfd, addr, addrlen));
1161 /* do_connect() Must return target values and target errnos. */
1162 static abi_long do_connect(int sockfd, abi_ulong target_addr,
1163 socklen_t addrlen)
1165 void *addr;
1167 if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
1168 return -TARGET_EINVAL;
1170 addr = alloca(addrlen);
1172 target_to_host_sockaddr(addr, target_addr, addrlen);
1173 return get_errno(connect(sockfd, addr, addrlen));
1176 /* do_sendrecvmsg() Must return target values and target errnos. */
1177 static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1178 int flags, int send)
1180 abi_long ret, len;
1181 struct target_msghdr *msgp;
1182 struct msghdr msg;
1183 int count;
1184 struct iovec *vec;
1185 abi_ulong target_vec;
1187 /* FIXME */
1188 if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1189 msgp,
1190 target_msg,
1191 send ? 1 : 0))
1192 return -TARGET_EFAULT;
1193 if (msgp->msg_name) {
1194 msg.msg_namelen = tswap32(msgp->msg_namelen);
1195 msg.msg_name = alloca(msg.msg_namelen);
1196 target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
1197 msg.msg_namelen);
1198 } else {
1199 msg.msg_name = NULL;
1200 msg.msg_namelen = 0;
1202 msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
1203 msg.msg_control = alloca(msg.msg_controllen);
1204 msg.msg_flags = tswap32(msgp->msg_flags);
1206 count = tswapl(msgp->msg_iovlen);
1207 vec = alloca(count * sizeof(struct iovec));
1208 target_vec = tswapl(msgp->msg_iov);
1209 lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1210 msg.msg_iovlen = count;
1211 msg.msg_iov = vec;
1213 if (send) {
1214 ret = target_to_host_cmsg(&msg, msgp);
1215 if (ret == 0)
1216 ret = get_errno(sendmsg(fd, &msg, flags));
1217 } else {
1218 ret = get_errno(recvmsg(fd, &msg, flags));
1219 if (!is_error(ret)) {
1220 len = ret;
1221 ret = host_to_target_cmsg(msgp, &msg);
1222 if (!is_error(ret))
1223 ret = len;
1226 unlock_iovec(vec, target_vec, count, !send);
1227 unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1228 return ret;
1231 /* do_accept() Must return target values and target errnos. */
1232 static abi_long do_accept(int fd, abi_ulong target_addr,
1233 abi_ulong target_addrlen_addr)
1235 socklen_t addrlen;
1236 void *addr;
1237 abi_long ret;
1239 if (get_user_u32(addrlen, target_addrlen_addr))
1240 return -TARGET_EFAULT;
1242 if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
1243 return -TARGET_EINVAL;
1245 addr = alloca(addrlen);
1247 ret = get_errno(accept(fd, addr, &addrlen));
1248 if (!is_error(ret)) {
1249 host_to_target_sockaddr(target_addr, addr, addrlen);
1250 if (put_user_u32(addrlen, target_addrlen_addr))
1251 ret = -TARGET_EFAULT;
1253 return ret;
1256 /* do_getpeername() Must return target values and target errnos. */
1257 static abi_long do_getpeername(int fd, abi_ulong target_addr,
1258 abi_ulong target_addrlen_addr)
1260 socklen_t addrlen;
1261 void *addr;
1262 abi_long ret;
1264 if (get_user_u32(addrlen, target_addrlen_addr))
1265 return -TARGET_EFAULT;
1267 if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
1268 return -TARGET_EINVAL;
1270 addr = alloca(addrlen);
1272 ret = get_errno(getpeername(fd, addr, &addrlen));
1273 if (!is_error(ret)) {
1274 host_to_target_sockaddr(target_addr, addr, addrlen);
1275 if (put_user_u32(addrlen, target_addrlen_addr))
1276 ret = -TARGET_EFAULT;
1278 return ret;
1281 /* do_getsockname() Must return target values and target errnos. */
1282 static abi_long do_getsockname(int fd, abi_ulong target_addr,
1283 abi_ulong target_addrlen_addr)
1285 socklen_t addrlen;
1286 void *addr;
1287 abi_long ret;
1289 if (target_addr == 0)
1290 return get_errno(accept(fd, NULL, NULL));
1292 if (get_user_u32(addrlen, target_addrlen_addr))
1293 return -TARGET_EFAULT;
1295 if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
1296 return -TARGET_EINVAL;
1298 addr = alloca(addrlen);
1300 ret = get_errno(getsockname(fd, addr, &addrlen));
1301 if (!is_error(ret)) {
1302 host_to_target_sockaddr(target_addr, addr, addrlen);
1303 if (put_user_u32(addrlen, target_addrlen_addr))
1304 ret = -TARGET_EFAULT;
1306 return ret;
1309 /* do_socketpair() Must return target values and target errnos. */
1310 static abi_long do_socketpair(int domain, int type, int protocol,
1311 abi_ulong target_tab_addr)
1313 int tab[2];
1314 abi_long ret;
1316 ret = get_errno(socketpair(domain, type, protocol, tab));
1317 if (!is_error(ret)) {
1318 if (put_user_s32(tab[0], target_tab_addr)
1319 || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1320 ret = -TARGET_EFAULT;
1322 return ret;
1325 /* do_sendto() Must return target values and target errnos. */
1326 static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
1327 abi_ulong target_addr, socklen_t addrlen)
1329 void *addr;
1330 void *host_msg;
1331 abi_long ret;
1333 if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
1334 return -TARGET_EINVAL;
1336 host_msg = lock_user(VERIFY_READ, msg, len, 1);
1337 if (!host_msg)
1338 return -TARGET_EFAULT;
1339 if (target_addr) {
1340 addr = alloca(addrlen);
1341 target_to_host_sockaddr(addr, target_addr, addrlen);
1342 ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
1343 } else {
1344 ret = get_errno(send(fd, host_msg, len, flags));
1346 unlock_user(host_msg, msg, 0);
1347 return ret;
1350 /* do_recvfrom() Must return target values and target errnos. */
1351 static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
1352 abi_ulong target_addr,
1353 abi_ulong target_addrlen)
1355 socklen_t addrlen;
1356 void *addr;
1357 void *host_msg;
1358 abi_long ret;
1360 host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
1361 if (!host_msg)
1362 return -TARGET_EFAULT;
1363 if (target_addr) {
1364 if (get_user_u32(addrlen, target_addrlen)) {
1365 ret = -TARGET_EFAULT;
1366 goto fail;
1368 if (addrlen < 0 || addrlen > MAX_SOCK_ADDR) {
1369 ret = -TARGET_EINVAL;
1370 goto fail;
1372 addr = alloca(addrlen);
1373 ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
1374 } else {
1375 addr = NULL; /* To keep compiler quiet. */
1376 ret = get_errno(recv(fd, host_msg, len, flags));
1378 if (!is_error(ret)) {
1379 if (target_addr) {
1380 host_to_target_sockaddr(target_addr, addr, addrlen);
1381 if (put_user_u32(addrlen, target_addrlen)) {
1382 ret = -TARGET_EFAULT;
1383 goto fail;
1386 unlock_user(host_msg, msg, len);
1387 } else {
1388 fail:
1389 unlock_user(host_msg, msg, 0);
1391 return ret;
1394 #ifdef TARGET_NR_socketcall
1395 /* do_socketcall() Must return target values and target errnos. */
1396 static abi_long do_socketcall(int num, abi_ulong vptr)
1398 abi_long ret;
1399 const int n = sizeof(abi_ulong);
1401 switch(num) {
1402 case SOCKOP_socket:
1404 int domain, type, protocol;
1406 if (get_user_s32(domain, vptr)
1407 || get_user_s32(type, vptr + n)
1408 || get_user_s32(protocol, vptr + 2 * n))
1409 return -TARGET_EFAULT;
1411 ret = do_socket(domain, type, protocol);
1413 break;
1414 case SOCKOP_bind:
1416 int sockfd;
1417 abi_ulong target_addr;
1418 socklen_t addrlen;
1420 if (get_user_s32(sockfd, vptr)
1421 || get_user_ual(target_addr, vptr + n)
1422 || get_user_u32(addrlen, vptr + 2 * n))
1423 return -TARGET_EFAULT;
1425 ret = do_bind(sockfd, target_addr, addrlen);
1427 break;
1428 case SOCKOP_connect:
1430 int sockfd;
1431 abi_ulong target_addr;
1432 socklen_t addrlen;
1434 if (get_user_s32(sockfd, vptr)
1435 || get_user_ual(target_addr, vptr + n)
1436 || get_user_u32(addrlen, vptr + 2 * n))
1437 return -TARGET_EFAULT;
1439 ret = do_connect(sockfd, target_addr, addrlen);
1441 break;
1442 case SOCKOP_listen:
1444 int sockfd, backlog;
1446 if (get_user_s32(sockfd, vptr)
1447 || get_user_s32(backlog, vptr + n))
1448 return -TARGET_EFAULT;
1450 ret = get_errno(listen(sockfd, backlog));
1452 break;
1453 case SOCKOP_accept:
1455 int sockfd;
1456 abi_ulong target_addr, target_addrlen;
1458 if (get_user_s32(sockfd, vptr)
1459 || get_user_ual(target_addr, vptr + n)
1460 || get_user_u32(target_addrlen, vptr + 2 * n))
1461 return -TARGET_EFAULT;
1463 ret = do_accept(sockfd, target_addr, target_addrlen);
1465 break;
1466 case SOCKOP_getsockname:
1468 int sockfd;
1469 abi_ulong target_addr, target_addrlen;
1471 if (get_user_s32(sockfd, vptr)
1472 || get_user_ual(target_addr, vptr + n)
1473 || get_user_u32(target_addrlen, vptr + 2 * n))
1474 return -TARGET_EFAULT;
1476 ret = do_getsockname(sockfd, target_addr, target_addrlen);
1478 break;
1479 case SOCKOP_getpeername:
1481 int sockfd;
1482 abi_ulong target_addr, target_addrlen;
1484 if (get_user_s32(sockfd, vptr)
1485 || get_user_ual(target_addr, vptr + n)
1486 || get_user_u32(target_addrlen, vptr + 2 * n))
1487 return -TARGET_EFAULT;
1489 ret = do_getpeername(sockfd, target_addr, target_addrlen);
1491 break;
1492 case SOCKOP_socketpair:
1494 int domain, type, protocol;
1495 abi_ulong tab;
1497 if (get_user_s32(domain, vptr)
1498 || get_user_s32(type, vptr + n)
1499 || get_user_s32(protocol, vptr + 2 * n)
1500 || get_user_ual(tab, vptr + 3 * n))
1501 return -TARGET_EFAULT;
1503 ret = do_socketpair(domain, type, protocol, tab);
1505 break;
1506 case SOCKOP_send:
1508 int sockfd;
1509 abi_ulong msg;
1510 size_t len;
1511 int flags;
1513 if (get_user_s32(sockfd, vptr)
1514 || get_user_ual(msg, vptr + n)
1515 || get_user_ual(len, vptr + 2 * n)
1516 || get_user_s32(flags, vptr + 3 * n))
1517 return -TARGET_EFAULT;
1519 ret = do_sendto(sockfd, msg, len, flags, 0, 0);
1521 break;
1522 case SOCKOP_recv:
1524 int sockfd;
1525 abi_ulong msg;
1526 size_t len;
1527 int flags;
1529 if (get_user_s32(sockfd, vptr)
1530 || get_user_ual(msg, vptr + n)
1531 || get_user_ual(len, vptr + 2 * n)
1532 || get_user_s32(flags, vptr + 3 * n))
1533 return -TARGET_EFAULT;
1535 ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
1537 break;
1538 case SOCKOP_sendto:
1540 int sockfd;
1541 abi_ulong msg;
1542 size_t len;
1543 int flags;
1544 abi_ulong addr;
1545 socklen_t addrlen;
1547 if (get_user_s32(sockfd, vptr)
1548 || get_user_ual(msg, vptr + n)
1549 || get_user_ual(len, vptr + 2 * n)
1550 || get_user_s32(flags, vptr + 3 * n)
1551 || get_user_ual(addr, vptr + 4 * n)
1552 || get_user_u32(addrlen, vptr + 5 * n))
1553 return -TARGET_EFAULT;
1555 ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
1557 break;
1558 case SOCKOP_recvfrom:
1560 int sockfd;
1561 abi_ulong msg;
1562 size_t len;
1563 int flags;
1564 abi_ulong addr;
1565 socklen_t addrlen;
1567 if (get_user_s32(sockfd, vptr)
1568 || get_user_ual(msg, vptr + n)
1569 || get_user_ual(len, vptr + 2 * n)
1570 || get_user_s32(flags, vptr + 3 * n)
1571 || get_user_ual(addr, vptr + 4 * n)
1572 || get_user_u32(addrlen, vptr + 5 * n))
1573 return -TARGET_EFAULT;
1575 ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
1577 break;
1578 case SOCKOP_shutdown:
1580 int sockfd, how;
1582 if (get_user_s32(sockfd, vptr)
1583 || get_user_s32(how, vptr + n))
1584 return -TARGET_EFAULT;
1586 ret = get_errno(shutdown(sockfd, how));
1588 break;
1589 case SOCKOP_sendmsg:
1590 case SOCKOP_recvmsg:
1592 int fd;
1593 abi_ulong target_msg;
1594 int flags;
1596 if (get_user_s32(fd, vptr)
1597 || get_user_ual(target_msg, vptr + n)
1598 || get_user_s32(flags, vptr + 2 * n))
1599 return -TARGET_EFAULT;
1601 ret = do_sendrecvmsg(fd, target_msg, flags,
1602 (num == SOCKOP_sendmsg));
1604 break;
1605 case SOCKOP_setsockopt:
1607 int sockfd;
1608 int level;
1609 int optname;
1610 abi_ulong optval;
1611 socklen_t optlen;
1613 if (get_user_s32(sockfd, vptr)
1614 || get_user_s32(level, vptr + n)
1615 || get_user_s32(optname, vptr + 2 * n)
1616 || get_user_ual(optval, vptr + 3 * n)
1617 || get_user_u32(optlen, vptr + 4 * n))
1618 return -TARGET_EFAULT;
1620 ret = do_setsockopt(sockfd, level, optname, optval, optlen);
1622 break;
1623 case SOCKOP_getsockopt:
1625 int sockfd;
1626 int level;
1627 int optname;
1628 abi_ulong optval;
1629 socklen_t optlen;
1631 if (get_user_s32(sockfd, vptr)
1632 || get_user_s32(level, vptr + n)
1633 || get_user_s32(optname, vptr + 2 * n)
1634 || get_user_ual(optval, vptr + 3 * n)
1635 || get_user_u32(optlen, vptr + 4 * n))
1636 return -TARGET_EFAULT;
1638 ret = do_getsockopt(sockfd, level, optname, optval, optlen);
1640 break;
1641 default:
1642 gemu_log("Unsupported socketcall: %d\n", num);
1643 ret = -TARGET_ENOSYS;
1644 break;
1646 return ret;
1648 #endif
1650 #ifdef TARGET_NR_ipc
1651 #define N_SHM_REGIONS 32
1653 static struct shm_region {
1654 abi_ulong start;
1655 abi_ulong size;
1656 } shm_regions[N_SHM_REGIONS];
1657 #endif
1659 struct target_ipc_perm
1661 abi_long __key;
1662 abi_ulong uid;
1663 abi_ulong gid;
1664 abi_ulong cuid;
1665 abi_ulong cgid;
1666 unsigned short int mode;
1667 unsigned short int __pad1;
1668 unsigned short int __seq;
1669 unsigned short int __pad2;
1670 abi_ulong __unused1;
1671 abi_ulong __unused2;
1674 struct target_semid_ds
1676 struct target_ipc_perm sem_perm;
1677 abi_ulong sem_otime;
1678 abi_ulong __unused1;
1679 abi_ulong sem_ctime;
1680 abi_ulong __unused2;
1681 abi_ulong sem_nsems;
1682 abi_ulong __unused3;
1683 abi_ulong __unused4;
1686 static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
1687 abi_ulong target_addr)
1689 struct target_ipc_perm *target_ip;
1690 struct target_semid_ds *target_sd;
1692 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
1693 return -TARGET_EFAULT;
1694 target_ip=&(target_sd->sem_perm);
1695 host_ip->__key = tswapl(target_ip->__key);
1696 host_ip->uid = tswapl(target_ip->uid);
1697 host_ip->gid = tswapl(target_ip->gid);
1698 host_ip->cuid = tswapl(target_ip->cuid);
1699 host_ip->cgid = tswapl(target_ip->cgid);
1700 host_ip->mode = tswapl(target_ip->mode);
1701 unlock_user_struct(target_sd, target_addr, 0);
1702 return 0;
1705 static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
1706 struct ipc_perm *host_ip)
1708 struct target_ipc_perm *target_ip;
1709 struct target_semid_ds *target_sd;
1711 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
1712 return -TARGET_EFAULT;
1713 target_ip = &(target_sd->sem_perm);
1714 target_ip->__key = tswapl(host_ip->__key);
1715 target_ip->uid = tswapl(host_ip->uid);
1716 target_ip->gid = tswapl(host_ip->gid);
1717 target_ip->cuid = tswapl(host_ip->cuid);
1718 target_ip->cgid = tswapl(host_ip->cgid);
1719 target_ip->mode = tswapl(host_ip->mode);
1720 unlock_user_struct(target_sd, target_addr, 1);
1721 return 0;
1724 static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
1725 abi_ulong target_addr)
1727 struct target_semid_ds *target_sd;
1729 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
1730 return -TARGET_EFAULT;
1731 target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr);
1732 host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
1733 host_sd->sem_otime = tswapl(target_sd->sem_otime);
1734 host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
1735 unlock_user_struct(target_sd, target_addr, 0);
1736 return 0;
1739 static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
1740 struct semid_ds *host_sd)
1742 struct target_semid_ds *target_sd;
1744 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
1745 return -TARGET_EFAULT;
1746 host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm));
1747 target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
1748 target_sd->sem_otime = tswapl(host_sd->sem_otime);
1749 target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
1750 unlock_user_struct(target_sd, target_addr, 1);
1751 return 0;
1754 union semun {
1755 int val;
1756 struct semid_ds *buf;
1757 unsigned short *array;
1760 union target_semun {
1761 int val;
1762 abi_long buf;
1763 unsigned short int *array;
1766 static inline abi_long target_to_host_semun(int cmd,
1767 union semun *host_su,
1768 abi_ulong target_addr,
1769 struct semid_ds *ds)
1771 union target_semun *target_su;
1773 switch( cmd ) {
1774 case IPC_STAT:
1775 case IPC_SET:
1776 if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1777 return -TARGET_EFAULT;
1778 target_to_host_semid_ds(ds,target_su->buf);
1779 host_su->buf = ds;
1780 unlock_user_struct(target_su, target_addr, 0);
1781 break;
1782 case GETVAL:
1783 case SETVAL:
1784 if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1785 return -TARGET_EFAULT;
1786 host_su->val = tswapl(target_su->val);
1787 unlock_user_struct(target_su, target_addr, 0);
1788 break;
1789 case GETALL:
1790 case SETALL:
1791 if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1792 return -TARGET_EFAULT;
1793 *host_su->array = tswap16(*target_su->array);
1794 unlock_user_struct(target_su, target_addr, 0);
1795 break;
1796 default:
1797 gemu_log("semun operation not fully supported: %d\n", (int)cmd);
1799 return 0;
1802 static inline abi_long host_to_target_semun(int cmd,
1803 abi_ulong target_addr,
1804 union semun *host_su,
1805 struct semid_ds *ds)
1807 union target_semun *target_su;
1809 switch( cmd ) {
1810 case IPC_STAT:
1811 case IPC_SET:
1812 if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1813 return -TARGET_EFAULT;
1814 host_to_target_semid_ds(target_su->buf,ds);
1815 unlock_user_struct(target_su, target_addr, 1);
1816 break;
1817 case GETVAL:
1818 case SETVAL:
1819 if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1820 return -TARGET_EFAULT;
1821 target_su->val = tswapl(host_su->val);
1822 unlock_user_struct(target_su, target_addr, 1);
1823 break;
1824 case GETALL:
1825 case SETALL:
1826 if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1827 return -TARGET_EFAULT;
1828 *target_su->array = tswap16(*host_su->array);
1829 unlock_user_struct(target_su, target_addr, 1);
1830 break;
1831 default:
1832 gemu_log("semun operation not fully supported: %d\n", (int)cmd);
1834 return 0;
1837 static inline abi_long do_semctl(int first, int second, int third,
1838 abi_long ptr)
1840 union semun arg;
1841 struct semid_ds dsarg;
1842 int cmd = third&0xff;
1843 abi_long ret = 0;
1845 switch( cmd ) {
1846 case GETVAL:
1847 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1848 ret = get_errno(semctl(first, second, cmd, arg));
1849 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1850 break;
1851 case SETVAL:
1852 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1853 ret = get_errno(semctl(first, second, cmd, arg));
1854 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1855 break;
1856 case GETALL:
1857 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1858 ret = get_errno(semctl(first, second, cmd, arg));
1859 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1860 break;
1861 case SETALL:
1862 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1863 ret = get_errno(semctl(first, second, cmd, arg));
1864 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1865 break;
1866 case IPC_STAT:
1867 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1868 ret = get_errno(semctl(first, second, cmd, arg));
1869 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1870 break;
1871 case IPC_SET:
1872 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1873 ret = get_errno(semctl(first, second, cmd, arg));
1874 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1875 break;
1876 default:
1877 ret = get_errno(semctl(first, second, cmd, arg));
1880 return ret;
1883 struct target_msqid_ds
1885 struct target_ipc_perm msg_perm;
1886 abi_ulong msg_stime;
1887 #if TARGET_ABI_BITS == 32
1888 abi_ulong __unused1;
1889 #endif
1890 abi_ulong msg_rtime;
1891 #if TARGET_ABI_BITS == 32
1892 abi_ulong __unused2;
1893 #endif
1894 abi_ulong msg_ctime;
1895 #if TARGET_ABI_BITS == 32
1896 abi_ulong __unused3;
1897 #endif
1898 abi_ulong __msg_cbytes;
1899 abi_ulong msg_qnum;
1900 abi_ulong msg_qbytes;
1901 abi_ulong msg_lspid;
1902 abi_ulong msg_lrpid;
1903 abi_ulong __unused4;
1904 abi_ulong __unused5;
1907 static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
1908 abi_ulong target_addr)
1910 struct target_msqid_ds *target_md;
1912 if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
1913 return -TARGET_EFAULT;
1914 if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
1915 return -TARGET_EFAULT;
1916 host_md->msg_stime = tswapl(target_md->msg_stime);
1917 host_md->msg_rtime = tswapl(target_md->msg_rtime);
1918 host_md->msg_ctime = tswapl(target_md->msg_ctime);
1919 host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
1920 host_md->msg_qnum = tswapl(target_md->msg_qnum);
1921 host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
1922 host_md->msg_lspid = tswapl(target_md->msg_lspid);
1923 host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
1924 unlock_user_struct(target_md, target_addr, 0);
1925 return 0;
1928 static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
1929 struct msqid_ds *host_md)
1931 struct target_msqid_ds *target_md;
1933 if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
1934 return -TARGET_EFAULT;
1935 if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
1936 return -TARGET_EFAULT;
1937 target_md->msg_stime = tswapl(host_md->msg_stime);
1938 target_md->msg_rtime = tswapl(host_md->msg_rtime);
1939 target_md->msg_ctime = tswapl(host_md->msg_ctime);
1940 target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
1941 target_md->msg_qnum = tswapl(host_md->msg_qnum);
1942 target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
1943 target_md->msg_lspid = tswapl(host_md->msg_lspid);
1944 target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
1945 unlock_user_struct(target_md, target_addr, 1);
1946 return 0;
1949 struct target_msginfo {
1950 int msgpool;
1951 int msgmap;
1952 int msgmax;
1953 int msgmnb;
1954 int msgmni;
1955 int msgssz;
1956 int msgtql;
1957 unsigned short int msgseg;
1960 static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
1961 struct msginfo *host_msginfo)
1963 struct target_msginfo *target_msginfo;
1964 if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
1965 return -TARGET_EFAULT;
1966 __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
1967 __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
1968 __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
1969 __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
1970 __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
1971 __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
1972 __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
1973 __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
1974 unlock_user_struct(target_msginfo, target_addr, 1);
1975 return 0;
1978 static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
1980 struct msqid_ds dsarg;
1981 struct msginfo msginfo;
1982 abi_long ret = -TARGET_EINVAL;
1984 cmd &= 0xff;
1986 switch (cmd) {
1987 case IPC_STAT:
1988 case IPC_SET:
1989 case MSG_STAT:
1990 if (target_to_host_msqid_ds(&dsarg,ptr))
1991 return -TARGET_EFAULT;
1992 ret = get_errno(msgctl(msgid, cmd, &dsarg));
1993 if (host_to_target_msqid_ds(ptr,&dsarg))
1994 return -TARGET_EFAULT;
1995 break;
1996 case IPC_RMID:
1997 ret = get_errno(msgctl(msgid, cmd, NULL));
1998 break;
1999 case IPC_INFO:
2000 case MSG_INFO:
2001 ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
2002 if (host_to_target_msginfo(ptr, &msginfo))
2003 return -TARGET_EFAULT;
2004 break;
2007 return ret;
2010 struct target_msgbuf {
2011 abi_long mtype;
2012 char mtext[1];
2015 static inline abi_long do_msgsnd(int msqid, abi_long msgp,
2016 unsigned int msgsz, int msgflg)
2018 struct target_msgbuf *target_mb;
2019 struct msgbuf *host_mb;
2020 abi_long ret = 0;
2022 if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
2023 return -TARGET_EFAULT;
2024 host_mb = malloc(msgsz+sizeof(long));
2025 host_mb->mtype = (abi_long) tswapl(target_mb->mtype);
2026 memcpy(host_mb->mtext, target_mb->mtext, msgsz);
2027 ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
2028 free(host_mb);
2029 unlock_user_struct(target_mb, msgp, 0);
2031 return ret;
2034 static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2035 unsigned int msgsz, abi_long msgtyp,
2036 int msgflg)
2038 struct target_msgbuf *target_mb;
2039 char *target_mtext;
2040 struct msgbuf *host_mb;
2041 abi_long ret = 0;
2043 if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2044 return -TARGET_EFAULT;
2046 host_mb = malloc(msgsz+sizeof(long));
2047 ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapl(msgtyp), msgflg));
2049 if (ret > 0) {
2050 abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2051 target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2052 if (!target_mtext) {
2053 ret = -TARGET_EFAULT;
2054 goto end;
2056 memcpy(target_mb->mtext, host_mb->mtext, ret);
2057 unlock_user(target_mtext, target_mtext_addr, ret);
2060 target_mb->mtype = tswapl(host_mb->mtype);
2061 free(host_mb);
2063 end:
2064 if (target_mb)
2065 unlock_user_struct(target_mb, msgp, 1);
2066 return ret;
2069 #ifdef TARGET_NR_ipc
2070 /* ??? This only works with linear mappings. */
2071 /* do_ipc() must return target values and target errnos. */
2072 static abi_long do_ipc(unsigned int call, int first,
2073 int second, int third,
2074 abi_long ptr, abi_long fifth)
2076 int version;
2077 abi_long ret = 0;
2078 struct shmid_ds shm_info;
2079 int i;
2081 version = call >> 16;
2082 call &= 0xffff;
2084 switch (call) {
2085 case IPCOP_semop:
2086 ret = get_errno(semop(first,(struct sembuf *)g2h(ptr), second));
2087 break;
2089 case IPCOP_semget:
2090 ret = get_errno(semget(first, second, third));
2091 break;
2093 case IPCOP_semctl:
2094 ret = do_semctl(first, second, third, ptr);
2095 break;
2097 case IPCOP_semtimedop:
2098 gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2099 ret = -TARGET_ENOSYS;
2100 break;
2102 case IPCOP_msgget:
2103 ret = get_errno(msgget(first, second));
2104 break;
2106 case IPCOP_msgsnd:
2107 ret = do_msgsnd(first, ptr, second, third);
2108 break;
2110 case IPCOP_msgctl:
2111 ret = do_msgctl(first, second, ptr);
2112 break;
2114 case IPCOP_msgrcv:
2115 switch (version) {
2116 case 0:
2118 struct target_ipc_kludge {
2119 abi_long msgp;
2120 abi_long msgtyp;
2121 } *tmp;
2123 if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
2124 ret = -TARGET_EFAULT;
2125 break;
2128 ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
2130 unlock_user_struct(tmp, ptr, 0);
2131 break;
2133 default:
2134 ret = do_msgrcv(first, ptr, second, fifth, third);
2136 break;
2138 case IPCOP_shmat:
2140 abi_ulong raddr;
2141 void *host_addr;
2142 /* SHM_* flags are the same on all linux platforms */
2143 host_addr = shmat(first, (void *)g2h(ptr), second);
2144 if (host_addr == (void *)-1) {
2145 ret = get_errno((long)host_addr);
2146 break;
2148 raddr = h2g((unsigned long)host_addr);
2149 /* find out the length of the shared memory segment */
2151 ret = get_errno(shmctl(first, IPC_STAT, &shm_info));
2152 if (is_error(ret)) {
2153 /* can't get length, bail out */
2154 shmdt(host_addr);
2155 break;
2157 page_set_flags(raddr, raddr + shm_info.shm_segsz,
2158 PAGE_VALID | PAGE_READ |
2159 ((second & SHM_RDONLY)? 0: PAGE_WRITE));
2160 for (i = 0; i < N_SHM_REGIONS; ++i) {
2161 if (shm_regions[i].start == 0) {
2162 shm_regions[i].start = raddr;
2163 shm_regions[i].size = shm_info.shm_segsz;
2164 break;
2167 if (put_user_ual(raddr, third))
2168 return -TARGET_EFAULT;
2169 ret = 0;
2171 break;
2172 case IPCOP_shmdt:
2173 for (i = 0; i < N_SHM_REGIONS; ++i) {
2174 if (shm_regions[i].start == ptr) {
2175 shm_regions[i].start = 0;
2176 page_set_flags(ptr, shm_regions[i].size, 0);
2177 break;
2180 ret = get_errno(shmdt((void *)g2h(ptr)));
2181 break;
2183 case IPCOP_shmget:
2184 /* IPC_* flag values are the same on all linux platforms */
2185 ret = get_errno(shmget(first, second, third));
2186 break;
2188 /* IPC_* and SHM_* command values are the same on all linux platforms */
2189 case IPCOP_shmctl:
2190 switch(second) {
2191 case IPC_RMID:
2192 case SHM_LOCK:
2193 case SHM_UNLOCK:
2194 ret = get_errno(shmctl(first, second, NULL));
2195 break;
2196 default:
2197 goto unimplemented;
2199 break;
2200 default:
2201 unimplemented:
2202 gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2203 ret = -TARGET_ENOSYS;
2204 break;
2206 return ret;
2208 #endif
2210 /* kernel structure types definitions */
2211 #define IFNAMSIZ 16
2213 #define STRUCT(name, list...) STRUCT_ ## name,
2214 #define STRUCT_SPECIAL(name) STRUCT_ ## name,
2215 enum {
2216 #include "syscall_types.h"
2218 #undef STRUCT
2219 #undef STRUCT_SPECIAL
2221 #define STRUCT(name, list...) static const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };
2222 #define STRUCT_SPECIAL(name)
2223 #include "syscall_types.h"
2224 #undef STRUCT
2225 #undef STRUCT_SPECIAL
2227 typedef struct IOCTLEntry {
2228 unsigned int target_cmd;
2229 unsigned int host_cmd;
2230 const char *name;
2231 int access;
2232 const argtype arg_type[5];
2233 } IOCTLEntry;
2235 #define IOC_R 0x0001
2236 #define IOC_W 0x0002
2237 #define IOC_RW (IOC_R | IOC_W)
2239 #define MAX_STRUCT_SIZE 4096
2241 static IOCTLEntry ioctl_entries[] = {
2242 #define IOCTL(cmd, access, types...) \
2243 { TARGET_ ## cmd, cmd, #cmd, access, { types } },
2244 #include "ioctls.h"
2245 { 0, 0, },
2248 /* ??? Implement proper locking for ioctls. */
2249 /* do_ioctl() Must return target values and target errnos. */
2250 static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
2252 const IOCTLEntry *ie;
2253 const argtype *arg_type;
2254 abi_long ret;
2255 uint8_t buf_temp[MAX_STRUCT_SIZE];
2256 int target_size;
2257 void *argptr;
2259 ie = ioctl_entries;
2260 for(;;) {
2261 if (ie->target_cmd == 0) {
2262 gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
2263 return -TARGET_ENOSYS;
2265 if (ie->target_cmd == cmd)
2266 break;
2267 ie++;
2269 arg_type = ie->arg_type;
2270 #if defined(DEBUG)
2271 gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
2272 #endif
2273 switch(arg_type[0]) {
2274 case TYPE_NULL:
2275 /* no argument */
2276 ret = get_errno(ioctl(fd, ie->host_cmd));
2277 break;
2278 case TYPE_PTRVOID:
2279 case TYPE_INT:
2280 /* int argment */
2281 ret = get_errno(ioctl(fd, ie->host_cmd, arg));
2282 break;
2283 case TYPE_PTR:
2284 arg_type++;
2285 target_size = thunk_type_size(arg_type, 0);
2286 switch(ie->access) {
2287 case IOC_R:
2288 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2289 if (!is_error(ret)) {
2290 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2291 if (!argptr)
2292 return -TARGET_EFAULT;
2293 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2294 unlock_user(argptr, arg, target_size);
2296 break;
2297 case IOC_W:
2298 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2299 if (!argptr)
2300 return -TARGET_EFAULT;
2301 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2302 unlock_user(argptr, arg, 0);
2303 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2304 break;
2305 default:
2306 case IOC_RW:
2307 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2308 if (!argptr)
2309 return -TARGET_EFAULT;
2310 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2311 unlock_user(argptr, arg, 0);
2312 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2313 if (!is_error(ret)) {
2314 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2315 if (!argptr)
2316 return -TARGET_EFAULT;
2317 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2318 unlock_user(argptr, arg, target_size);
2320 break;
2322 break;
2323 default:
2324 gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
2325 (long)cmd, arg_type[0]);
2326 ret = -TARGET_ENOSYS;
2327 break;
2329 return ret;
2332 static const bitmask_transtbl iflag_tbl[] = {
2333 { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
2334 { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
2335 { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
2336 { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
2337 { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
2338 { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
2339 { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
2340 { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
2341 { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
2342 { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
2343 { TARGET_IXON, TARGET_IXON, IXON, IXON },
2344 { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
2345 { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
2346 { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
2347 { 0, 0, 0, 0 }
2350 static const bitmask_transtbl oflag_tbl[] = {
2351 { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
2352 { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
2353 { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
2354 { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
2355 { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
2356 { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
2357 { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
2358 { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
2359 { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
2360 { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
2361 { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
2362 { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
2363 { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
2364 { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
2365 { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
2366 { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
2367 { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
2368 { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
2369 { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
2370 { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
2371 { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
2372 { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
2373 { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
2374 { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
2375 { 0, 0, 0, 0 }
2378 static const bitmask_transtbl cflag_tbl[] = {
2379 { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
2380 { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
2381 { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
2382 { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
2383 { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
2384 { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
2385 { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
2386 { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
2387 { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
2388 { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
2389 { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
2390 { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
2391 { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
2392 { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
2393 { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
2394 { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
2395 { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
2396 { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
2397 { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
2398 { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
2399 { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
2400 { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
2401 { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
2402 { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
2403 { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
2404 { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
2405 { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
2406 { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
2407 { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
2408 { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
2409 { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
2410 { 0, 0, 0, 0 }
2413 static const bitmask_transtbl lflag_tbl[] = {
2414 { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
2415 { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
2416 { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
2417 { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
2418 { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
2419 { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
2420 { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
2421 { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
2422 { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
2423 { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
2424 { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
2425 { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
2426 { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
2427 { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
2428 { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
2429 { 0, 0, 0, 0 }
2432 static void target_to_host_termios (void *dst, const void *src)
2434 struct host_termios *host = dst;
2435 const struct target_termios *target = src;
2437 host->c_iflag =
2438 target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
2439 host->c_oflag =
2440 target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
2441 host->c_cflag =
2442 target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
2443 host->c_lflag =
2444 target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
2445 host->c_line = target->c_line;
2447 host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
2448 host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
2449 host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
2450 host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
2451 host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
2452 host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
2453 host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
2454 host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
2455 host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
2456 host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
2457 host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
2458 host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
2459 host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
2460 host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
2461 host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
2462 host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
2463 host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
2466 static void host_to_target_termios (void *dst, const void *src)
2468 struct target_termios *target = dst;
2469 const struct host_termios *host = src;
2471 target->c_iflag =
2472 tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
2473 target->c_oflag =
2474 tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
2475 target->c_cflag =
2476 tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
2477 target->c_lflag =
2478 tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
2479 target->c_line = host->c_line;
2481 target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
2482 target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
2483 target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
2484 target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
2485 target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
2486 target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
2487 target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
2488 target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
2489 target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
2490 target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
2491 target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
2492 target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
2493 target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
2494 target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
2495 target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
2496 target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
2497 target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
2500 static const StructEntry struct_termios_def = {
2501 .convert = { host_to_target_termios, target_to_host_termios },
2502 .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
2503 .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
2506 static bitmask_transtbl mmap_flags_tbl[] = {
2507 { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
2508 { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
2509 { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
2510 { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
2511 { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
2512 { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
2513 { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
2514 { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
2515 { 0, 0, 0, 0 }
2518 static bitmask_transtbl fcntl_flags_tbl[] = {
2519 { TARGET_O_ACCMODE, TARGET_O_WRONLY, O_ACCMODE, O_WRONLY, },
2520 { TARGET_O_ACCMODE, TARGET_O_RDWR, O_ACCMODE, O_RDWR, },
2521 { TARGET_O_CREAT, TARGET_O_CREAT, O_CREAT, O_CREAT, },
2522 { TARGET_O_EXCL, TARGET_O_EXCL, O_EXCL, O_EXCL, },
2523 { TARGET_O_NOCTTY, TARGET_O_NOCTTY, O_NOCTTY, O_NOCTTY, },
2524 { TARGET_O_TRUNC, TARGET_O_TRUNC, O_TRUNC, O_TRUNC, },
2525 { TARGET_O_APPEND, TARGET_O_APPEND, O_APPEND, O_APPEND, },
2526 { TARGET_O_NONBLOCK, TARGET_O_NONBLOCK, O_NONBLOCK, O_NONBLOCK, },
2527 { TARGET_O_SYNC, TARGET_O_SYNC, O_SYNC, O_SYNC, },
2528 { TARGET_FASYNC, TARGET_FASYNC, FASYNC, FASYNC, },
2529 { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
2530 { TARGET_O_NOFOLLOW, TARGET_O_NOFOLLOW, O_NOFOLLOW, O_NOFOLLOW, },
2531 { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
2532 #if defined(O_DIRECT)
2533 { TARGET_O_DIRECT, TARGET_O_DIRECT, O_DIRECT, O_DIRECT, },
2534 #endif
2535 { 0, 0, 0, 0 }
2538 #if defined(TARGET_I386)
2540 /* NOTE: there is really one LDT for all the threads */
2541 static uint8_t *ldt_table;
2543 static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
2545 int size;
2546 void *p;
2548 if (!ldt_table)
2549 return 0;
2550 size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
2551 if (size > bytecount)
2552 size = bytecount;
2553 p = lock_user(VERIFY_WRITE, ptr, size, 0);
2554 if (!p)
2555 return -TARGET_EFAULT;
2556 /* ??? Should this by byteswapped? */
2557 memcpy(p, ldt_table, size);
2558 unlock_user(p, ptr, size);
2559 return size;
2562 /* XXX: add locking support */
2563 static abi_long write_ldt(CPUX86State *env,
2564 abi_ulong ptr, unsigned long bytecount, int oldmode)
2566 struct target_modify_ldt_ldt_s ldt_info;
2567 struct target_modify_ldt_ldt_s *target_ldt_info;
2568 int seg_32bit, contents, read_exec_only, limit_in_pages;
2569 int seg_not_present, useable, lm;
2570 uint32_t *lp, entry_1, entry_2;
2572 if (bytecount != sizeof(ldt_info))
2573 return -TARGET_EINVAL;
2574 if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
2575 return -TARGET_EFAULT;
2576 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2577 ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2578 ldt_info.limit = tswap32(target_ldt_info->limit);
2579 ldt_info.flags = tswap32(target_ldt_info->flags);
2580 unlock_user_struct(target_ldt_info, ptr, 0);
2582 if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
2583 return -TARGET_EINVAL;
2584 seg_32bit = ldt_info.flags & 1;
2585 contents = (ldt_info.flags >> 1) & 3;
2586 read_exec_only = (ldt_info.flags >> 3) & 1;
2587 limit_in_pages = (ldt_info.flags >> 4) & 1;
2588 seg_not_present = (ldt_info.flags >> 5) & 1;
2589 useable = (ldt_info.flags >> 6) & 1;
2590 #ifdef TARGET_ABI32
2591 lm = 0;
2592 #else
2593 lm = (ldt_info.flags >> 7) & 1;
2594 #endif
2595 if (contents == 3) {
2596 if (oldmode)
2597 return -TARGET_EINVAL;
2598 if (seg_not_present == 0)
2599 return -TARGET_EINVAL;
2601 /* allocate the LDT */
2602 if (!ldt_table) {
2603 env->ldt.base = target_mmap(0,
2604 TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
2605 PROT_READ|PROT_WRITE,
2606 MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
2607 if (env->ldt.base == -1)
2608 return -TARGET_ENOMEM;
2609 memset(g2h(env->ldt.base), 0,
2610 TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
2611 env->ldt.limit = 0xffff;
2612 ldt_table = g2h(env->ldt.base);
2615 /* NOTE: same code as Linux kernel */
2616 /* Allow LDTs to be cleared by the user. */
2617 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2618 if (oldmode ||
2619 (contents == 0 &&
2620 read_exec_only == 1 &&
2621 seg_32bit == 0 &&
2622 limit_in_pages == 0 &&
2623 seg_not_present == 1 &&
2624 useable == 0 )) {
2625 entry_1 = 0;
2626 entry_2 = 0;
2627 goto install;
2631 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2632 (ldt_info.limit & 0x0ffff);
2633 entry_2 = (ldt_info.base_addr & 0xff000000) |
2634 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2635 (ldt_info.limit & 0xf0000) |
2636 ((read_exec_only ^ 1) << 9) |
2637 (contents << 10) |
2638 ((seg_not_present ^ 1) << 15) |
2639 (seg_32bit << 22) |
2640 (limit_in_pages << 23) |
2641 (lm << 21) |
2642 0x7000;
2643 if (!oldmode)
2644 entry_2 |= (useable << 20);
2646 /* Install the new entry ... */
2647 install:
2648 lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
2649 lp[0] = tswap32(entry_1);
2650 lp[1] = tswap32(entry_2);
2651 return 0;
2654 /* specific and weird i386 syscalls */
2655 static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
2656 unsigned long bytecount)
2658 abi_long ret;
2660 switch (func) {
2661 case 0:
2662 ret = read_ldt(ptr, bytecount);
2663 break;
2664 case 1:
2665 ret = write_ldt(env, ptr, bytecount, 1);
2666 break;
2667 case 0x11:
2668 ret = write_ldt(env, ptr, bytecount, 0);
2669 break;
2670 default:
2671 ret = -TARGET_ENOSYS;
2672 break;
2674 return ret;
2677 #if defined(TARGET_I386) && defined(TARGET_ABI32)
2678 static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
2680 uint64_t *gdt_table = g2h(env->gdt.base);
2681 struct target_modify_ldt_ldt_s ldt_info;
2682 struct target_modify_ldt_ldt_s *target_ldt_info;
2683 int seg_32bit, contents, read_exec_only, limit_in_pages;
2684 int seg_not_present, useable, lm;
2685 uint32_t *lp, entry_1, entry_2;
2686 int i;
2688 lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
2689 if (!target_ldt_info)
2690 return -TARGET_EFAULT;
2691 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2692 ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2693 ldt_info.limit = tswap32(target_ldt_info->limit);
2694 ldt_info.flags = tswap32(target_ldt_info->flags);
2695 if (ldt_info.entry_number == -1) {
2696 for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
2697 if (gdt_table[i] == 0) {
2698 ldt_info.entry_number = i;
2699 target_ldt_info->entry_number = tswap32(i);
2700 break;
2704 unlock_user_struct(target_ldt_info, ptr, 1);
2706 if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN ||
2707 ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
2708 return -TARGET_EINVAL;
2709 seg_32bit = ldt_info.flags & 1;
2710 contents = (ldt_info.flags >> 1) & 3;
2711 read_exec_only = (ldt_info.flags >> 3) & 1;
2712 limit_in_pages = (ldt_info.flags >> 4) & 1;
2713 seg_not_present = (ldt_info.flags >> 5) & 1;
2714 useable = (ldt_info.flags >> 6) & 1;
2715 #ifdef TARGET_ABI32
2716 lm = 0;
2717 #else
2718 lm = (ldt_info.flags >> 7) & 1;
2719 #endif
2721 if (contents == 3) {
2722 if (seg_not_present == 0)
2723 return -TARGET_EINVAL;
2726 /* NOTE: same code as Linux kernel */
2727 /* Allow LDTs to be cleared by the user. */
2728 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2729 if ((contents == 0 &&
2730 read_exec_only == 1 &&
2731 seg_32bit == 0 &&
2732 limit_in_pages == 0 &&
2733 seg_not_present == 1 &&
2734 useable == 0 )) {
2735 entry_1 = 0;
2736 entry_2 = 0;
2737 goto install;
2741 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2742 (ldt_info.limit & 0x0ffff);
2743 entry_2 = (ldt_info.base_addr & 0xff000000) |
2744 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2745 (ldt_info.limit & 0xf0000) |
2746 ((read_exec_only ^ 1) << 9) |
2747 (contents << 10) |
2748 ((seg_not_present ^ 1) << 15) |
2749 (seg_32bit << 22) |
2750 (limit_in_pages << 23) |
2751 (useable << 20) |
2752 (lm << 21) |
2753 0x7000;
2755 /* Install the new entry ... */
2756 install:
2757 lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
2758 lp[0] = tswap32(entry_1);
2759 lp[1] = tswap32(entry_2);
2760 return 0;
2763 static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
2765 struct target_modify_ldt_ldt_s *target_ldt_info;
2766 uint64_t *gdt_table = g2h(env->gdt.base);
2767 uint32_t base_addr, limit, flags;
2768 int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
2769 int seg_not_present, useable, lm;
2770 uint32_t *lp, entry_1, entry_2;
2772 lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
2773 if (!target_ldt_info)
2774 return -TARGET_EFAULT;
2775 idx = tswap32(target_ldt_info->entry_number);
2776 if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
2777 idx > TARGET_GDT_ENTRY_TLS_MAX) {
2778 unlock_user_struct(target_ldt_info, ptr, 1);
2779 return -TARGET_EINVAL;
2781 lp = (uint32_t *)(gdt_table + idx);
2782 entry_1 = tswap32(lp[0]);
2783 entry_2 = tswap32(lp[1]);
2785 read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
2786 contents = (entry_2 >> 10) & 3;
2787 seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
2788 seg_32bit = (entry_2 >> 22) & 1;
2789 limit_in_pages = (entry_2 >> 23) & 1;
2790 useable = (entry_2 >> 20) & 1;
2791 #ifdef TARGET_ABI32
2792 lm = 0;
2793 #else
2794 lm = (entry_2 >> 21) & 1;
2795 #endif
2796 flags = (seg_32bit << 0) | (contents << 1) |
2797 (read_exec_only << 3) | (limit_in_pages << 4) |
2798 (seg_not_present << 5) | (useable << 6) | (lm << 7);
2799 limit = (entry_1 & 0xffff) | (entry_2 & 0xf0000);
2800 base_addr = (entry_1 >> 16) |
2801 (entry_2 & 0xff000000) |
2802 ((entry_2 & 0xff) << 16);
2803 target_ldt_info->base_addr = tswapl(base_addr);
2804 target_ldt_info->limit = tswap32(limit);
2805 target_ldt_info->flags = tswap32(flags);
2806 unlock_user_struct(target_ldt_info, ptr, 1);
2807 return 0;
2809 #endif /* TARGET_I386 && TARGET_ABI32 */
2811 #ifndef TARGET_ABI32
2812 static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
2814 abi_long ret;
2815 abi_ulong val;
2816 int idx;
2818 switch(code) {
2819 case TARGET_ARCH_SET_GS:
2820 case TARGET_ARCH_SET_FS:
2821 if (code == TARGET_ARCH_SET_GS)
2822 idx = R_GS;
2823 else
2824 idx = R_FS;
2825 cpu_x86_load_seg(env, idx, 0);
2826 env->segs[idx].base = addr;
2827 break;
2828 case TARGET_ARCH_GET_GS:
2829 case TARGET_ARCH_GET_FS:
2830 if (code == TARGET_ARCH_GET_GS)
2831 idx = R_GS;
2832 else
2833 idx = R_FS;
2834 val = env->segs[idx].base;
2835 if (put_user(val, addr, abi_ulong))
2836 return -TARGET_EFAULT;
2837 break;
2838 default:
2839 ret = -TARGET_EINVAL;
2840 break;
2842 return 0;
2844 #endif
2846 #endif /* defined(TARGET_I386) */
2848 #if defined(USE_NPTL)
2850 #define NEW_STACK_SIZE PTHREAD_STACK_MIN
2852 static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
2853 typedef struct {
2854 CPUState *env;
2855 pthread_mutex_t mutex;
2856 pthread_cond_t cond;
2857 pthread_t thread;
2858 uint32_t tid;
2859 abi_ulong child_tidptr;
2860 abi_ulong parent_tidptr;
2861 sigset_t sigmask;
2862 } new_thread_info;
2864 static void *clone_func(void *arg)
2866 new_thread_info *info = arg;
2867 CPUState *env;
2869 env = info->env;
2870 thread_env = env;
2871 info->tid = gettid();
2872 if (info->child_tidptr)
2873 put_user_u32(info->tid, info->child_tidptr);
2874 if (info->parent_tidptr)
2875 put_user_u32(info->tid, info->parent_tidptr);
2876 /* Enable signals. */
2877 sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
2878 /* Signal to the parent that we're ready. */
2879 pthread_mutex_lock(&info->mutex);
2880 pthread_cond_broadcast(&info->cond);
2881 pthread_mutex_unlock(&info->mutex);
2882 /* Wait until the parent has finshed initializing the tls state. */
2883 pthread_mutex_lock(&clone_lock);
2884 pthread_mutex_unlock(&clone_lock);
2885 cpu_loop(env);
2886 /* never exits */
2887 return NULL;
2889 #else
2890 /* this stack is the equivalent of the kernel stack associated with a
2891 thread/process */
2892 #define NEW_STACK_SIZE 8192
2894 static int clone_func(void *arg)
2896 CPUState *env = arg;
2897 cpu_loop(env);
2898 /* never exits */
2899 return 0;
2901 #endif
2903 /* do_fork() Must return host values and target errnos (unlike most
2904 do_*() functions). */
2905 static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
2906 abi_ulong parent_tidptr, target_ulong newtls,
2907 abi_ulong child_tidptr)
2909 int ret;
2910 TaskState *ts;
2911 uint8_t *new_stack;
2912 CPUState *new_env;
2913 #if defined(USE_NPTL)
2914 unsigned int nptl_flags;
2915 sigset_t sigmask;
2916 #endif
2918 /* Emulate vfork() with fork() */
2919 if (flags & CLONE_VFORK)
2920 flags &= ~(CLONE_VFORK | CLONE_VM);
2922 if (flags & CLONE_VM) {
2923 #if defined(USE_NPTL)
2924 new_thread_info info;
2925 pthread_attr_t attr;
2926 #endif
2927 ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
2928 init_task_state(ts);
2929 new_stack = ts->stack;
2930 /* we create a new CPU instance. */
2931 new_env = cpu_copy(env);
2932 /* Init regs that differ from the parent. */
2933 cpu_clone_regs(new_env, newsp);
2934 new_env->opaque = ts;
2935 #if defined(USE_NPTL)
2936 nptl_flags = flags;
2937 flags &= ~CLONE_NPTL_FLAGS2;
2939 /* TODO: Implement CLONE_CHILD_CLEARTID. */
2940 if (nptl_flags & CLONE_SETTLS)
2941 cpu_set_tls (new_env, newtls);
2943 /* Grab a mutex so that thread setup appears atomic. */
2944 pthread_mutex_lock(&clone_lock);
2946 memset(&info, 0, sizeof(info));
2947 pthread_mutex_init(&info.mutex, NULL);
2948 pthread_mutex_lock(&info.mutex);
2949 pthread_cond_init(&info.cond, NULL);
2950 info.env = new_env;
2951 if (nptl_flags & CLONE_CHILD_SETTID)
2952 info.child_tidptr = child_tidptr;
2953 if (nptl_flags & CLONE_PARENT_SETTID)
2954 info.parent_tidptr = parent_tidptr;
2956 ret = pthread_attr_init(&attr);
2957 ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE);
2958 /* It is not safe to deliver signals until the child has finished
2959 initializing, so temporarily block all signals. */
2960 sigfillset(&sigmask);
2961 sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
2963 ret = pthread_create(&info.thread, &attr, clone_func, &info);
2965 sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
2966 pthread_attr_destroy(&attr);
2967 if (ret == 0) {
2968 /* Wait for the child to initialize. */
2969 pthread_cond_wait(&info.cond, &info.mutex);
2970 ret = info.tid;
2971 if (flags & CLONE_PARENT_SETTID)
2972 put_user_u32(ret, parent_tidptr);
2973 } else {
2974 ret = -1;
2976 pthread_mutex_unlock(&info.mutex);
2977 pthread_cond_destroy(&info.cond);
2978 pthread_mutex_destroy(&info.mutex);
2979 pthread_mutex_unlock(&clone_lock);
2980 #else
2981 if (flags & CLONE_NPTL_FLAGS2)
2982 return -EINVAL;
2983 /* This is probably going to die very quickly, but do it anyway. */
2984 #ifdef __ia64__
2985 ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
2986 #else
2987 ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
2988 #endif
2989 #endif
2990 } else {
2991 /* if no CLONE_VM, we consider it is a fork */
2992 if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
2993 return -EINVAL;
2994 fork_start();
2995 ret = fork();
2996 if (ret == 0) {
2997 /* Child Process. */
2998 cpu_clone_regs(env, newsp);
2999 fork_end(1);
3000 #if defined(USE_NPTL)
3001 /* There is a race condition here. The parent process could
3002 theoretically read the TID in the child process before the child
3003 tid is set. This would require using either ptrace
3004 (not implemented) or having *_tidptr to point at a shared memory
3005 mapping. We can't repeat the spinlock hack used above because
3006 the child process gets its own copy of the lock. */
3007 if (flags & CLONE_CHILD_SETTID)
3008 put_user_u32(gettid(), child_tidptr);
3009 if (flags & CLONE_PARENT_SETTID)
3010 put_user_u32(gettid(), parent_tidptr);
3011 ts = (TaskState *)env->opaque;
3012 if (flags & CLONE_SETTLS)
3013 cpu_set_tls (env, newtls);
3014 /* TODO: Implement CLONE_CHILD_CLEARTID. */
3015 #endif
3016 } else {
3017 fork_end(0);
3020 return ret;
3023 static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
3025 struct flock fl;
3026 struct target_flock *target_fl;
3027 struct flock64 fl64;
3028 struct target_flock64 *target_fl64;
3029 abi_long ret;
3031 switch(cmd) {
3032 case TARGET_F_GETLK:
3033 if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3034 return -TARGET_EFAULT;
3035 fl.l_type = tswap16(target_fl->l_type);
3036 fl.l_whence = tswap16(target_fl->l_whence);
3037 fl.l_start = tswapl(target_fl->l_start);
3038 fl.l_len = tswapl(target_fl->l_len);
3039 fl.l_pid = tswapl(target_fl->l_pid);
3040 unlock_user_struct(target_fl, arg, 0);
3041 ret = get_errno(fcntl(fd, cmd, &fl));
3042 if (ret == 0) {
3043 if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
3044 return -TARGET_EFAULT;
3045 target_fl->l_type = tswap16(fl.l_type);
3046 target_fl->l_whence = tswap16(fl.l_whence);
3047 target_fl->l_start = tswapl(fl.l_start);
3048 target_fl->l_len = tswapl(fl.l_len);
3049 target_fl->l_pid = tswapl(fl.l_pid);
3050 unlock_user_struct(target_fl, arg, 1);
3052 break;
3054 case TARGET_F_SETLK:
3055 case TARGET_F_SETLKW:
3056 if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3057 return -TARGET_EFAULT;
3058 fl.l_type = tswap16(target_fl->l_type);
3059 fl.l_whence = tswap16(target_fl->l_whence);
3060 fl.l_start = tswapl(target_fl->l_start);
3061 fl.l_len = tswapl(target_fl->l_len);
3062 fl.l_pid = tswapl(target_fl->l_pid);
3063 unlock_user_struct(target_fl, arg, 0);
3064 ret = get_errno(fcntl(fd, cmd, &fl));
3065 break;
3067 case TARGET_F_GETLK64:
3068 if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3069 return -TARGET_EFAULT;
3070 fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3071 fl64.l_whence = tswap16(target_fl64->l_whence);
3072 fl64.l_start = tswapl(target_fl64->l_start);
3073 fl64.l_len = tswapl(target_fl64->l_len);
3074 fl64.l_pid = tswap16(target_fl64->l_pid);
3075 unlock_user_struct(target_fl64, arg, 0);
3076 ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
3077 if (ret == 0) {
3078 if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
3079 return -TARGET_EFAULT;
3080 target_fl64->l_type = tswap16(fl64.l_type) >> 1;
3081 target_fl64->l_whence = tswap16(fl64.l_whence);
3082 target_fl64->l_start = tswapl(fl64.l_start);
3083 target_fl64->l_len = tswapl(fl64.l_len);
3084 target_fl64->l_pid = tswapl(fl64.l_pid);
3085 unlock_user_struct(target_fl64, arg, 1);
3087 break;
3088 case TARGET_F_SETLK64:
3089 case TARGET_F_SETLKW64:
3090 if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3091 return -TARGET_EFAULT;
3092 fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3093 fl64.l_whence = tswap16(target_fl64->l_whence);
3094 fl64.l_start = tswapl(target_fl64->l_start);
3095 fl64.l_len = tswapl(target_fl64->l_len);
3096 fl64.l_pid = tswap16(target_fl64->l_pid);
3097 unlock_user_struct(target_fl64, arg, 0);
3098 ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
3099 break;
3101 case F_GETFL:
3102 ret = get_errno(fcntl(fd, cmd, arg));
3103 if (ret >= 0) {
3104 ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
3106 break;
3108 case F_SETFL:
3109 ret = get_errno(fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
3110 break;
3112 default:
3113 ret = get_errno(fcntl(fd, cmd, arg));
3114 break;
3116 return ret;
3119 #ifdef USE_UID16
3121 static inline int high2lowuid(int uid)
3123 if (uid > 65535)
3124 return 65534;
3125 else
3126 return uid;
3129 static inline int high2lowgid(int gid)
3131 if (gid > 65535)
3132 return 65534;
3133 else
3134 return gid;
3137 static inline int low2highuid(int uid)
3139 if ((int16_t)uid == -1)
3140 return -1;
3141 else
3142 return uid;
3145 static inline int low2highgid(int gid)
3147 if ((int16_t)gid == -1)
3148 return -1;
3149 else
3150 return gid;
3153 #endif /* USE_UID16 */
3155 void syscall_init(void)
3157 IOCTLEntry *ie;
3158 const argtype *arg_type;
3159 int size;
3160 int i;
3162 #define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3163 #define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3164 #include "syscall_types.h"
3165 #undef STRUCT
3166 #undef STRUCT_SPECIAL
3168 /* we patch the ioctl size if necessary. We rely on the fact that
3169 no ioctl has all the bits at '1' in the size field */
3170 ie = ioctl_entries;
3171 while (ie->target_cmd != 0) {
3172 if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
3173 TARGET_IOC_SIZEMASK) {
3174 arg_type = ie->arg_type;
3175 if (arg_type[0] != TYPE_PTR) {
3176 fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
3177 ie->target_cmd);
3178 exit(1);
3180 arg_type++;
3181 size = thunk_type_size(arg_type, 0);
3182 ie->target_cmd = (ie->target_cmd &
3183 ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
3184 (size << TARGET_IOC_SIZESHIFT);
3187 /* Build target_to_host_errno_table[] table from
3188 * host_to_target_errno_table[]. */
3189 for (i=0; i < ERRNO_TABLE_SIZE; i++)
3190 target_to_host_errno_table[host_to_target_errno_table[i]] = i;
3192 /* automatic consistency check if same arch */
3193 #if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
3194 (defined(__x86_64__) && defined(TARGET_X86_64))
3195 if (unlikely(ie->target_cmd != ie->host_cmd)) {
3196 fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
3197 ie->name, ie->target_cmd, ie->host_cmd);
3199 #endif
3200 ie++;
3204 #if TARGET_ABI_BITS == 32
3205 static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
3207 #ifdef TARGET_WORDS_BIGENDIAN
3208 return ((uint64_t)word0 << 32) | word1;
3209 #else
3210 return ((uint64_t)word1 << 32) | word0;
3211 #endif
3213 #else /* TARGET_ABI_BITS == 32 */
3214 static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
3216 return word0;
3218 #endif /* TARGET_ABI_BITS != 32 */
3220 #ifdef TARGET_NR_truncate64
3221 static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
3222 abi_long arg2,
3223 abi_long arg3,
3224 abi_long arg4)
3226 #ifdef TARGET_ARM
3227 if (((CPUARMState *)cpu_env)->eabi)
3229 arg2 = arg3;
3230 arg3 = arg4;
3232 #endif
3233 return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
3235 #endif
3237 #ifdef TARGET_NR_ftruncate64
3238 static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
3239 abi_long arg2,
3240 abi_long arg3,
3241 abi_long arg4)
3243 #ifdef TARGET_ARM
3244 if (((CPUARMState *)cpu_env)->eabi)
3246 arg2 = arg3;
3247 arg3 = arg4;
3249 #endif
3250 return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
3252 #endif
3254 static inline abi_long target_to_host_timespec(struct timespec *host_ts,
3255 abi_ulong target_addr)
3257 struct target_timespec *target_ts;
3259 if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
3260 return -TARGET_EFAULT;
3261 host_ts->tv_sec = tswapl(target_ts->tv_sec);
3262 host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
3263 unlock_user_struct(target_ts, target_addr, 0);
3264 return 0;
3267 static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3268 struct timespec *host_ts)
3270 struct target_timespec *target_ts;
3272 if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
3273 return -TARGET_EFAULT;
3274 target_ts->tv_sec = tswapl(host_ts->tv_sec);
3275 target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
3276 unlock_user_struct(target_ts, target_addr, 1);
3277 return 0;
3280 #ifdef TARGET_NR_stat64
3281 static inline abi_long host_to_target_stat64(void *cpu_env,
3282 abi_ulong target_addr,
3283 struct stat *host_st)
3285 #ifdef TARGET_ARM
3286 if (((CPUARMState *)cpu_env)->eabi) {
3287 struct target_eabi_stat64 *target_st;
3289 if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3290 return -TARGET_EFAULT;
3291 memset(target_st, 0, sizeof(struct target_eabi_stat64));
3292 __put_user(host_st->st_dev, &target_st->st_dev);
3293 __put_user(host_st->st_ino, &target_st->st_ino);
3294 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3295 __put_user(host_st->st_ino, &target_st->__st_ino);
3296 #endif
3297 __put_user(host_st->st_mode, &target_st->st_mode);
3298 __put_user(host_st->st_nlink, &target_st->st_nlink);
3299 __put_user(host_st->st_uid, &target_st->st_uid);
3300 __put_user(host_st->st_gid, &target_st->st_gid);
3301 __put_user(host_st->st_rdev, &target_st->st_rdev);
3302 __put_user(host_st->st_size, &target_st->st_size);
3303 __put_user(host_st->st_blksize, &target_st->st_blksize);
3304 __put_user(host_st->st_blocks, &target_st->st_blocks);
3305 __put_user(host_st->st_atime, &target_st->target_st_atime);
3306 __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3307 __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3308 unlock_user_struct(target_st, target_addr, 1);
3309 } else
3310 #endif
3312 struct target_stat64 *target_st;
3314 if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3315 return -TARGET_EFAULT;
3316 memset(target_st, 0, sizeof(struct target_stat64));
3317 __put_user(host_st->st_dev, &target_st->st_dev);
3318 __put_user(host_st->st_ino, &target_st->st_ino);
3319 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3320 __put_user(host_st->st_ino, &target_st->__st_ino);
3321 #endif
3322 __put_user(host_st->st_mode, &target_st->st_mode);
3323 __put_user(host_st->st_nlink, &target_st->st_nlink);
3324 __put_user(host_st->st_uid, &target_st->st_uid);
3325 __put_user(host_st->st_gid, &target_st->st_gid);
3326 __put_user(host_st->st_rdev, &target_st->st_rdev);
3327 /* XXX: better use of kernel struct */
3328 __put_user(host_st->st_size, &target_st->st_size);
3329 __put_user(host_st->st_blksize, &target_st->st_blksize);
3330 __put_user(host_st->st_blocks, &target_st->st_blocks);
3331 __put_user(host_st->st_atime, &target_st->target_st_atime);
3332 __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3333 __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3334 unlock_user_struct(target_st, target_addr, 1);
3337 return 0;
3339 #endif
3341 #if defined(USE_NPTL)
3342 /* ??? Using host futex calls even when target atomic operations
3343 are not really atomic probably breaks things. However implementing
3344 futexes locally would make futexes shared between multiple processes
3345 tricky. However they're probably useless because guest atomic
3346 operations won't work either. */
3347 static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
3348 target_ulong uaddr2, int val3)
3350 struct timespec ts, *pts;
3352 /* ??? We assume FUTEX_* constants are the same on both host
3353 and target. */
3354 switch (op) {
3355 case FUTEX_WAIT:
3356 if (timeout) {
3357 pts = &ts;
3358 target_to_host_timespec(pts, timeout);
3359 } else {
3360 pts = NULL;
3362 return get_errno(sys_futex(g2h(uaddr), FUTEX_WAIT, tswap32(val),
3363 pts, NULL, 0));
3364 case FUTEX_WAKE:
3365 return get_errno(sys_futex(g2h(uaddr), FUTEX_WAKE, val, NULL, NULL, 0));
3366 case FUTEX_FD:
3367 return get_errno(sys_futex(g2h(uaddr), FUTEX_FD, val, NULL, NULL, 0));
3368 case FUTEX_REQUEUE:
3369 return get_errno(sys_futex(g2h(uaddr), FUTEX_REQUEUE, val,
3370 NULL, g2h(uaddr2), 0));
3371 case FUTEX_CMP_REQUEUE:
3372 return get_errno(sys_futex(g2h(uaddr), FUTEX_CMP_REQUEUE, val,
3373 NULL, g2h(uaddr2), tswap32(val3)));
3374 default:
3375 return -TARGET_ENOSYS;
3378 #endif
3380 int get_osversion(void)
3382 static int osversion;
3383 struct new_utsname buf;
3384 const char *s;
3385 int i, n, tmp;
3386 if (osversion)
3387 return osversion;
3388 if (qemu_uname_release && *qemu_uname_release) {
3389 s = qemu_uname_release;
3390 } else {
3391 if (sys_uname(&buf))
3392 return 0;
3393 s = buf.release;
3395 tmp = 0;
3396 for (i = 0; i < 3; i++) {
3397 n = 0;
3398 while (*s >= '0' && *s <= '9') {
3399 n *= 10;
3400 n += *s - '0';
3401 s++;
3403 tmp = (tmp << 8) + n;
3404 if (*s == '.')
3405 s++;
3407 osversion = tmp;
3408 return osversion;
3411 /* do_syscall() should always have a single exit point at the end so
3412 that actions, such as logging of syscall results, can be performed.
3413 All errnos that do_syscall() returns must be -TARGET_<errcode>. */
3414 abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3415 abi_long arg2, abi_long arg3, abi_long arg4,
3416 abi_long arg5, abi_long arg6)
3418 abi_long ret;
3419 struct stat st;
3420 struct statfs stfs;
3421 void *p;
3423 #ifdef DEBUG
3424 gemu_log("syscall %d", num);
3425 #endif
3426 if(do_strace)
3427 print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
3429 switch(num) {
3430 case TARGET_NR_exit:
3431 #ifdef HAVE_GPROF
3432 _mcleanup();
3433 #endif
3434 gdb_exit(cpu_env, arg1);
3435 /* XXX: should free thread stack and CPU env */
3436 sys_exit(arg1);
3437 ret = 0; /* avoid warning */
3438 break;
3439 case TARGET_NR_read:
3440 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
3441 goto efault;
3442 ret = get_errno(read(arg1, p, arg3));
3443 unlock_user(p, arg2, ret);
3444 break;
3445 case TARGET_NR_write:
3446 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
3447 goto efault;
3448 ret = get_errno(write(arg1, p, arg3));
3449 unlock_user(p, arg2, 0);
3450 break;
3451 case TARGET_NR_open:
3452 if (!(p = lock_user_string(arg1)))
3453 goto efault;
3454 ret = get_errno(open(path(p),
3455 target_to_host_bitmask(arg2, fcntl_flags_tbl),
3456 arg3));
3457 unlock_user(p, arg1, 0);
3458 break;
3459 #if defined(TARGET_NR_openat) && defined(__NR_openat)
3460 case TARGET_NR_openat:
3461 if (!(p = lock_user_string(arg2)))
3462 goto efault;
3463 ret = get_errno(sys_openat(arg1,
3464 path(p),
3465 target_to_host_bitmask(arg3, fcntl_flags_tbl),
3466 arg4));
3467 unlock_user(p, arg2, 0);
3468 break;
3469 #endif
3470 case TARGET_NR_close:
3471 ret = get_errno(close(arg1));
3472 break;
3473 case TARGET_NR_brk:
3474 ret = do_brk(arg1);
3475 break;
3476 case TARGET_NR_fork:
3477 ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
3478 break;
3479 #ifdef TARGET_NR_waitpid
3480 case TARGET_NR_waitpid:
3482 int status;
3483 ret = get_errno(waitpid(arg1, &status, arg3));
3484 if (!is_error(ret) && arg2
3485 && put_user_s32(status, arg2))
3486 goto efault;
3488 break;
3489 #endif
3490 #ifdef TARGET_NR_waitid
3491 case TARGET_NR_waitid:
3493 siginfo_t info;
3494 info.si_pid = 0;
3495 ret = get_errno(waitid(arg1, arg2, &info, arg4));
3496 if (!is_error(ret) && arg3 && info.si_pid != 0) {
3497 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
3498 goto efault;
3499 host_to_target_siginfo(p, &info);
3500 unlock_user(p, arg3, sizeof(target_siginfo_t));
3503 break;
3504 #endif
3505 #ifdef TARGET_NR_creat /* not on alpha */
3506 case TARGET_NR_creat:
3507 if (!(p = lock_user_string(arg1)))
3508 goto efault;
3509 ret = get_errno(creat(p, arg2));
3510 unlock_user(p, arg1, 0);
3511 break;
3512 #endif
3513 case TARGET_NR_link:
3515 void * p2;
3516 p = lock_user_string(arg1);
3517 p2 = lock_user_string(arg2);
3518 if (!p || !p2)
3519 ret = -TARGET_EFAULT;
3520 else
3521 ret = get_errno(link(p, p2));
3522 unlock_user(p2, arg2, 0);
3523 unlock_user(p, arg1, 0);
3525 break;
3526 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
3527 case TARGET_NR_linkat:
3529 void * p2 = NULL;
3530 if (!arg2 || !arg4)
3531 goto efault;
3532 p = lock_user_string(arg2);
3533 p2 = lock_user_string(arg4);
3534 if (!p || !p2)
3535 ret = -TARGET_EFAULT;
3536 else
3537 ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
3538 unlock_user(p, arg2, 0);
3539 unlock_user(p2, arg4, 0);
3541 break;
3542 #endif
3543 case TARGET_NR_unlink:
3544 if (!(p = lock_user_string(arg1)))
3545 goto efault;
3546 ret = get_errno(unlink(p));
3547 unlock_user(p, arg1, 0);
3548 break;
3549 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
3550 case TARGET_NR_unlinkat:
3551 if (!(p = lock_user_string(arg2)))
3552 goto efault;
3553 ret = get_errno(sys_unlinkat(arg1, p, arg3));
3554 unlock_user(p, arg2, 0);
3555 break;
3556 #endif
3557 case TARGET_NR_execve:
3559 char **argp, **envp;
3560 int argc, envc;
3561 abi_ulong gp;
3562 abi_ulong guest_argp;
3563 abi_ulong guest_envp;
3564 abi_ulong addr;
3565 char **q;
3567 argc = 0;
3568 guest_argp = arg2;
3569 for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
3570 if (get_user_ual(addr, gp))
3571 goto efault;
3572 if (!addr)
3573 break;
3574 argc++;
3576 envc = 0;
3577 guest_envp = arg3;
3578 for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
3579 if (get_user_ual(addr, gp))
3580 goto efault;
3581 if (!addr)
3582 break;
3583 envc++;
3586 argp = alloca((argc + 1) * sizeof(void *));
3587 envp = alloca((envc + 1) * sizeof(void *));
3589 for (gp = guest_argp, q = argp; gp;
3590 gp += sizeof(abi_ulong), q++) {
3591 if (get_user_ual(addr, gp))
3592 goto execve_efault;
3593 if (!addr)
3594 break;
3595 if (!(*q = lock_user_string(addr)))
3596 goto execve_efault;
3598 *q = NULL;
3600 for (gp = guest_envp, q = envp; gp;
3601 gp += sizeof(abi_ulong), q++) {
3602 if (get_user_ual(addr, gp))
3603 goto execve_efault;
3604 if (!addr)
3605 break;
3606 if (!(*q = lock_user_string(addr)))
3607 goto execve_efault;
3609 *q = NULL;
3611 if (!(p = lock_user_string(arg1)))
3612 goto execve_efault;
3613 ret = get_errno(execve(p, argp, envp));
3614 unlock_user(p, arg1, 0);
3616 goto execve_end;
3618 execve_efault:
3619 ret = -TARGET_EFAULT;
3621 execve_end:
3622 for (gp = guest_argp, q = argp; *q;
3623 gp += sizeof(abi_ulong), q++) {
3624 if (get_user_ual(addr, gp)
3625 || !addr)
3626 break;
3627 unlock_user(*q, addr, 0);
3629 for (gp = guest_envp, q = envp; *q;
3630 gp += sizeof(abi_ulong), q++) {
3631 if (get_user_ual(addr, gp)
3632 || !addr)
3633 break;
3634 unlock_user(*q, addr, 0);
3637 break;
3638 case TARGET_NR_chdir:
3639 if (!(p = lock_user_string(arg1)))
3640 goto efault;
3641 ret = get_errno(chdir(p));
3642 unlock_user(p, arg1, 0);
3643 break;
3644 #ifdef TARGET_NR_time
3645 case TARGET_NR_time:
3647 time_t host_time;
3648 ret = get_errno(time(&host_time));
3649 if (!is_error(ret)
3650 && arg1
3651 && put_user_sal(host_time, arg1))
3652 goto efault;
3654 break;
3655 #endif
3656 case TARGET_NR_mknod:
3657 if (!(p = lock_user_string(arg1)))
3658 goto efault;
3659 ret = get_errno(mknod(p, arg2, arg3));
3660 unlock_user(p, arg1, 0);
3661 break;
3662 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
3663 case TARGET_NR_mknodat:
3664 if (!(p = lock_user_string(arg2)))
3665 goto efault;
3666 ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
3667 unlock_user(p, arg2, 0);
3668 break;
3669 #endif
3670 case TARGET_NR_chmod:
3671 if (!(p = lock_user_string(arg1)))
3672 goto efault;
3673 ret = get_errno(chmod(p, arg2));
3674 unlock_user(p, arg1, 0);
3675 break;
3676 #ifdef TARGET_NR_break
3677 case TARGET_NR_break:
3678 goto unimplemented;
3679 #endif
3680 #ifdef TARGET_NR_oldstat
3681 case TARGET_NR_oldstat:
3682 goto unimplemented;
3683 #endif
3684 case TARGET_NR_lseek:
3685 ret = get_errno(lseek(arg1, arg2, arg3));
3686 break;
3687 #ifdef TARGET_NR_getxpid
3688 case TARGET_NR_getxpid:
3689 #else
3690 case TARGET_NR_getpid:
3691 #endif
3692 ret = get_errno(getpid());
3693 break;
3694 case TARGET_NR_mount:
3696 /* need to look at the data field */
3697 void *p2, *p3;
3698 p = lock_user_string(arg1);
3699 p2 = lock_user_string(arg2);
3700 p3 = lock_user_string(arg3);
3701 if (!p || !p2 || !p3)
3702 ret = -TARGET_EFAULT;
3703 else
3704 /* FIXME - arg5 should be locked, but it isn't clear how to
3705 * do that since it's not guaranteed to be a NULL-terminated
3706 * string.
3708 ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
3709 unlock_user(p, arg1, 0);
3710 unlock_user(p2, arg2, 0);
3711 unlock_user(p3, arg3, 0);
3712 break;
3714 #ifdef TARGET_NR_umount
3715 case TARGET_NR_umount:
3716 if (!(p = lock_user_string(arg1)))
3717 goto efault;
3718 ret = get_errno(umount(p));
3719 unlock_user(p, arg1, 0);
3720 break;
3721 #endif
3722 #ifdef TARGET_NR_stime /* not on alpha */
3723 case TARGET_NR_stime:
3725 time_t host_time;
3726 if (get_user_sal(host_time, arg1))
3727 goto efault;
3728 ret = get_errno(stime(&host_time));
3730 break;
3731 #endif
3732 case TARGET_NR_ptrace:
3733 goto unimplemented;
3734 #ifdef TARGET_NR_alarm /* not on alpha */
3735 case TARGET_NR_alarm:
3736 ret = alarm(arg1);
3737 break;
3738 #endif
3739 #ifdef TARGET_NR_oldfstat
3740 case TARGET_NR_oldfstat:
3741 goto unimplemented;
3742 #endif
3743 #ifdef TARGET_NR_pause /* not on alpha */
3744 case TARGET_NR_pause:
3745 ret = get_errno(pause());
3746 break;
3747 #endif
3748 #ifdef TARGET_NR_utime
3749 case TARGET_NR_utime:
3751 struct utimbuf tbuf, *host_tbuf;
3752 struct target_utimbuf *target_tbuf;
3753 if (arg2) {
3754 if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
3755 goto efault;
3756 tbuf.actime = tswapl(target_tbuf->actime);
3757 tbuf.modtime = tswapl(target_tbuf->modtime);
3758 unlock_user_struct(target_tbuf, arg2, 0);
3759 host_tbuf = &tbuf;
3760 } else {
3761 host_tbuf = NULL;
3763 if (!(p = lock_user_string(arg1)))
3764 goto efault;
3765 ret = get_errno(utime(p, host_tbuf));
3766 unlock_user(p, arg1, 0);
3768 break;
3769 #endif
3770 case TARGET_NR_utimes:
3772 struct timeval *tvp, tv[2];
3773 if (arg2) {
3774 if (copy_from_user_timeval(&tv[0], arg2)
3775 || copy_from_user_timeval(&tv[1],
3776 arg2 + sizeof(struct target_timeval)))
3777 goto efault;
3778 tvp = tv;
3779 } else {
3780 tvp = NULL;
3782 if (!(p = lock_user_string(arg1)))
3783 goto efault;
3784 ret = get_errno(utimes(p, tvp));
3785 unlock_user(p, arg1, 0);
3787 break;
3788 #if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
3789 case TARGET_NR_futimesat:
3791 struct timeval *tvp, tv[2];
3792 if (arg3) {
3793 if (copy_from_user_timeval(&tv[0], arg3)
3794 || copy_from_user_timeval(&tv[1],
3795 arg3 + sizeof(struct target_timeval)))
3796 goto efault;
3797 tvp = tv;
3798 } else {
3799 tvp = NULL;
3801 if (!(p = lock_user_string(arg2)))
3802 goto efault;
3803 ret = get_errno(sys_futimesat(arg1, path(p), tvp));
3804 unlock_user(p, arg2, 0);
3806 break;
3807 #endif
3808 #ifdef TARGET_NR_stty
3809 case TARGET_NR_stty:
3810 goto unimplemented;
3811 #endif
3812 #ifdef TARGET_NR_gtty
3813 case TARGET_NR_gtty:
3814 goto unimplemented;
3815 #endif
3816 case TARGET_NR_access:
3817 if (!(p = lock_user_string(arg1)))
3818 goto efault;
3819 ret = get_errno(access(p, arg2));
3820 unlock_user(p, arg1, 0);
3821 break;
3822 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
3823 case TARGET_NR_faccessat:
3824 if (!(p = lock_user_string(arg2)))
3825 goto efault;
3826 ret = get_errno(sys_faccessat(arg1, p, arg3, arg4));
3827 unlock_user(p, arg2, 0);
3828 break;
3829 #endif
3830 #ifdef TARGET_NR_nice /* not on alpha */
3831 case TARGET_NR_nice:
3832 ret = get_errno(nice(arg1));
3833 break;
3834 #endif
3835 #ifdef TARGET_NR_ftime
3836 case TARGET_NR_ftime:
3837 goto unimplemented;
3838 #endif
3839 case TARGET_NR_sync:
3840 sync();
3841 ret = 0;
3842 break;
3843 case TARGET_NR_kill:
3844 ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
3845 break;
3846 case TARGET_NR_rename:
3848 void *p2;
3849 p = lock_user_string(arg1);
3850 p2 = lock_user_string(arg2);
3851 if (!p || !p2)
3852 ret = -TARGET_EFAULT;
3853 else
3854 ret = get_errno(rename(p, p2));
3855 unlock_user(p2, arg2, 0);
3856 unlock_user(p, arg1, 0);
3858 break;
3859 #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
3860 case TARGET_NR_renameat:
3862 void *p2;
3863 p = lock_user_string(arg2);
3864 p2 = lock_user_string(arg4);
3865 if (!p || !p2)
3866 ret = -TARGET_EFAULT;
3867 else
3868 ret = get_errno(sys_renameat(arg1, p, arg3, p2));
3869 unlock_user(p2, arg4, 0);
3870 unlock_user(p, arg2, 0);
3872 break;
3873 #endif
3874 case TARGET_NR_mkdir:
3875 if (!(p = lock_user_string(arg1)))
3876 goto efault;
3877 ret = get_errno(mkdir(p, arg2));
3878 unlock_user(p, arg1, 0);
3879 break;
3880 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
3881 case TARGET_NR_mkdirat:
3882 if (!(p = lock_user_string(arg2)))
3883 goto efault;
3884 ret = get_errno(sys_mkdirat(arg1, p, arg3));
3885 unlock_user(p, arg2, 0);
3886 break;
3887 #endif
3888 case TARGET_NR_rmdir:
3889 if (!(p = lock_user_string(arg1)))
3890 goto efault;
3891 ret = get_errno(rmdir(p));
3892 unlock_user(p, arg1, 0);
3893 break;
3894 case TARGET_NR_dup:
3895 ret = get_errno(dup(arg1));
3896 break;
3897 case TARGET_NR_pipe:
3899 int host_pipe[2];
3900 ret = get_errno(pipe(host_pipe));
3901 if (!is_error(ret)) {
3902 #if defined(TARGET_MIPS)
3903 CPUMIPSState *env = (CPUMIPSState*)cpu_env;
3904 env->active_tc.gpr[3] = host_pipe[1];
3905 ret = host_pipe[0];
3906 #elif defined(TARGET_SH4)
3907 ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
3908 ret = host_pipe[0];
3909 #else
3910 if (put_user_s32(host_pipe[0], arg1)
3911 || put_user_s32(host_pipe[1], arg1 + sizeof(host_pipe[0])))
3912 goto efault;
3913 #endif
3916 break;
3917 case TARGET_NR_times:
3919 struct target_tms *tmsp;
3920 struct tms tms;
3921 ret = get_errno(times(&tms));
3922 if (arg1) {
3923 tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
3924 if (!tmsp)
3925 goto efault;
3926 tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
3927 tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
3928 tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
3929 tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime));
3931 if (!is_error(ret))
3932 ret = host_to_target_clock_t(ret);
3934 break;
3935 #ifdef TARGET_NR_prof
3936 case TARGET_NR_prof:
3937 goto unimplemented;
3938 #endif
3939 #ifdef TARGET_NR_signal
3940 case TARGET_NR_signal:
3941 goto unimplemented;
3942 #endif
3943 case TARGET_NR_acct:
3944 if (!(p = lock_user_string(arg1)))
3945 goto efault;
3946 ret = get_errno(acct(path(p)));
3947 unlock_user(p, arg1, 0);
3948 break;
3949 #ifdef TARGET_NR_umount2 /* not on alpha */
3950 case TARGET_NR_umount2:
3951 if (!(p = lock_user_string(arg1)))
3952 goto efault;
3953 ret = get_errno(umount2(p, arg2));
3954 unlock_user(p, arg1, 0);
3955 break;
3956 #endif
3957 #ifdef TARGET_NR_lock
3958 case TARGET_NR_lock:
3959 goto unimplemented;
3960 #endif
3961 case TARGET_NR_ioctl:
3962 ret = do_ioctl(arg1, arg2, arg3);
3963 break;
3964 case TARGET_NR_fcntl:
3965 ret = do_fcntl(arg1, arg2, arg3);
3966 break;
3967 #ifdef TARGET_NR_mpx
3968 case TARGET_NR_mpx:
3969 goto unimplemented;
3970 #endif
3971 case TARGET_NR_setpgid:
3972 ret = get_errno(setpgid(arg1, arg2));
3973 break;
3974 #ifdef TARGET_NR_ulimit
3975 case TARGET_NR_ulimit:
3976 goto unimplemented;
3977 #endif
3978 #ifdef TARGET_NR_oldolduname
3979 case TARGET_NR_oldolduname:
3980 goto unimplemented;
3981 #endif
3982 case TARGET_NR_umask:
3983 ret = get_errno(umask(arg1));
3984 break;
3985 case TARGET_NR_chroot:
3986 if (!(p = lock_user_string(arg1)))
3987 goto efault;
3988 ret = get_errno(chroot(p));
3989 unlock_user(p, arg1, 0);
3990 break;
3991 case TARGET_NR_ustat:
3992 goto unimplemented;
3993 case TARGET_NR_dup2:
3994 ret = get_errno(dup2(arg1, arg2));
3995 break;
3996 #ifdef TARGET_NR_getppid /* not on alpha */
3997 case TARGET_NR_getppid:
3998 ret = get_errno(getppid());
3999 break;
4000 #endif
4001 case TARGET_NR_getpgrp:
4002 ret = get_errno(getpgrp());
4003 break;
4004 case TARGET_NR_setsid:
4005 ret = get_errno(setsid());
4006 break;
4007 #ifdef TARGET_NR_sigaction
4008 case TARGET_NR_sigaction:
4010 #if !defined(TARGET_MIPS)
4011 struct target_old_sigaction *old_act;
4012 struct target_sigaction act, oact, *pact;
4013 if (arg2) {
4014 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4015 goto efault;
4016 act._sa_handler = old_act->_sa_handler;
4017 target_siginitset(&act.sa_mask, old_act->sa_mask);
4018 act.sa_flags = old_act->sa_flags;
4019 act.sa_restorer = old_act->sa_restorer;
4020 unlock_user_struct(old_act, arg2, 0);
4021 pact = &act;
4022 } else {
4023 pact = NULL;
4025 ret = get_errno(do_sigaction(arg1, pact, &oact));
4026 if (!is_error(ret) && arg3) {
4027 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4028 goto efault;
4029 old_act->_sa_handler = oact._sa_handler;
4030 old_act->sa_mask = oact.sa_mask.sig[0];
4031 old_act->sa_flags = oact.sa_flags;
4032 old_act->sa_restorer = oact.sa_restorer;
4033 unlock_user_struct(old_act, arg3, 1);
4035 #else
4036 struct target_sigaction act, oact, *pact, *old_act;
4038 if (arg2) {
4039 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4040 goto efault;
4041 act._sa_handler = old_act->_sa_handler;
4042 target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
4043 act.sa_flags = old_act->sa_flags;
4044 unlock_user_struct(old_act, arg2, 0);
4045 pact = &act;
4046 } else {
4047 pact = NULL;
4050 ret = get_errno(do_sigaction(arg1, pact, &oact));
4052 if (!is_error(ret) && arg3) {
4053 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4054 goto efault;
4055 old_act->_sa_handler = oact._sa_handler;
4056 old_act->sa_flags = oact.sa_flags;
4057 old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
4058 old_act->sa_mask.sig[1] = 0;
4059 old_act->sa_mask.sig[2] = 0;
4060 old_act->sa_mask.sig[3] = 0;
4061 unlock_user_struct(old_act, arg3, 1);
4063 #endif
4065 break;
4066 #endif
4067 case TARGET_NR_rt_sigaction:
4069 struct target_sigaction *act;
4070 struct target_sigaction *oact;
4072 if (arg2) {
4073 if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
4074 goto efault;
4075 } else
4076 act = NULL;
4077 if (arg3) {
4078 if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
4079 ret = -TARGET_EFAULT;
4080 goto rt_sigaction_fail;
4082 } else
4083 oact = NULL;
4084 ret = get_errno(do_sigaction(arg1, act, oact));
4085 rt_sigaction_fail:
4086 if (act)
4087 unlock_user_struct(act, arg2, 0);
4088 if (oact)
4089 unlock_user_struct(oact, arg3, 1);
4091 break;
4092 #ifdef TARGET_NR_sgetmask /* not on alpha */
4093 case TARGET_NR_sgetmask:
4095 sigset_t cur_set;
4096 abi_ulong target_set;
4097 sigprocmask(0, NULL, &cur_set);
4098 host_to_target_old_sigset(&target_set, &cur_set);
4099 ret = target_set;
4101 break;
4102 #endif
4103 #ifdef TARGET_NR_ssetmask /* not on alpha */
4104 case TARGET_NR_ssetmask:
4106 sigset_t set, oset, cur_set;
4107 abi_ulong target_set = arg1;
4108 sigprocmask(0, NULL, &cur_set);
4109 target_to_host_old_sigset(&set, &target_set);
4110 sigorset(&set, &set, &cur_set);
4111 sigprocmask(SIG_SETMASK, &set, &oset);
4112 host_to_target_old_sigset(&target_set, &oset);
4113 ret = target_set;
4115 break;
4116 #endif
4117 #ifdef TARGET_NR_sigprocmask
4118 case TARGET_NR_sigprocmask:
4120 int how = arg1;
4121 sigset_t set, oldset, *set_ptr;
4123 if (arg2) {
4124 switch(how) {
4125 case TARGET_SIG_BLOCK:
4126 how = SIG_BLOCK;
4127 break;
4128 case TARGET_SIG_UNBLOCK:
4129 how = SIG_UNBLOCK;
4130 break;
4131 case TARGET_SIG_SETMASK:
4132 how = SIG_SETMASK;
4133 break;
4134 default:
4135 ret = -TARGET_EINVAL;
4136 goto fail;
4138 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4139 goto efault;
4140 target_to_host_old_sigset(&set, p);
4141 unlock_user(p, arg2, 0);
4142 set_ptr = &set;
4143 } else {
4144 how = 0;
4145 set_ptr = NULL;
4147 ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
4148 if (!is_error(ret) && arg3) {
4149 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4150 goto efault;
4151 host_to_target_old_sigset(p, &oldset);
4152 unlock_user(p, arg3, sizeof(target_sigset_t));
4155 break;
4156 #endif
4157 case TARGET_NR_rt_sigprocmask:
4159 int how = arg1;
4160 sigset_t set, oldset, *set_ptr;
4162 if (arg2) {
4163 switch(how) {
4164 case TARGET_SIG_BLOCK:
4165 how = SIG_BLOCK;
4166 break;
4167 case TARGET_SIG_UNBLOCK:
4168 how = SIG_UNBLOCK;
4169 break;
4170 case TARGET_SIG_SETMASK:
4171 how = SIG_SETMASK;
4172 break;
4173 default:
4174 ret = -TARGET_EINVAL;
4175 goto fail;
4177 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4178 goto efault;
4179 target_to_host_sigset(&set, p);
4180 unlock_user(p, arg2, 0);
4181 set_ptr = &set;
4182 } else {
4183 how = 0;
4184 set_ptr = NULL;
4186 ret = get_errno(sigprocmask(how, set_ptr, &oldset));
4187 if (!is_error(ret) && arg3) {
4188 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4189 goto efault;
4190 host_to_target_sigset(p, &oldset);
4191 unlock_user(p, arg3, sizeof(target_sigset_t));
4194 break;
4195 #ifdef TARGET_NR_sigpending
4196 case TARGET_NR_sigpending:
4198 sigset_t set;
4199 ret = get_errno(sigpending(&set));
4200 if (!is_error(ret)) {
4201 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4202 goto efault;
4203 host_to_target_old_sigset(p, &set);
4204 unlock_user(p, arg1, sizeof(target_sigset_t));
4207 break;
4208 #endif
4209 case TARGET_NR_rt_sigpending:
4211 sigset_t set;
4212 ret = get_errno(sigpending(&set));
4213 if (!is_error(ret)) {
4214 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4215 goto efault;
4216 host_to_target_sigset(p, &set);
4217 unlock_user(p, arg1, sizeof(target_sigset_t));
4220 break;
4221 #ifdef TARGET_NR_sigsuspend
4222 case TARGET_NR_sigsuspend:
4224 sigset_t set;
4225 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4226 goto efault;
4227 target_to_host_old_sigset(&set, p);
4228 unlock_user(p, arg1, 0);
4229 ret = get_errno(sigsuspend(&set));
4231 break;
4232 #endif
4233 case TARGET_NR_rt_sigsuspend:
4235 sigset_t set;
4236 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4237 goto efault;
4238 target_to_host_sigset(&set, p);
4239 unlock_user(p, arg1, 0);
4240 ret = get_errno(sigsuspend(&set));
4242 break;
4243 case TARGET_NR_rt_sigtimedwait:
4245 sigset_t set;
4246 struct timespec uts, *puts;
4247 siginfo_t uinfo;
4249 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4250 goto efault;
4251 target_to_host_sigset(&set, p);
4252 unlock_user(p, arg1, 0);
4253 if (arg3) {
4254 puts = &uts;
4255 target_to_host_timespec(puts, arg3);
4256 } else {
4257 puts = NULL;
4259 ret = get_errno(sigtimedwait(&set, &uinfo, puts));
4260 if (!is_error(ret) && arg2) {
4261 if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
4262 goto efault;
4263 host_to_target_siginfo(p, &uinfo);
4264 unlock_user(p, arg2, sizeof(target_siginfo_t));
4267 break;
4268 case TARGET_NR_rt_sigqueueinfo:
4270 siginfo_t uinfo;
4271 if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
4272 goto efault;
4273 target_to_host_siginfo(&uinfo, p);
4274 unlock_user(p, arg1, 0);
4275 ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
4277 break;
4278 #ifdef TARGET_NR_sigreturn
4279 case TARGET_NR_sigreturn:
4280 /* NOTE: ret is eax, so not transcoding must be done */
4281 ret = do_sigreturn(cpu_env);
4282 break;
4283 #endif
4284 case TARGET_NR_rt_sigreturn:
4285 /* NOTE: ret is eax, so not transcoding must be done */
4286 ret = do_rt_sigreturn(cpu_env);
4287 break;
4288 case TARGET_NR_sethostname:
4289 if (!(p = lock_user_string(arg1)))
4290 goto efault;
4291 ret = get_errno(sethostname(p, arg2));
4292 unlock_user(p, arg1, 0);
4293 break;
4294 case TARGET_NR_setrlimit:
4296 /* XXX: convert resource ? */
4297 int resource = arg1;
4298 struct target_rlimit *target_rlim;
4299 struct rlimit rlim;
4300 if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
4301 goto efault;
4302 rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4303 rlim.rlim_max = tswapl(target_rlim->rlim_max);
4304 unlock_user_struct(target_rlim, arg2, 0);
4305 ret = get_errno(setrlimit(resource, &rlim));
4307 break;
4308 case TARGET_NR_getrlimit:
4310 /* XXX: convert resource ? */
4311 int resource = arg1;
4312 struct target_rlimit *target_rlim;
4313 struct rlimit rlim;
4315 ret = get_errno(getrlimit(resource, &rlim));
4316 if (!is_error(ret)) {
4317 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
4318 goto efault;
4319 rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4320 rlim.rlim_max = tswapl(target_rlim->rlim_max);
4321 unlock_user_struct(target_rlim, arg2, 1);
4324 break;
4325 case TARGET_NR_getrusage:
4327 struct rusage rusage;
4328 ret = get_errno(getrusage(arg1, &rusage));
4329 if (!is_error(ret)) {
4330 host_to_target_rusage(arg2, &rusage);
4333 break;
4334 case TARGET_NR_gettimeofday:
4336 struct timeval tv;
4337 ret = get_errno(gettimeofday(&tv, NULL));
4338 if (!is_error(ret)) {
4339 if (copy_to_user_timeval(arg1, &tv))
4340 goto efault;
4343 break;
4344 case TARGET_NR_settimeofday:
4346 struct timeval tv;
4347 if (copy_from_user_timeval(&tv, arg1))
4348 goto efault;
4349 ret = get_errno(settimeofday(&tv, NULL));
4351 break;
4352 #ifdef TARGET_NR_select
4353 case TARGET_NR_select:
4355 struct target_sel_arg_struct *sel;
4356 abi_ulong inp, outp, exp, tvp;
4357 long nsel;
4359 if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
4360 goto efault;
4361 nsel = tswapl(sel->n);
4362 inp = tswapl(sel->inp);
4363 outp = tswapl(sel->outp);
4364 exp = tswapl(sel->exp);
4365 tvp = tswapl(sel->tvp);
4366 unlock_user_struct(sel, arg1, 0);
4367 ret = do_select(nsel, inp, outp, exp, tvp);
4369 break;
4370 #endif
4371 case TARGET_NR_symlink:
4373 void *p2;
4374 p = lock_user_string(arg1);
4375 p2 = lock_user_string(arg2);
4376 if (!p || !p2)
4377 ret = -TARGET_EFAULT;
4378 else
4379 ret = get_errno(symlink(p, p2));
4380 unlock_user(p2, arg2, 0);
4381 unlock_user(p, arg1, 0);
4383 break;
4384 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
4385 case TARGET_NR_symlinkat:
4387 void *p2;
4388 p = lock_user_string(arg1);
4389 p2 = lock_user_string(arg3);
4390 if (!p || !p2)
4391 ret = -TARGET_EFAULT;
4392 else
4393 ret = get_errno(sys_symlinkat(p, arg2, p2));
4394 unlock_user(p2, arg3, 0);
4395 unlock_user(p, arg1, 0);
4397 break;
4398 #endif
4399 #ifdef TARGET_NR_oldlstat
4400 case TARGET_NR_oldlstat:
4401 goto unimplemented;
4402 #endif
4403 case TARGET_NR_readlink:
4405 void *p2;
4406 p = lock_user_string(arg1);
4407 p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
4408 if (!p || !p2)
4409 ret = -TARGET_EFAULT;
4410 else
4411 ret = get_errno(readlink(path(p), p2, arg3));
4412 unlock_user(p2, arg2, ret);
4413 unlock_user(p, arg1, 0);
4415 break;
4416 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
4417 case TARGET_NR_readlinkat:
4419 void *p2;
4420 p = lock_user_string(arg2);
4421 p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
4422 if (!p || !p2)
4423 ret = -TARGET_EFAULT;
4424 else
4425 ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
4426 unlock_user(p2, arg3, ret);
4427 unlock_user(p, arg2, 0);
4429 break;
4430 #endif
4431 #ifdef TARGET_NR_uselib
4432 case TARGET_NR_uselib:
4433 goto unimplemented;
4434 #endif
4435 #ifdef TARGET_NR_swapon
4436 case TARGET_NR_swapon:
4437 if (!(p = lock_user_string(arg1)))
4438 goto efault;
4439 ret = get_errno(swapon(p, arg2));
4440 unlock_user(p, arg1, 0);
4441 break;
4442 #endif
4443 case TARGET_NR_reboot:
4444 goto unimplemented;
4445 #ifdef TARGET_NR_readdir
4446 case TARGET_NR_readdir:
4447 goto unimplemented;
4448 #endif
4449 #ifdef TARGET_NR_mmap
4450 case TARGET_NR_mmap:
4451 #if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS)
4453 abi_ulong *v;
4454 abi_ulong v1, v2, v3, v4, v5, v6;
4455 if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
4456 goto efault;
4457 v1 = tswapl(v[0]);
4458 v2 = tswapl(v[1]);
4459 v3 = tswapl(v[2]);
4460 v4 = tswapl(v[3]);
4461 v5 = tswapl(v[4]);
4462 v6 = tswapl(v[5]);
4463 unlock_user(v, arg1, 0);
4464 ret = get_errno(target_mmap(v1, v2, v3,
4465 target_to_host_bitmask(v4, mmap_flags_tbl),
4466 v5, v6));
4468 #else
4469 ret = get_errno(target_mmap(arg1, arg2, arg3,
4470 target_to_host_bitmask(arg4, mmap_flags_tbl),
4471 arg5,
4472 arg6));
4473 #endif
4474 break;
4475 #endif
4476 #ifdef TARGET_NR_mmap2
4477 case TARGET_NR_mmap2:
4478 #ifndef MMAP_SHIFT
4479 #define MMAP_SHIFT 12
4480 #endif
4481 ret = get_errno(target_mmap(arg1, arg2, arg3,
4482 target_to_host_bitmask(arg4, mmap_flags_tbl),
4483 arg5,
4484 arg6 << MMAP_SHIFT));
4485 break;
4486 #endif
4487 case TARGET_NR_munmap:
4488 ret = get_errno(target_munmap(arg1, arg2));
4489 break;
4490 case TARGET_NR_mprotect:
4491 ret = get_errno(target_mprotect(arg1, arg2, arg3));
4492 break;
4493 #ifdef TARGET_NR_mremap
4494 case TARGET_NR_mremap:
4495 ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
4496 break;
4497 #endif
4498 /* ??? msync/mlock/munlock are broken for softmmu. */
4499 #ifdef TARGET_NR_msync
4500 case TARGET_NR_msync:
4501 ret = get_errno(msync(g2h(arg1), arg2, arg3));
4502 break;
4503 #endif
4504 #ifdef TARGET_NR_mlock
4505 case TARGET_NR_mlock:
4506 ret = get_errno(mlock(g2h(arg1), arg2));
4507 break;
4508 #endif
4509 #ifdef TARGET_NR_munlock
4510 case TARGET_NR_munlock:
4511 ret = get_errno(munlock(g2h(arg1), arg2));
4512 break;
4513 #endif
4514 #ifdef TARGET_NR_mlockall
4515 case TARGET_NR_mlockall:
4516 ret = get_errno(mlockall(arg1));
4517 break;
4518 #endif
4519 #ifdef TARGET_NR_munlockall
4520 case TARGET_NR_munlockall:
4521 ret = get_errno(munlockall());
4522 break;
4523 #endif
4524 case TARGET_NR_truncate:
4525 if (!(p = lock_user_string(arg1)))
4526 goto efault;
4527 ret = get_errno(truncate(p, arg2));
4528 unlock_user(p, arg1, 0);
4529 break;
4530 case TARGET_NR_ftruncate:
4531 ret = get_errno(ftruncate(arg1, arg2));
4532 break;
4533 case TARGET_NR_fchmod:
4534 ret = get_errno(fchmod(arg1, arg2));
4535 break;
4536 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
4537 case TARGET_NR_fchmodat:
4538 if (!(p = lock_user_string(arg2)))
4539 goto efault;
4540 ret = get_errno(sys_fchmodat(arg1, p, arg3, arg4));
4541 unlock_user(p, arg2, 0);
4542 break;
4543 #endif
4544 case TARGET_NR_getpriority:
4545 /* libc does special remapping of the return value of
4546 * sys_getpriority() so it's just easiest to call
4547 * sys_getpriority() directly rather than through libc. */
4548 ret = sys_getpriority(arg1, arg2);
4549 break;
4550 case TARGET_NR_setpriority:
4551 ret = get_errno(setpriority(arg1, arg2, arg3));
4552 break;
4553 #ifdef TARGET_NR_profil
4554 case TARGET_NR_profil:
4555 goto unimplemented;
4556 #endif
4557 case TARGET_NR_statfs:
4558 if (!(p = lock_user_string(arg1)))
4559 goto efault;
4560 ret = get_errno(statfs(path(p), &stfs));
4561 unlock_user(p, arg1, 0);
4562 convert_statfs:
4563 if (!is_error(ret)) {
4564 struct target_statfs *target_stfs;
4566 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
4567 goto efault;
4568 __put_user(stfs.f_type, &target_stfs->f_type);
4569 __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4570 __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4571 __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4572 __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4573 __put_user(stfs.f_files, &target_stfs->f_files);
4574 __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4575 __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4576 __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4577 __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4578 unlock_user_struct(target_stfs, arg2, 1);
4580 break;
4581 case TARGET_NR_fstatfs:
4582 ret = get_errno(fstatfs(arg1, &stfs));
4583 goto convert_statfs;
4584 #ifdef TARGET_NR_statfs64
4585 case TARGET_NR_statfs64:
4586 if (!(p = lock_user_string(arg1)))
4587 goto efault;
4588 ret = get_errno(statfs(path(p), &stfs));
4589 unlock_user(p, arg1, 0);
4590 convert_statfs64:
4591 if (!is_error(ret)) {
4592 struct target_statfs64 *target_stfs;
4594 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
4595 goto efault;
4596 __put_user(stfs.f_type, &target_stfs->f_type);
4597 __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4598 __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4599 __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4600 __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4601 __put_user(stfs.f_files, &target_stfs->f_files);
4602 __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4603 __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4604 __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4605 __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4606 unlock_user_struct(target_stfs, arg3, 1);
4608 break;
4609 case TARGET_NR_fstatfs64:
4610 ret = get_errno(fstatfs(arg1, &stfs));
4611 goto convert_statfs64;
4612 #endif
4613 #ifdef TARGET_NR_ioperm
4614 case TARGET_NR_ioperm:
4615 goto unimplemented;
4616 #endif
4617 #ifdef TARGET_NR_socketcall
4618 case TARGET_NR_socketcall:
4619 ret = do_socketcall(arg1, arg2);
4620 break;
4621 #endif
4622 #ifdef TARGET_NR_accept
4623 case TARGET_NR_accept:
4624 ret = do_accept(arg1, arg2, arg3);
4625 break;
4626 #endif
4627 #ifdef TARGET_NR_bind
4628 case TARGET_NR_bind:
4629 ret = do_bind(arg1, arg2, arg3);
4630 break;
4631 #endif
4632 #ifdef TARGET_NR_connect
4633 case TARGET_NR_connect:
4634 ret = do_connect(arg1, arg2, arg3);
4635 break;
4636 #endif
4637 #ifdef TARGET_NR_getpeername
4638 case TARGET_NR_getpeername:
4639 ret = do_getpeername(arg1, arg2, arg3);
4640 break;
4641 #endif
4642 #ifdef TARGET_NR_getsockname
4643 case TARGET_NR_getsockname:
4644 ret = do_getsockname(arg1, arg2, arg3);
4645 break;
4646 #endif
4647 #ifdef TARGET_NR_getsockopt
4648 case TARGET_NR_getsockopt:
4649 ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
4650 break;
4651 #endif
4652 #ifdef TARGET_NR_listen
4653 case TARGET_NR_listen:
4654 ret = get_errno(listen(arg1, arg2));
4655 break;
4656 #endif
4657 #ifdef TARGET_NR_recv
4658 case TARGET_NR_recv:
4659 ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
4660 break;
4661 #endif
4662 #ifdef TARGET_NR_recvfrom
4663 case TARGET_NR_recvfrom:
4664 ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
4665 break;
4666 #endif
4667 #ifdef TARGET_NR_recvmsg
4668 case TARGET_NR_recvmsg:
4669 ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
4670 break;
4671 #endif
4672 #ifdef TARGET_NR_send
4673 case TARGET_NR_send:
4674 ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
4675 break;
4676 #endif
4677 #ifdef TARGET_NR_sendmsg
4678 case TARGET_NR_sendmsg:
4679 ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
4680 break;
4681 #endif
4682 #ifdef TARGET_NR_sendto
4683 case TARGET_NR_sendto:
4684 ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
4685 break;
4686 #endif
4687 #ifdef TARGET_NR_shutdown
4688 case TARGET_NR_shutdown:
4689 ret = get_errno(shutdown(arg1, arg2));
4690 break;
4691 #endif
4692 #ifdef TARGET_NR_socket
4693 case TARGET_NR_socket:
4694 ret = do_socket(arg1, arg2, arg3);
4695 break;
4696 #endif
4697 #ifdef TARGET_NR_socketpair
4698 case TARGET_NR_socketpair:
4699 ret = do_socketpair(arg1, arg2, arg3, arg4);
4700 break;
4701 #endif
4702 #ifdef TARGET_NR_setsockopt
4703 case TARGET_NR_setsockopt:
4704 ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
4705 break;
4706 #endif
4708 case TARGET_NR_syslog:
4709 if (!(p = lock_user_string(arg2)))
4710 goto efault;
4711 ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
4712 unlock_user(p, arg2, 0);
4713 break;
4715 case TARGET_NR_setitimer:
4717 struct itimerval value, ovalue, *pvalue;
4719 if (arg2) {
4720 pvalue = &value;
4721 if (copy_from_user_timeval(&pvalue->it_interval, arg2)
4722 || copy_from_user_timeval(&pvalue->it_value,
4723 arg2 + sizeof(struct target_timeval)))
4724 goto efault;
4725 } else {
4726 pvalue = NULL;
4728 ret = get_errno(setitimer(arg1, pvalue, &ovalue));
4729 if (!is_error(ret) && arg3) {
4730 if (copy_to_user_timeval(arg3,
4731 &ovalue.it_interval)
4732 || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
4733 &ovalue.it_value))
4734 goto efault;
4737 break;
4738 case TARGET_NR_getitimer:
4740 struct itimerval value;
4742 ret = get_errno(getitimer(arg1, &value));
4743 if (!is_error(ret) && arg2) {
4744 if (copy_to_user_timeval(arg2,
4745 &value.it_interval)
4746 || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
4747 &value.it_value))
4748 goto efault;
4751 break;
4752 case TARGET_NR_stat:
4753 if (!(p = lock_user_string(arg1)))
4754 goto efault;
4755 ret = get_errno(stat(path(p), &st));
4756 unlock_user(p, arg1, 0);
4757 goto do_stat;
4758 case TARGET_NR_lstat:
4759 if (!(p = lock_user_string(arg1)))
4760 goto efault;
4761 ret = get_errno(lstat(path(p), &st));
4762 unlock_user(p, arg1, 0);
4763 goto do_stat;
4764 case TARGET_NR_fstat:
4766 ret = get_errno(fstat(arg1, &st));
4767 do_stat:
4768 if (!is_error(ret)) {
4769 struct target_stat *target_st;
4771 if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
4772 goto efault;
4773 __put_user(st.st_dev, &target_st->st_dev);
4774 __put_user(st.st_ino, &target_st->st_ino);
4775 __put_user(st.st_mode, &target_st->st_mode);
4776 __put_user(st.st_uid, &target_st->st_uid);
4777 __put_user(st.st_gid, &target_st->st_gid);
4778 __put_user(st.st_nlink, &target_st->st_nlink);
4779 __put_user(st.st_rdev, &target_st->st_rdev);
4780 __put_user(st.st_size, &target_st->st_size);
4781 __put_user(st.st_blksize, &target_st->st_blksize);
4782 __put_user(st.st_blocks, &target_st->st_blocks);
4783 __put_user(st.st_atime, &target_st->target_st_atime);
4784 __put_user(st.st_mtime, &target_st->target_st_mtime);
4785 __put_user(st.st_ctime, &target_st->target_st_ctime);
4786 unlock_user_struct(target_st, arg2, 1);
4789 break;
4790 #ifdef TARGET_NR_olduname
4791 case TARGET_NR_olduname:
4792 goto unimplemented;
4793 #endif
4794 #ifdef TARGET_NR_iopl
4795 case TARGET_NR_iopl:
4796 goto unimplemented;
4797 #endif
4798 case TARGET_NR_vhangup:
4799 ret = get_errno(vhangup());
4800 break;
4801 #ifdef TARGET_NR_idle
4802 case TARGET_NR_idle:
4803 goto unimplemented;
4804 #endif
4805 #ifdef TARGET_NR_syscall
4806 case TARGET_NR_syscall:
4807 ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
4808 break;
4809 #endif
4810 case TARGET_NR_wait4:
4812 int status;
4813 abi_long status_ptr = arg2;
4814 struct rusage rusage, *rusage_ptr;
4815 abi_ulong target_rusage = arg4;
4816 if (target_rusage)
4817 rusage_ptr = &rusage;
4818 else
4819 rusage_ptr = NULL;
4820 ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
4821 if (!is_error(ret)) {
4822 if (status_ptr) {
4823 if (put_user_s32(status, status_ptr))
4824 goto efault;
4826 if (target_rusage)
4827 host_to_target_rusage(target_rusage, &rusage);
4830 break;
4831 #ifdef TARGET_NR_swapoff
4832 case TARGET_NR_swapoff:
4833 if (!(p = lock_user_string(arg1)))
4834 goto efault;
4835 ret = get_errno(swapoff(p));
4836 unlock_user(p, arg1, 0);
4837 break;
4838 #endif
4839 case TARGET_NR_sysinfo:
4841 struct target_sysinfo *target_value;
4842 struct sysinfo value;
4843 ret = get_errno(sysinfo(&value));
4844 if (!is_error(ret) && arg1)
4846 if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
4847 goto efault;
4848 __put_user(value.uptime, &target_value->uptime);
4849 __put_user(value.loads[0], &target_value->loads[0]);
4850 __put_user(value.loads[1], &target_value->loads[1]);
4851 __put_user(value.loads[2], &target_value->loads[2]);
4852 __put_user(value.totalram, &target_value->totalram);
4853 __put_user(value.freeram, &target_value->freeram);
4854 __put_user(value.sharedram, &target_value->sharedram);
4855 __put_user(value.bufferram, &target_value->bufferram);
4856 __put_user(value.totalswap, &target_value->totalswap);
4857 __put_user(value.freeswap, &target_value->freeswap);
4858 __put_user(value.procs, &target_value->procs);
4859 __put_user(value.totalhigh, &target_value->totalhigh);
4860 __put_user(value.freehigh, &target_value->freehigh);
4861 __put_user(value.mem_unit, &target_value->mem_unit);
4862 unlock_user_struct(target_value, arg1, 1);
4865 break;
4866 #ifdef TARGET_NR_ipc
4867 case TARGET_NR_ipc:
4868 ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
4869 break;
4870 #endif
4872 #ifdef TARGET_NR_msgctl
4873 case TARGET_NR_msgctl:
4874 ret = do_msgctl(arg1, arg2, arg3);
4875 break;
4876 #endif
4877 #ifdef TARGET_NR_msgget
4878 case TARGET_NR_msgget:
4879 ret = get_errno(msgget(arg1, arg2));
4880 break;
4881 #endif
4882 #ifdef TARGET_NR_msgrcv
4883 case TARGET_NR_msgrcv:
4884 ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
4885 break;
4886 #endif
4887 #ifdef TARGET_NR_msgsnd
4888 case TARGET_NR_msgsnd:
4889 ret = do_msgsnd(arg1, arg2, arg3, arg4);
4890 break;
4891 #endif
4892 case TARGET_NR_fsync:
4893 ret = get_errno(fsync(arg1));
4894 break;
4895 case TARGET_NR_clone:
4896 #if defined(TARGET_SH4)
4897 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
4898 #elif defined(TARGET_CRIS)
4899 ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg4, arg5));
4900 #else
4901 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
4902 #endif
4903 break;
4904 #ifdef __NR_exit_group
4905 /* new thread calls */
4906 case TARGET_NR_exit_group:
4907 #ifdef HAVE_GPROF
4908 _mcleanup();
4909 #endif
4910 gdb_exit(cpu_env, arg1);
4911 ret = get_errno(exit_group(arg1));
4912 break;
4913 #endif
4914 case TARGET_NR_setdomainname:
4915 if (!(p = lock_user_string(arg1)))
4916 goto efault;
4917 ret = get_errno(setdomainname(p, arg2));
4918 unlock_user(p, arg1, 0);
4919 break;
4920 case TARGET_NR_uname:
4921 /* no need to transcode because we use the linux syscall */
4923 struct new_utsname * buf;
4925 if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
4926 goto efault;
4927 ret = get_errno(sys_uname(buf));
4928 if (!is_error(ret)) {
4929 /* Overrite the native machine name with whatever is being
4930 emulated. */
4931 strcpy (buf->machine, UNAME_MACHINE);
4932 /* Allow the user to override the reported release. */
4933 if (qemu_uname_release && *qemu_uname_release)
4934 strcpy (buf->release, qemu_uname_release);
4936 unlock_user_struct(buf, arg1, 1);
4938 break;
4939 #ifdef TARGET_I386
4940 case TARGET_NR_modify_ldt:
4941 ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
4942 break;
4943 #if !defined(TARGET_X86_64)
4944 case TARGET_NR_vm86old:
4945 goto unimplemented;
4946 case TARGET_NR_vm86:
4947 ret = do_vm86(cpu_env, arg1, arg2);
4948 break;
4949 #endif
4950 #endif
4951 case TARGET_NR_adjtimex:
4952 goto unimplemented;
4953 #ifdef TARGET_NR_create_module
4954 case TARGET_NR_create_module:
4955 #endif
4956 case TARGET_NR_init_module:
4957 case TARGET_NR_delete_module:
4958 #ifdef TARGET_NR_get_kernel_syms
4959 case TARGET_NR_get_kernel_syms:
4960 #endif
4961 goto unimplemented;
4962 case TARGET_NR_quotactl:
4963 goto unimplemented;
4964 case TARGET_NR_getpgid:
4965 ret = get_errno(getpgid(arg1));
4966 break;
4967 case TARGET_NR_fchdir:
4968 ret = get_errno(fchdir(arg1));
4969 break;
4970 #ifdef TARGET_NR_bdflush /* not on x86_64 */
4971 case TARGET_NR_bdflush:
4972 goto unimplemented;
4973 #endif
4974 #ifdef TARGET_NR_sysfs
4975 case TARGET_NR_sysfs:
4976 goto unimplemented;
4977 #endif
4978 case TARGET_NR_personality:
4979 ret = get_errno(personality(arg1));
4980 break;
4981 #ifdef TARGET_NR_afs_syscall
4982 case TARGET_NR_afs_syscall:
4983 goto unimplemented;
4984 #endif
4985 #ifdef TARGET_NR__llseek /* Not on alpha */
4986 case TARGET_NR__llseek:
4988 #if defined (__x86_64__)
4989 ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
4990 if (put_user_s64(ret, arg4))
4991 goto efault;
4992 #else
4993 int64_t res;
4994 ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
4995 if (put_user_s64(res, arg4))
4996 goto efault;
4997 #endif
4999 break;
5000 #endif
5001 case TARGET_NR_getdents:
5002 #if TARGET_ABI_BITS != 32
5003 goto unimplemented;
5004 #elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
5006 struct target_dirent *target_dirp;
5007 struct linux_dirent *dirp;
5008 abi_long count = arg3;
5010 dirp = malloc(count);
5011 if (!dirp) {
5012 ret = -TARGET_ENOMEM;
5013 goto fail;
5016 ret = get_errno(sys_getdents(arg1, dirp, count));
5017 if (!is_error(ret)) {
5018 struct linux_dirent *de;
5019 struct target_dirent *tde;
5020 int len = ret;
5021 int reclen, treclen;
5022 int count1, tnamelen;
5024 count1 = 0;
5025 de = dirp;
5026 if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5027 goto efault;
5028 tde = target_dirp;
5029 while (len > 0) {
5030 reclen = de->d_reclen;
5031 treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
5032 tde->d_reclen = tswap16(treclen);
5033 tde->d_ino = tswapl(de->d_ino);
5034 tde->d_off = tswapl(de->d_off);
5035 tnamelen = treclen - (2 * sizeof(abi_long) + 2);
5036 if (tnamelen > 256)
5037 tnamelen = 256;
5038 /* XXX: may not be correct */
5039 pstrcpy(tde->d_name, tnamelen, de->d_name);
5040 de = (struct linux_dirent *)((char *)de + reclen);
5041 len -= reclen;
5042 tde = (struct target_dirent *)((char *)tde + treclen);
5043 count1 += treclen;
5045 ret = count1;
5046 unlock_user(target_dirp, arg2, ret);
5048 free(dirp);
5050 #else
5052 struct linux_dirent *dirp;
5053 abi_long count = arg3;
5055 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5056 goto efault;
5057 ret = get_errno(sys_getdents(arg1, dirp, count));
5058 if (!is_error(ret)) {
5059 struct linux_dirent *de;
5060 int len = ret;
5061 int reclen;
5062 de = dirp;
5063 while (len > 0) {
5064 reclen = de->d_reclen;
5065 if (reclen > len)
5066 break;
5067 de->d_reclen = tswap16(reclen);
5068 tswapls(&de->d_ino);
5069 tswapls(&de->d_off);
5070 de = (struct linux_dirent *)((char *)de + reclen);
5071 len -= reclen;
5074 unlock_user(dirp, arg2, ret);
5076 #endif
5077 break;
5078 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
5079 case TARGET_NR_getdents64:
5081 struct linux_dirent64 *dirp;
5082 abi_long count = arg3;
5083 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5084 goto efault;
5085 ret = get_errno(sys_getdents64(arg1, dirp, count));
5086 if (!is_error(ret)) {
5087 struct linux_dirent64 *de;
5088 int len = ret;
5089 int reclen;
5090 de = dirp;
5091 while (len > 0) {
5092 reclen = de->d_reclen;
5093 if (reclen > len)
5094 break;
5095 de->d_reclen = tswap16(reclen);
5096 tswap64s((uint64_t *)&de->d_ino);
5097 tswap64s((uint64_t *)&de->d_off);
5098 de = (struct linux_dirent64 *)((char *)de + reclen);
5099 len -= reclen;
5102 unlock_user(dirp, arg2, ret);
5104 break;
5105 #endif /* TARGET_NR_getdents64 */
5106 #ifdef TARGET_NR__newselect
5107 case TARGET_NR__newselect:
5108 ret = do_select(arg1, arg2, arg3, arg4, arg5);
5109 break;
5110 #endif
5111 #ifdef TARGET_NR_poll
5112 case TARGET_NR_poll:
5114 struct target_pollfd *target_pfd;
5115 unsigned int nfds = arg2;
5116 int timeout = arg3;
5117 struct pollfd *pfd;
5118 unsigned int i;
5120 target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
5121 if (!target_pfd)
5122 goto efault;
5123 pfd = alloca(sizeof(struct pollfd) * nfds);
5124 for(i = 0; i < nfds; i++) {
5125 pfd[i].fd = tswap32(target_pfd[i].fd);
5126 pfd[i].events = tswap16(target_pfd[i].events);
5128 ret = get_errno(poll(pfd, nfds, timeout));
5129 if (!is_error(ret)) {
5130 for(i = 0; i < nfds; i++) {
5131 target_pfd[i].revents = tswap16(pfd[i].revents);
5133 ret += nfds * (sizeof(struct target_pollfd)
5134 - sizeof(struct pollfd));
5136 unlock_user(target_pfd, arg1, ret);
5138 break;
5139 #endif
5140 case TARGET_NR_flock:
5141 /* NOTE: the flock constant seems to be the same for every
5142 Linux platform */
5143 ret = get_errno(flock(arg1, arg2));
5144 break;
5145 case TARGET_NR_readv:
5147 int count = arg3;
5148 struct iovec *vec;
5150 vec = alloca(count * sizeof(struct iovec));
5151 if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
5152 goto efault;
5153 ret = get_errno(readv(arg1, vec, count));
5154 unlock_iovec(vec, arg2, count, 1);
5156 break;
5157 case TARGET_NR_writev:
5159 int count = arg3;
5160 struct iovec *vec;
5162 vec = alloca(count * sizeof(struct iovec));
5163 if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
5164 goto efault;
5165 ret = get_errno(writev(arg1, vec, count));
5166 unlock_iovec(vec, arg2, count, 0);
5168 break;
5169 case TARGET_NR_getsid:
5170 ret = get_errno(getsid(arg1));
5171 break;
5172 #if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
5173 case TARGET_NR_fdatasync:
5174 ret = get_errno(fdatasync(arg1));
5175 break;
5176 #endif
5177 case TARGET_NR__sysctl:
5178 /* We don't implement this, but ENOTDIR is always a safe
5179 return value. */
5180 ret = -TARGET_ENOTDIR;
5181 break;
5182 case TARGET_NR_sched_setparam:
5184 struct sched_param *target_schp;
5185 struct sched_param schp;
5187 if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
5188 goto efault;
5189 schp.sched_priority = tswap32(target_schp->sched_priority);
5190 unlock_user_struct(target_schp, arg2, 0);
5191 ret = get_errno(sched_setparam(arg1, &schp));
5193 break;
5194 case TARGET_NR_sched_getparam:
5196 struct sched_param *target_schp;
5197 struct sched_param schp;
5198 ret = get_errno(sched_getparam(arg1, &schp));
5199 if (!is_error(ret)) {
5200 if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
5201 goto efault;
5202 target_schp->sched_priority = tswap32(schp.sched_priority);
5203 unlock_user_struct(target_schp, arg2, 1);
5206 break;
5207 case TARGET_NR_sched_setscheduler:
5209 struct sched_param *target_schp;
5210 struct sched_param schp;
5211 if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
5212 goto efault;
5213 schp.sched_priority = tswap32(target_schp->sched_priority);
5214 unlock_user_struct(target_schp, arg3, 0);
5215 ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
5217 break;
5218 case TARGET_NR_sched_getscheduler:
5219 ret = get_errno(sched_getscheduler(arg1));
5220 break;
5221 case TARGET_NR_sched_yield:
5222 ret = get_errno(sched_yield());
5223 break;
5224 case TARGET_NR_sched_get_priority_max:
5225 ret = get_errno(sched_get_priority_max(arg1));
5226 break;
5227 case TARGET_NR_sched_get_priority_min:
5228 ret = get_errno(sched_get_priority_min(arg1));
5229 break;
5230 case TARGET_NR_sched_rr_get_interval:
5232 struct timespec ts;
5233 ret = get_errno(sched_rr_get_interval(arg1, &ts));
5234 if (!is_error(ret)) {
5235 host_to_target_timespec(arg2, &ts);
5238 break;
5239 case TARGET_NR_nanosleep:
5241 struct timespec req, rem;
5242 target_to_host_timespec(&req, arg1);
5243 ret = get_errno(nanosleep(&req, &rem));
5244 if (is_error(ret) && arg2) {
5245 host_to_target_timespec(arg2, &rem);
5248 break;
5249 #ifdef TARGET_NR_query_module
5250 case TARGET_NR_query_module:
5251 goto unimplemented;
5252 #endif
5253 #ifdef TARGET_NR_nfsservctl
5254 case TARGET_NR_nfsservctl:
5255 goto unimplemented;
5256 #endif
5257 case TARGET_NR_prctl:
5258 switch (arg1)
5260 case PR_GET_PDEATHSIG:
5262 int deathsig;
5263 ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
5264 if (!is_error(ret) && arg2
5265 && put_user_ual(deathsig, arg2))
5266 goto efault;
5268 break;
5269 default:
5270 ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
5271 break;
5273 break;
5274 #ifdef TARGET_NR_arch_prctl
5275 case TARGET_NR_arch_prctl:
5276 #if defined(TARGET_I386) && !defined(TARGET_ABI32)
5277 ret = do_arch_prctl(cpu_env, arg1, arg2);
5278 break;
5279 #else
5280 goto unimplemented;
5281 #endif
5282 #endif
5283 #ifdef TARGET_NR_pread
5284 case TARGET_NR_pread:
5285 #ifdef TARGET_ARM
5286 if (((CPUARMState *)cpu_env)->eabi)
5287 arg4 = arg5;
5288 #endif
5289 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5290 goto efault;
5291 ret = get_errno(pread(arg1, p, arg3, arg4));
5292 unlock_user(p, arg2, ret);
5293 break;
5294 case TARGET_NR_pwrite:
5295 #ifdef TARGET_ARM
5296 if (((CPUARMState *)cpu_env)->eabi)
5297 arg4 = arg5;
5298 #endif
5299 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5300 goto efault;
5301 ret = get_errno(pwrite(arg1, p, arg3, arg4));
5302 unlock_user(p, arg2, 0);
5303 break;
5304 #endif
5305 #ifdef TARGET_NR_pread64
5306 case TARGET_NR_pread64:
5307 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5308 goto efault;
5309 ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
5310 unlock_user(p, arg2, ret);
5311 break;
5312 case TARGET_NR_pwrite64:
5313 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5314 goto efault;
5315 ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
5316 unlock_user(p, arg2, 0);
5317 break;
5318 #endif
5319 case TARGET_NR_getcwd:
5320 if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
5321 goto efault;
5322 ret = get_errno(sys_getcwd1(p, arg2));
5323 unlock_user(p, arg1, ret);
5324 break;
5325 case TARGET_NR_capget:
5326 goto unimplemented;
5327 case TARGET_NR_capset:
5328 goto unimplemented;
5329 case TARGET_NR_sigaltstack:
5330 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
5331 defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA)
5332 ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env));
5333 break;
5334 #else
5335 goto unimplemented;
5336 #endif
5337 case TARGET_NR_sendfile:
5338 goto unimplemented;
5339 #ifdef TARGET_NR_getpmsg
5340 case TARGET_NR_getpmsg:
5341 goto unimplemented;
5342 #endif
5343 #ifdef TARGET_NR_putpmsg
5344 case TARGET_NR_putpmsg:
5345 goto unimplemented;
5346 #endif
5347 #ifdef TARGET_NR_vfork
5348 case TARGET_NR_vfork:
5349 ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
5350 0, 0, 0, 0));
5351 break;
5352 #endif
5353 #ifdef TARGET_NR_ugetrlimit
5354 case TARGET_NR_ugetrlimit:
5356 struct rlimit rlim;
5357 ret = get_errno(getrlimit(arg1, &rlim));
5358 if (!is_error(ret)) {
5359 struct target_rlimit *target_rlim;
5360 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
5361 goto efault;
5362 target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
5363 target_rlim->rlim_max = tswapl(rlim.rlim_max);
5364 unlock_user_struct(target_rlim, arg2, 1);
5366 break;
5368 #endif
5369 #ifdef TARGET_NR_truncate64
5370 case TARGET_NR_truncate64:
5371 if (!(p = lock_user_string(arg1)))
5372 goto efault;
5373 ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
5374 unlock_user(p, arg1, 0);
5375 break;
5376 #endif
5377 #ifdef TARGET_NR_ftruncate64
5378 case TARGET_NR_ftruncate64:
5379 ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
5380 break;
5381 #endif
5382 #ifdef TARGET_NR_stat64
5383 case TARGET_NR_stat64:
5384 if (!(p = lock_user_string(arg1)))
5385 goto efault;
5386 ret = get_errno(stat(path(p), &st));
5387 unlock_user(p, arg1, 0);
5388 if (!is_error(ret))
5389 ret = host_to_target_stat64(cpu_env, arg2, &st);
5390 break;
5391 #endif
5392 #ifdef TARGET_NR_lstat64
5393 case TARGET_NR_lstat64:
5394 if (!(p = lock_user_string(arg1)))
5395 goto efault;
5396 ret = get_errno(lstat(path(p), &st));
5397 unlock_user(p, arg1, 0);
5398 if (!is_error(ret))
5399 ret = host_to_target_stat64(cpu_env, arg2, &st);
5400 break;
5401 #endif
5402 #ifdef TARGET_NR_fstat64
5403 case TARGET_NR_fstat64:
5404 ret = get_errno(fstat(arg1, &st));
5405 if (!is_error(ret))
5406 ret = host_to_target_stat64(cpu_env, arg2, &st);
5407 break;
5408 #endif
5409 #if defined(TARGET_NR_fstatat64) && defined(__NR_fstatat64)
5410 case TARGET_NR_fstatat64:
5411 if (!(p = lock_user_string(arg2)))
5412 goto efault;
5413 ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
5414 if (!is_error(ret))
5415 ret = host_to_target_stat64(cpu_env, arg3, &st);
5416 break;
5417 #endif
5418 #ifdef USE_UID16
5419 case TARGET_NR_lchown:
5420 if (!(p = lock_user_string(arg1)))
5421 goto efault;
5422 ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
5423 unlock_user(p, arg1, 0);
5424 break;
5425 case TARGET_NR_getuid:
5426 ret = get_errno(high2lowuid(getuid()));
5427 break;
5428 case TARGET_NR_getgid:
5429 ret = get_errno(high2lowgid(getgid()));
5430 break;
5431 case TARGET_NR_geteuid:
5432 ret = get_errno(high2lowuid(geteuid()));
5433 break;
5434 case TARGET_NR_getegid:
5435 ret = get_errno(high2lowgid(getegid()));
5436 break;
5437 case TARGET_NR_setreuid:
5438 ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
5439 break;
5440 case TARGET_NR_setregid:
5441 ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
5442 break;
5443 case TARGET_NR_getgroups:
5445 int gidsetsize = arg1;
5446 uint16_t *target_grouplist;
5447 gid_t *grouplist;
5448 int i;
5450 grouplist = alloca(gidsetsize * sizeof(gid_t));
5451 ret = get_errno(getgroups(gidsetsize, grouplist));
5452 if (gidsetsize == 0)
5453 break;
5454 if (!is_error(ret)) {
5455 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
5456 if (!target_grouplist)
5457 goto efault;
5458 for(i = 0;i < ret; i++)
5459 target_grouplist[i] = tswap16(grouplist[i]);
5460 unlock_user(target_grouplist, arg2, gidsetsize * 2);
5463 break;
5464 case TARGET_NR_setgroups:
5466 int gidsetsize = arg1;
5467 uint16_t *target_grouplist;
5468 gid_t *grouplist;
5469 int i;
5471 grouplist = alloca(gidsetsize * sizeof(gid_t));
5472 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
5473 if (!target_grouplist) {
5474 ret = -TARGET_EFAULT;
5475 goto fail;
5477 for(i = 0;i < gidsetsize; i++)
5478 grouplist[i] = tswap16(target_grouplist[i]);
5479 unlock_user(target_grouplist, arg2, 0);
5480 ret = get_errno(setgroups(gidsetsize, grouplist));
5482 break;
5483 case TARGET_NR_fchown:
5484 ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
5485 break;
5486 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
5487 case TARGET_NR_fchownat:
5488 if (!(p = lock_user_string(arg2)))
5489 goto efault;
5490 ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
5491 unlock_user(p, arg2, 0);
5492 break;
5493 #endif
5494 #ifdef TARGET_NR_setresuid
5495 case TARGET_NR_setresuid:
5496 ret = get_errno(setresuid(low2highuid(arg1),
5497 low2highuid(arg2),
5498 low2highuid(arg3)));
5499 break;
5500 #endif
5501 #ifdef TARGET_NR_getresuid
5502 case TARGET_NR_getresuid:
5504 uid_t ruid, euid, suid;
5505 ret = get_errno(getresuid(&ruid, &euid, &suid));
5506 if (!is_error(ret)) {
5507 if (put_user_u16(high2lowuid(ruid), arg1)
5508 || put_user_u16(high2lowuid(euid), arg2)
5509 || put_user_u16(high2lowuid(suid), arg3))
5510 goto efault;
5513 break;
5514 #endif
5515 #ifdef TARGET_NR_getresgid
5516 case TARGET_NR_setresgid:
5517 ret = get_errno(setresgid(low2highgid(arg1),
5518 low2highgid(arg2),
5519 low2highgid(arg3)));
5520 break;
5521 #endif
5522 #ifdef TARGET_NR_getresgid
5523 case TARGET_NR_getresgid:
5525 gid_t rgid, egid, sgid;
5526 ret = get_errno(getresgid(&rgid, &egid, &sgid));
5527 if (!is_error(ret)) {
5528 if (put_user_u16(high2lowgid(rgid), arg1)
5529 || put_user_u16(high2lowgid(egid), arg2)
5530 || put_user_u16(high2lowgid(sgid), arg3))
5531 goto efault;
5534 break;
5535 #endif
5536 case TARGET_NR_chown:
5537 if (!(p = lock_user_string(arg1)))
5538 goto efault;
5539 ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
5540 unlock_user(p, arg1, 0);
5541 break;
5542 case TARGET_NR_setuid:
5543 ret = get_errno(setuid(low2highuid(arg1)));
5544 break;
5545 case TARGET_NR_setgid:
5546 ret = get_errno(setgid(low2highgid(arg1)));
5547 break;
5548 case TARGET_NR_setfsuid:
5549 ret = get_errno(setfsuid(arg1));
5550 break;
5551 case TARGET_NR_setfsgid:
5552 ret = get_errno(setfsgid(arg1));
5553 break;
5554 #endif /* USE_UID16 */
5556 #ifdef TARGET_NR_lchown32
5557 case TARGET_NR_lchown32:
5558 if (!(p = lock_user_string(arg1)))
5559 goto efault;
5560 ret = get_errno(lchown(p, arg2, arg3));
5561 unlock_user(p, arg1, 0);
5562 break;
5563 #endif
5564 #ifdef TARGET_NR_getuid32
5565 case TARGET_NR_getuid32:
5566 ret = get_errno(getuid());
5567 break;
5568 #endif
5570 #if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
5571 /* Alpha specific */
5572 case TARGET_NR_getxuid:
5574 uid_t euid;
5575 euid=geteuid();
5576 ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
5578 ret = get_errno(getuid());
5579 break;
5580 #endif
5581 #if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
5582 /* Alpha specific */
5583 case TARGET_NR_getxgid:
5585 uid_t egid;
5586 egid=getegid();
5587 ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
5589 ret = get_errno(getgid());
5590 break;
5591 #endif
5593 #ifdef TARGET_NR_getgid32
5594 case TARGET_NR_getgid32:
5595 ret = get_errno(getgid());
5596 break;
5597 #endif
5598 #ifdef TARGET_NR_geteuid32
5599 case TARGET_NR_geteuid32:
5600 ret = get_errno(geteuid());
5601 break;
5602 #endif
5603 #ifdef TARGET_NR_getegid32
5604 case TARGET_NR_getegid32:
5605 ret = get_errno(getegid());
5606 break;
5607 #endif
5608 #ifdef TARGET_NR_setreuid32
5609 case TARGET_NR_setreuid32:
5610 ret = get_errno(setreuid(arg1, arg2));
5611 break;
5612 #endif
5613 #ifdef TARGET_NR_setregid32
5614 case TARGET_NR_setregid32:
5615 ret = get_errno(setregid(arg1, arg2));
5616 break;
5617 #endif
5618 #ifdef TARGET_NR_getgroups32
5619 case TARGET_NR_getgroups32:
5621 int gidsetsize = arg1;
5622 uint32_t *target_grouplist;
5623 gid_t *grouplist;
5624 int i;
5626 grouplist = alloca(gidsetsize * sizeof(gid_t));
5627 ret = get_errno(getgroups(gidsetsize, grouplist));
5628 if (gidsetsize == 0)
5629 break;
5630 if (!is_error(ret)) {
5631 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
5632 if (!target_grouplist) {
5633 ret = -TARGET_EFAULT;
5634 goto fail;
5636 for(i = 0;i < ret; i++)
5637 target_grouplist[i] = tswap32(grouplist[i]);
5638 unlock_user(target_grouplist, arg2, gidsetsize * 4);
5641 break;
5642 #endif
5643 #ifdef TARGET_NR_setgroups32
5644 case TARGET_NR_setgroups32:
5646 int gidsetsize = arg1;
5647 uint32_t *target_grouplist;
5648 gid_t *grouplist;
5649 int i;
5651 grouplist = alloca(gidsetsize * sizeof(gid_t));
5652 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
5653 if (!target_grouplist) {
5654 ret = -TARGET_EFAULT;
5655 goto fail;
5657 for(i = 0;i < gidsetsize; i++)
5658 grouplist[i] = tswap32(target_grouplist[i]);
5659 unlock_user(target_grouplist, arg2, 0);
5660 ret = get_errno(setgroups(gidsetsize, grouplist));
5662 break;
5663 #endif
5664 #ifdef TARGET_NR_fchown32
5665 case TARGET_NR_fchown32:
5666 ret = get_errno(fchown(arg1, arg2, arg3));
5667 break;
5668 #endif
5669 #ifdef TARGET_NR_setresuid32
5670 case TARGET_NR_setresuid32:
5671 ret = get_errno(setresuid(arg1, arg2, arg3));
5672 break;
5673 #endif
5674 #ifdef TARGET_NR_getresuid32
5675 case TARGET_NR_getresuid32:
5677 uid_t ruid, euid, suid;
5678 ret = get_errno(getresuid(&ruid, &euid, &suid));
5679 if (!is_error(ret)) {
5680 if (put_user_u32(ruid, arg1)
5681 || put_user_u32(euid, arg2)
5682 || put_user_u32(suid, arg3))
5683 goto efault;
5686 break;
5687 #endif
5688 #ifdef TARGET_NR_setresgid32
5689 case TARGET_NR_setresgid32:
5690 ret = get_errno(setresgid(arg1, arg2, arg3));
5691 break;
5692 #endif
5693 #ifdef TARGET_NR_getresgid32
5694 case TARGET_NR_getresgid32:
5696 gid_t rgid, egid, sgid;
5697 ret = get_errno(getresgid(&rgid, &egid, &sgid));
5698 if (!is_error(ret)) {
5699 if (put_user_u32(rgid, arg1)
5700 || put_user_u32(egid, arg2)
5701 || put_user_u32(sgid, arg3))
5702 goto efault;
5705 break;
5706 #endif
5707 #ifdef TARGET_NR_chown32
5708 case TARGET_NR_chown32:
5709 if (!(p = lock_user_string(arg1)))
5710 goto efault;
5711 ret = get_errno(chown(p, arg2, arg3));
5712 unlock_user(p, arg1, 0);
5713 break;
5714 #endif
5715 #ifdef TARGET_NR_setuid32
5716 case TARGET_NR_setuid32:
5717 ret = get_errno(setuid(arg1));
5718 break;
5719 #endif
5720 #ifdef TARGET_NR_setgid32
5721 case TARGET_NR_setgid32:
5722 ret = get_errno(setgid(arg1));
5723 break;
5724 #endif
5725 #ifdef TARGET_NR_setfsuid32
5726 case TARGET_NR_setfsuid32:
5727 ret = get_errno(setfsuid(arg1));
5728 break;
5729 #endif
5730 #ifdef TARGET_NR_setfsgid32
5731 case TARGET_NR_setfsgid32:
5732 ret = get_errno(setfsgid(arg1));
5733 break;
5734 #endif
5736 case TARGET_NR_pivot_root:
5737 goto unimplemented;
5738 #ifdef TARGET_NR_mincore
5739 case TARGET_NR_mincore:
5741 void *a;
5742 ret = -TARGET_EFAULT;
5743 if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
5744 goto efault;
5745 if (!(p = lock_user_string(arg3)))
5746 goto mincore_fail;
5747 ret = get_errno(mincore(a, arg2, p));
5748 unlock_user(p, arg3, ret);
5749 mincore_fail:
5750 unlock_user(a, arg1, 0);
5752 break;
5753 #endif
5754 #ifdef TARGET_NR_arm_fadvise64_64
5755 case TARGET_NR_arm_fadvise64_64:
5758 * arm_fadvise64_64 looks like fadvise64_64 but
5759 * with different argument order
5761 abi_long temp;
5762 temp = arg3;
5763 arg3 = arg4;
5764 arg4 = temp;
5766 #endif
5767 #if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64)
5768 #ifdef TARGET_NR_fadvise64_64
5769 case TARGET_NR_fadvise64_64:
5770 #endif
5771 /* This is a hint, so ignoring and returning success is ok. */
5772 ret = get_errno(0);
5773 break;
5774 #endif
5775 #ifdef TARGET_NR_madvise
5776 case TARGET_NR_madvise:
5777 /* A straight passthrough may not be safe because qemu sometimes
5778 turns private flie-backed mappings into anonymous mappings.
5779 This will break MADV_DONTNEED.
5780 This is a hint, so ignoring and returning success is ok. */
5781 ret = get_errno(0);
5782 break;
5783 #endif
5784 #if TARGET_ABI_BITS == 32
5785 case TARGET_NR_fcntl64:
5787 int cmd;
5788 struct flock64 fl;
5789 struct target_flock64 *target_fl;
5790 #ifdef TARGET_ARM
5791 struct target_eabi_flock64 *target_efl;
5792 #endif
5794 switch(arg2){
5795 case TARGET_F_GETLK64:
5796 cmd = F_GETLK64;
5797 break;
5798 case TARGET_F_SETLK64:
5799 cmd = F_SETLK64;
5800 break;
5801 case TARGET_F_SETLKW64:
5802 cmd = F_SETLK64;
5803 break;
5804 default:
5805 cmd = arg2;
5806 break;
5809 switch(arg2) {
5810 case TARGET_F_GETLK64:
5811 #ifdef TARGET_ARM
5812 if (((CPUARMState *)cpu_env)->eabi) {
5813 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1))
5814 goto efault;
5815 fl.l_type = tswap16(target_efl->l_type);
5816 fl.l_whence = tswap16(target_efl->l_whence);
5817 fl.l_start = tswap64(target_efl->l_start);
5818 fl.l_len = tswap64(target_efl->l_len);
5819 fl.l_pid = tswapl(target_efl->l_pid);
5820 unlock_user_struct(target_efl, arg3, 0);
5821 } else
5822 #endif
5824 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1))
5825 goto efault;
5826 fl.l_type = tswap16(target_fl->l_type);
5827 fl.l_whence = tswap16(target_fl->l_whence);
5828 fl.l_start = tswap64(target_fl->l_start);
5829 fl.l_len = tswap64(target_fl->l_len);
5830 fl.l_pid = tswapl(target_fl->l_pid);
5831 unlock_user_struct(target_fl, arg3, 0);
5833 ret = get_errno(fcntl(arg1, cmd, &fl));
5834 if (ret == 0) {
5835 #ifdef TARGET_ARM
5836 if (((CPUARMState *)cpu_env)->eabi) {
5837 if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0))
5838 goto efault;
5839 target_efl->l_type = tswap16(fl.l_type);
5840 target_efl->l_whence = tswap16(fl.l_whence);
5841 target_efl->l_start = tswap64(fl.l_start);
5842 target_efl->l_len = tswap64(fl.l_len);
5843 target_efl->l_pid = tswapl(fl.l_pid);
5844 unlock_user_struct(target_efl, arg3, 1);
5845 } else
5846 #endif
5848 if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0))
5849 goto efault;
5850 target_fl->l_type = tswap16(fl.l_type);
5851 target_fl->l_whence = tswap16(fl.l_whence);
5852 target_fl->l_start = tswap64(fl.l_start);
5853 target_fl->l_len = tswap64(fl.l_len);
5854 target_fl->l_pid = tswapl(fl.l_pid);
5855 unlock_user_struct(target_fl, arg3, 1);
5858 break;
5860 case TARGET_F_SETLK64:
5861 case TARGET_F_SETLKW64:
5862 #ifdef TARGET_ARM
5863 if (((CPUARMState *)cpu_env)->eabi) {
5864 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1))
5865 goto efault;
5866 fl.l_type = tswap16(target_efl->l_type);
5867 fl.l_whence = tswap16(target_efl->l_whence);
5868 fl.l_start = tswap64(target_efl->l_start);
5869 fl.l_len = tswap64(target_efl->l_len);
5870 fl.l_pid = tswapl(target_efl->l_pid);
5871 unlock_user_struct(target_efl, arg3, 0);
5872 } else
5873 #endif
5875 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1))
5876 goto efault;
5877 fl.l_type = tswap16(target_fl->l_type);
5878 fl.l_whence = tswap16(target_fl->l_whence);
5879 fl.l_start = tswap64(target_fl->l_start);
5880 fl.l_len = tswap64(target_fl->l_len);
5881 fl.l_pid = tswapl(target_fl->l_pid);
5882 unlock_user_struct(target_fl, arg3, 0);
5884 ret = get_errno(fcntl(arg1, cmd, &fl));
5885 break;
5886 default:
5887 ret = do_fcntl(arg1, cmd, arg3);
5888 break;
5890 break;
5892 #endif
5893 #ifdef TARGET_NR_cacheflush
5894 case TARGET_NR_cacheflush:
5895 /* self-modifying code is handled automatically, so nothing needed */
5896 ret = 0;
5897 break;
5898 #endif
5899 #ifdef TARGET_NR_security
5900 case TARGET_NR_security:
5901 goto unimplemented;
5902 #endif
5903 #ifdef TARGET_NR_getpagesize
5904 case TARGET_NR_getpagesize:
5905 ret = TARGET_PAGE_SIZE;
5906 break;
5907 #endif
5908 case TARGET_NR_gettid:
5909 ret = get_errno(gettid());
5910 break;
5911 #ifdef TARGET_NR_readahead
5912 case TARGET_NR_readahead:
5913 #if TARGET_ABI_BITS == 32
5914 #ifdef TARGET_ARM
5915 if (((CPUARMState *)cpu_env)->eabi)
5917 arg2 = arg3;
5918 arg3 = arg4;
5919 arg4 = arg5;
5921 #endif
5922 ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
5923 #else
5924 ret = get_errno(readahead(arg1, arg2, arg3));
5925 #endif
5926 break;
5927 #endif
5928 #ifdef TARGET_NR_setxattr
5929 case TARGET_NR_setxattr:
5930 case TARGET_NR_lsetxattr:
5931 case TARGET_NR_fsetxattr:
5932 case TARGET_NR_getxattr:
5933 case TARGET_NR_lgetxattr:
5934 case TARGET_NR_fgetxattr:
5935 case TARGET_NR_listxattr:
5936 case TARGET_NR_llistxattr:
5937 case TARGET_NR_flistxattr:
5938 case TARGET_NR_removexattr:
5939 case TARGET_NR_lremovexattr:
5940 case TARGET_NR_fremovexattr:
5941 goto unimplemented_nowarn;
5942 #endif
5943 #ifdef TARGET_NR_set_thread_area
5944 case TARGET_NR_set_thread_area:
5945 #if defined(TARGET_MIPS)
5946 ((CPUMIPSState *) cpu_env)->tls_value = arg1;
5947 ret = 0;
5948 break;
5949 #elif defined(TARGET_CRIS)
5950 if (arg1 & 0xff)
5951 ret = -TARGET_EINVAL;
5952 else {
5953 ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
5954 ret = 0;
5956 break;
5957 #elif defined(TARGET_I386) && defined(TARGET_ABI32)
5958 ret = do_set_thread_area(cpu_env, arg1);
5959 break;
5960 #else
5961 goto unimplemented_nowarn;
5962 #endif
5963 #endif
5964 #ifdef TARGET_NR_get_thread_area
5965 case TARGET_NR_get_thread_area:
5966 #if defined(TARGET_I386) && defined(TARGET_ABI32)
5967 ret = do_get_thread_area(cpu_env, arg1);
5968 #else
5969 goto unimplemented_nowarn;
5970 #endif
5971 #endif
5972 #ifdef TARGET_NR_getdomainname
5973 case TARGET_NR_getdomainname:
5974 goto unimplemented_nowarn;
5975 #endif
5977 #ifdef TARGET_NR_clock_gettime
5978 case TARGET_NR_clock_gettime:
5980 struct timespec ts;
5981 ret = get_errno(clock_gettime(arg1, &ts));
5982 if (!is_error(ret)) {
5983 host_to_target_timespec(arg2, &ts);
5985 break;
5987 #endif
5988 #ifdef TARGET_NR_clock_getres
5989 case TARGET_NR_clock_getres:
5991 struct timespec ts;
5992 ret = get_errno(clock_getres(arg1, &ts));
5993 if (!is_error(ret)) {
5994 host_to_target_timespec(arg2, &ts);
5996 break;
5998 #endif
5999 #ifdef TARGET_NR_clock_nanosleep
6000 case TARGET_NR_clock_nanosleep:
6002 struct timespec ts;
6003 target_to_host_timespec(&ts, arg3);
6004 ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
6005 if (arg4)
6006 host_to_target_timespec(arg4, &ts);
6007 break;
6009 #endif
6011 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
6012 case TARGET_NR_set_tid_address:
6013 ret = get_errno(set_tid_address((int *)g2h(arg1)));
6014 break;
6015 #endif
6017 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
6018 case TARGET_NR_tkill:
6019 ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
6020 break;
6021 #endif
6023 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
6024 case TARGET_NR_tgkill:
6025 ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
6026 target_to_host_signal(arg3)));
6027 break;
6028 #endif
6030 #ifdef TARGET_NR_set_robust_list
6031 case TARGET_NR_set_robust_list:
6032 goto unimplemented_nowarn;
6033 #endif
6035 #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
6036 case TARGET_NR_utimensat:
6038 struct timespec ts[2];
6039 target_to_host_timespec(ts, arg3);
6040 target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
6041 if (!arg2)
6042 ret = get_errno(sys_utimensat(arg1, NULL, ts, arg4));
6043 else {
6044 if (!(p = lock_user_string(arg2))) {
6045 ret = -TARGET_EFAULT;
6046 goto fail;
6048 ret = get_errno(sys_utimensat(arg1, path(p), ts, arg4));
6049 unlock_user(p, arg2, 0);
6052 break;
6053 #endif
6054 #if defined(USE_NPTL)
6055 case TARGET_NR_futex:
6056 ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
6057 break;
6058 #endif
6059 #ifdef TARGET_NR_inotify_init
6060 case TARGET_NR_inotify_init:
6061 ret = get_errno(sys_inotify_init());
6062 break;
6063 #endif
6064 #ifdef TARGET_NR_inotify_add_watch
6065 case TARGET_NR_inotify_add_watch:
6066 p = lock_user_string(arg2);
6067 ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
6068 unlock_user(p, arg2, 0);
6069 break;
6070 #endif
6071 #ifdef TARGET_NR_inotify_rm_watch
6072 case TARGET_NR_inotify_rm_watch:
6073 ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
6074 break;
6075 #endif
6077 default:
6078 unimplemented:
6079 gemu_log("qemu: Unsupported syscall: %d\n", num);
6080 #if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
6081 unimplemented_nowarn:
6082 #endif
6083 ret = -TARGET_ENOSYS;
6084 break;
6086 fail:
6087 #ifdef DEBUG
6088 gemu_log(" = %ld\n", ret);
6089 #endif
6090 if(do_strace)
6091 print_syscall_ret(num, ret);
6092 return ret;
6093 efault:
6094 ret = -TARGET_EFAULT;
6095 goto fail;