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