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