Fix a typo in fpsub32
[qemu/mini2440.git] / linux-user / syscall.c
blobeba2c02ad7d5d9924b37f48c0cf567ebb7fcbed6
1 /*
2 * Linux syscalls
4 * Copyright (c) 2003 Fabrice Bellard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <stdarg.h>
23 #include <string.h>
24 #include <elf.h>
25 #include <endian.h>
26 #include <errno.h>
27 #include <unistd.h>
28 #include <fcntl.h>
29 #include <time.h>
30 #include <limits.h>
31 #include <sys/types.h>
32 #include <sys/ipc.h>
33 #include <sys/msg.h>
34 #include <sys/wait.h>
35 #include <sys/time.h>
36 #include <sys/stat.h>
37 #include <sys/mount.h>
38 #include <sys/prctl.h>
39 #include <sys/resource.h>
40 #include <sys/mman.h>
41 #include <sys/swap.h>
42 #include <signal.h>
43 #include <sched.h>
44 #include <sys/socket.h>
45 #include <sys/uio.h>
46 #include <sys/poll.h>
47 #include <sys/times.h>
48 #include <sys/shm.h>
49 #include <sys/sem.h>
50 #include <sys/statfs.h>
51 #include <utime.h>
52 #include <sys/sysinfo.h>
53 //#include <sys/user.h>
54 #include <netinet/ip.h>
55 #include <netinet/tcp.h>
57 #define termios host_termios
58 #define winsize host_winsize
59 #define termio host_termio
60 #define sgttyb host_sgttyb /* same as target */
61 #define tchars host_tchars /* same as target */
62 #define ltchars host_ltchars /* same as target */
64 #include <linux/termios.h>
65 #include <linux/unistd.h>
66 #include <linux/utsname.h>
67 #include <linux/cdrom.h>
68 #include <linux/hdreg.h>
69 #include <linux/soundcard.h>
70 #include <linux/dirent.h>
71 #include <linux/kd.h>
72 #include "linux_loop.h"
74 #include "qemu.h"
75 #include "qemu-common.h"
77 #if defined(USE_NPTL)
78 #include <linux/futex.h>
79 #define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
80 CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
81 #else
82 /* XXX: Hardcode the above values. */
83 #define CLONE_NPTL_FLAGS2 0
84 #endif
86 //#define DEBUG
88 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \
89 || defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS)
90 /* 16 bit uid wrappers emulation */
91 #define USE_UID16
92 #endif
94 //#include <linux/msdos_fs.h>
95 #define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct dirent [2])
96 #define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct dirent [2])
99 #undef _syscall0
100 #undef _syscall1
101 #undef _syscall2
102 #undef _syscall3
103 #undef _syscall4
104 #undef _syscall5
105 #undef _syscall6
107 #define _syscall0(type,name) \
108 static type name (void) \
110 return syscall(__NR_##name); \
113 #define _syscall1(type,name,type1,arg1) \
114 static type name (type1 arg1) \
116 return syscall(__NR_##name, arg1); \
119 #define _syscall2(type,name,type1,arg1,type2,arg2) \
120 static type name (type1 arg1,type2 arg2) \
122 return syscall(__NR_##name, arg1, arg2); \
125 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
126 static type name (type1 arg1,type2 arg2,type3 arg3) \
128 return syscall(__NR_##name, arg1, arg2, arg3); \
131 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
132 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4) \
134 return syscall(__NR_##name, arg1, arg2, arg3, arg4); \
137 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
138 type5,arg5) \
139 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
141 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5); \
145 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
146 type5,arg5,type6,arg6) \
147 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \
148 type6 arg6) \
150 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6); \
154 #define __NR_sys_uname __NR_uname
155 #define __NR_sys_faccessat __NR_faccessat
156 #define __NR_sys_fchmodat __NR_fchmodat
157 #define __NR_sys_fchownat __NR_fchownat
158 #define __NR_sys_getcwd1 __NR_getcwd
159 #define __NR_sys_getdents __NR_getdents
160 #define __NR_sys_getdents64 __NR_getdents64
161 #define __NR_sys_getpriority __NR_getpriority
162 #define __NR_sys_linkat __NR_linkat
163 #define __NR_sys_mkdirat __NR_mkdirat
164 #define __NR_sys_mknodat __NR_mknodat
165 #define __NR_sys_openat __NR_openat
166 #define __NR_sys_readlinkat __NR_readlinkat
167 #define __NR_sys_renameat __NR_renameat
168 #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
169 #define __NR_sys_symlinkat __NR_symlinkat
170 #define __NR_sys_syslog __NR_syslog
171 #define __NR_sys_tgkill __NR_tgkill
172 #define __NR_sys_tkill __NR_tkill
173 #define __NR_sys_unlinkat __NR_unlinkat
174 #define __NR_sys_utimensat __NR_utimensat
175 #define __NR_sys_futex __NR_futex
177 #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
178 #define __NR__llseek __NR_lseek
179 #endif
181 #ifdef __NR_gettid
182 _syscall0(int, gettid)
183 #else
184 /* This is a replacement for the host gettid() and must return a host
185 errno. */
186 static int gettid(void) {
187 return -ENOSYS;
189 #endif
190 _syscall1(int,sys_uname,struct new_utsname *,buf)
191 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
192 _syscall4(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode,int,flags)
193 #endif
194 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
195 _syscall4(int,sys_fchmodat,int,dirfd,const char *,pathname,
196 mode_t,mode,int,flags)
197 #endif
198 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) && defined(USE_UID16)
199 _syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
200 uid_t,owner,gid_t,group,int,flags)
201 #endif
202 _syscall2(int,sys_getcwd1,char *,buf,size_t,size)
203 #if TARGET_ABI_BITS == 32
204 _syscall3(int, sys_getdents, uint, fd, struct dirent *, dirp, uint, count);
205 #endif
206 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
207 _syscall3(int, sys_getdents64, uint, fd, struct dirent64 *, dirp, uint, count);
208 #endif
209 _syscall2(int, sys_getpriority, int, which, int, who);
210 #if !defined (__x86_64__)
211 _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo,
212 loff_t *, res, uint, wh);
213 #endif
214 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
215 _syscall5(int,sys_linkat,int,olddirfd,const char *,oldpath,
216 int,newdirfd,const char *,newpath,int,flags)
217 #endif
218 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
219 _syscall3(int,sys_mkdirat,int,dirfd,const char *,pathname,mode_t,mode)
220 #endif
221 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
222 _syscall4(int,sys_mknodat,int,dirfd,const char *,pathname,
223 mode_t,mode,dev_t,dev)
224 #endif
225 #if defined(TARGET_NR_openat) && defined(__NR_openat)
226 _syscall4(int,sys_openat,int,dirfd,const char *,pathname,int,flags,mode_t,mode)
227 #endif
228 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
229 _syscall4(int,sys_readlinkat,int,dirfd,const char *,pathname,
230 char *,buf,size_t,bufsize)
231 #endif
232 #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
233 _syscall4(int,sys_renameat,int,olddirfd,const char *,oldpath,
234 int,newdirfd,const char *,newpath)
235 #endif
236 _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
237 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
238 _syscall3(int,sys_symlinkat,const char *,oldpath,
239 int,newdirfd,const char *,newpath)
240 #endif
241 _syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
242 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
243 _syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
244 #endif
245 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
246 _syscall2(int,sys_tkill,int,tid,int,sig)
247 #endif
248 #ifdef __NR_exit_group
249 _syscall1(int,exit_group,int,error_code)
250 #endif
251 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
252 _syscall1(int,set_tid_address,int *,tidptr)
253 #endif
254 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
255 _syscall3(int,sys_unlinkat,int,dirfd,const char *,pathname,int,flags)
256 #endif
257 #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
258 _syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
259 const struct timespec *,tsp,int,flags)
260 #endif
261 #if defined(USE_NPTL)
262 #if defined(TARGET_NR_futex) && defined(__NR_futex)
263 _syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
264 const struct timespec *,timeout,int *,uaddr2,int,val3)
265 #endif
266 #endif
268 extern int personality(int);
269 extern int flock(int, int);
270 extern int setfsuid(int);
271 extern int setfsgid(int);
272 extern int setgroups(int, gid_t *);
274 #define ERRNO_TABLE_SIZE 1200
276 /* target_to_host_errno_table[] is initialized from
277 * host_to_target_errno_table[] in syscall_init(). */
278 static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
282 * This list is the union of errno values overridden in asm-<arch>/errno.h
283 * minus the errnos that are not actually generic to all archs.
285 static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
286 [EIDRM] = TARGET_EIDRM,
287 [ECHRNG] = TARGET_ECHRNG,
288 [EL2NSYNC] = TARGET_EL2NSYNC,
289 [EL3HLT] = TARGET_EL3HLT,
290 [EL3RST] = TARGET_EL3RST,
291 [ELNRNG] = TARGET_ELNRNG,
292 [EUNATCH] = TARGET_EUNATCH,
293 [ENOCSI] = TARGET_ENOCSI,
294 [EL2HLT] = TARGET_EL2HLT,
295 [EDEADLK] = TARGET_EDEADLK,
296 [ENOLCK] = TARGET_ENOLCK,
297 [EBADE] = TARGET_EBADE,
298 [EBADR] = TARGET_EBADR,
299 [EXFULL] = TARGET_EXFULL,
300 [ENOANO] = TARGET_ENOANO,
301 [EBADRQC] = TARGET_EBADRQC,
302 [EBADSLT] = TARGET_EBADSLT,
303 [EBFONT] = TARGET_EBFONT,
304 [ENOSTR] = TARGET_ENOSTR,
305 [ENODATA] = TARGET_ENODATA,
306 [ETIME] = TARGET_ETIME,
307 [ENOSR] = TARGET_ENOSR,
308 [ENONET] = TARGET_ENONET,
309 [ENOPKG] = TARGET_ENOPKG,
310 [EREMOTE] = TARGET_EREMOTE,
311 [ENOLINK] = TARGET_ENOLINK,
312 [EADV] = TARGET_EADV,
313 [ESRMNT] = TARGET_ESRMNT,
314 [ECOMM] = TARGET_ECOMM,
315 [EPROTO] = TARGET_EPROTO,
316 [EDOTDOT] = TARGET_EDOTDOT,
317 [EMULTIHOP] = TARGET_EMULTIHOP,
318 [EBADMSG] = TARGET_EBADMSG,
319 [ENAMETOOLONG] = TARGET_ENAMETOOLONG,
320 [EOVERFLOW] = TARGET_EOVERFLOW,
321 [ENOTUNIQ] = TARGET_ENOTUNIQ,
322 [EBADFD] = TARGET_EBADFD,
323 [EREMCHG] = TARGET_EREMCHG,
324 [ELIBACC] = TARGET_ELIBACC,
325 [ELIBBAD] = TARGET_ELIBBAD,
326 [ELIBSCN] = TARGET_ELIBSCN,
327 [ELIBMAX] = TARGET_ELIBMAX,
328 [ELIBEXEC] = TARGET_ELIBEXEC,
329 [EILSEQ] = TARGET_EILSEQ,
330 [ENOSYS] = TARGET_ENOSYS,
331 [ELOOP] = TARGET_ELOOP,
332 [ERESTART] = TARGET_ERESTART,
333 [ESTRPIPE] = TARGET_ESTRPIPE,
334 [ENOTEMPTY] = TARGET_ENOTEMPTY,
335 [EUSERS] = TARGET_EUSERS,
336 [ENOTSOCK] = TARGET_ENOTSOCK,
337 [EDESTADDRREQ] = TARGET_EDESTADDRREQ,
338 [EMSGSIZE] = TARGET_EMSGSIZE,
339 [EPROTOTYPE] = TARGET_EPROTOTYPE,
340 [ENOPROTOOPT] = TARGET_ENOPROTOOPT,
341 [EPROTONOSUPPORT] = TARGET_EPROTONOSUPPORT,
342 [ESOCKTNOSUPPORT] = TARGET_ESOCKTNOSUPPORT,
343 [EOPNOTSUPP] = TARGET_EOPNOTSUPP,
344 [EPFNOSUPPORT] = TARGET_EPFNOSUPPORT,
345 [EAFNOSUPPORT] = TARGET_EAFNOSUPPORT,
346 [EADDRINUSE] = TARGET_EADDRINUSE,
347 [EADDRNOTAVAIL] = TARGET_EADDRNOTAVAIL,
348 [ENETDOWN] = TARGET_ENETDOWN,
349 [ENETUNREACH] = TARGET_ENETUNREACH,
350 [ENETRESET] = TARGET_ENETRESET,
351 [ECONNABORTED] = TARGET_ECONNABORTED,
352 [ECONNRESET] = TARGET_ECONNRESET,
353 [ENOBUFS] = TARGET_ENOBUFS,
354 [EISCONN] = TARGET_EISCONN,
355 [ENOTCONN] = TARGET_ENOTCONN,
356 [EUCLEAN] = TARGET_EUCLEAN,
357 [ENOTNAM] = TARGET_ENOTNAM,
358 [ENAVAIL] = TARGET_ENAVAIL,
359 [EISNAM] = TARGET_EISNAM,
360 [EREMOTEIO] = TARGET_EREMOTEIO,
361 [ESHUTDOWN] = TARGET_ESHUTDOWN,
362 [ETOOMANYREFS] = TARGET_ETOOMANYREFS,
363 [ETIMEDOUT] = TARGET_ETIMEDOUT,
364 [ECONNREFUSED] = TARGET_ECONNREFUSED,
365 [EHOSTDOWN] = TARGET_EHOSTDOWN,
366 [EHOSTUNREACH] = TARGET_EHOSTUNREACH,
367 [EALREADY] = TARGET_EALREADY,
368 [EINPROGRESS] = TARGET_EINPROGRESS,
369 [ESTALE] = TARGET_ESTALE,
370 [ECANCELED] = TARGET_ECANCELED,
371 [ENOMEDIUM] = TARGET_ENOMEDIUM,
372 [EMEDIUMTYPE] = TARGET_EMEDIUMTYPE,
373 #ifdef ENOKEY
374 [ENOKEY] = TARGET_ENOKEY,
375 #endif
376 #ifdef EKEYEXPIRED
377 [EKEYEXPIRED] = TARGET_EKEYEXPIRED,
378 #endif
379 #ifdef EKEYREVOKED
380 [EKEYREVOKED] = TARGET_EKEYREVOKED,
381 #endif
382 #ifdef EKEYREJECTED
383 [EKEYREJECTED] = TARGET_EKEYREJECTED,
384 #endif
385 #ifdef EOWNERDEAD
386 [EOWNERDEAD] = TARGET_EOWNERDEAD,
387 #endif
388 #ifdef ENOTRECOVERABLE
389 [ENOTRECOVERABLE] = TARGET_ENOTRECOVERABLE,
390 #endif
393 static inline int host_to_target_errno(int err)
395 if(host_to_target_errno_table[err])
396 return host_to_target_errno_table[err];
397 return err;
400 static inline int target_to_host_errno(int err)
402 if (target_to_host_errno_table[err])
403 return target_to_host_errno_table[err];
404 return err;
407 static inline abi_long get_errno(abi_long ret)
409 if (ret == -1)
410 return -host_to_target_errno(errno);
411 else
412 return ret;
415 static inline int is_error(abi_long ret)
417 return (abi_ulong)ret >= (abi_ulong)(-4096);
420 char *target_strerror(int err)
422 return strerror(target_to_host_errno(err));
425 static abi_ulong target_brk;
426 static abi_ulong target_original_brk;
428 void target_set_brk(abi_ulong new_brk)
430 target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
433 /* do_brk() must return target values and target errnos. */
434 abi_long do_brk(abi_ulong new_brk)
436 abi_ulong brk_page;
437 abi_long mapped_addr;
438 int new_alloc_size;
440 if (!new_brk)
441 return target_brk;
442 if (new_brk < target_original_brk)
443 return target_brk;
445 brk_page = HOST_PAGE_ALIGN(target_brk);
447 /* If the new brk is less than this, set it and we're done... */
448 if (new_brk < brk_page) {
449 target_brk = new_brk;
450 return target_brk;
453 /* We need to allocate more memory after the brk... */
454 new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
455 mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
456 PROT_READ|PROT_WRITE,
457 MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
459 if (!is_error(mapped_addr))
460 target_brk = new_brk;
462 return target_brk;
465 static inline abi_long copy_from_user_fdset(fd_set *fds,
466 abi_ulong target_fds_addr,
467 int n)
469 int i, nw, j, k;
470 abi_ulong b, *target_fds;
472 nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
473 if (!(target_fds = lock_user(VERIFY_READ,
474 target_fds_addr,
475 sizeof(abi_ulong) * nw,
476 1)))
477 return -TARGET_EFAULT;
479 FD_ZERO(fds);
480 k = 0;
481 for (i = 0; i < nw; i++) {
482 /* grab the abi_ulong */
483 __get_user(b, &target_fds[i]);
484 for (j = 0; j < TARGET_ABI_BITS; j++) {
485 /* check the bit inside the abi_ulong */
486 if ((b >> j) & 1)
487 FD_SET(k, fds);
488 k++;
492 unlock_user(target_fds, target_fds_addr, 0);
494 return 0;
497 static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
498 const fd_set *fds,
499 int n)
501 int i, nw, j, k;
502 abi_long v;
503 abi_ulong *target_fds;
505 nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
506 if (!(target_fds = lock_user(VERIFY_WRITE,
507 target_fds_addr,
508 sizeof(abi_ulong) * nw,
509 0)))
510 return -TARGET_EFAULT;
512 k = 0;
513 for (i = 0; i < nw; i++) {
514 v = 0;
515 for (j = 0; j < TARGET_ABI_BITS; j++) {
516 v |= ((FD_ISSET(k, fds) != 0) << j);
517 k++;
519 __put_user(v, &target_fds[i]);
522 unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
524 return 0;
527 #if defined(__alpha__)
528 #define HOST_HZ 1024
529 #else
530 #define HOST_HZ 100
531 #endif
533 static inline abi_long host_to_target_clock_t(long ticks)
535 #if HOST_HZ == TARGET_HZ
536 return ticks;
537 #else
538 return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
539 #endif
542 static inline abi_long host_to_target_rusage(abi_ulong target_addr,
543 const struct rusage *rusage)
545 struct target_rusage *target_rusage;
547 if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
548 return -TARGET_EFAULT;
549 target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
550 target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
551 target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
552 target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec);
553 target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss);
554 target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss);
555 target_rusage->ru_idrss = tswapl(rusage->ru_idrss);
556 target_rusage->ru_isrss = tswapl(rusage->ru_isrss);
557 target_rusage->ru_minflt = tswapl(rusage->ru_minflt);
558 target_rusage->ru_majflt = tswapl(rusage->ru_majflt);
559 target_rusage->ru_nswap = tswapl(rusage->ru_nswap);
560 target_rusage->ru_inblock = tswapl(rusage->ru_inblock);
561 target_rusage->ru_oublock = tswapl(rusage->ru_oublock);
562 target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd);
563 target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv);
564 target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);
565 target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
566 target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
567 unlock_user_struct(target_rusage, target_addr, 1);
569 return 0;
572 static inline abi_long copy_from_user_timeval(struct timeval *tv,
573 abi_ulong target_tv_addr)
575 struct target_timeval *target_tv;
577 if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
578 return -TARGET_EFAULT;
580 __get_user(tv->tv_sec, &target_tv->tv_sec);
581 __get_user(tv->tv_usec, &target_tv->tv_usec);
583 unlock_user_struct(target_tv, target_tv_addr, 0);
585 return 0;
588 static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
589 const struct timeval *tv)
591 struct target_timeval *target_tv;
593 if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
594 return -TARGET_EFAULT;
596 __put_user(tv->tv_sec, &target_tv->tv_sec);
597 __put_user(tv->tv_usec, &target_tv->tv_usec);
599 unlock_user_struct(target_tv, target_tv_addr, 1);
601 return 0;
605 /* do_select() must return target values and target errnos. */
606 static abi_long do_select(int n,
607 abi_ulong rfd_addr, abi_ulong wfd_addr,
608 abi_ulong efd_addr, abi_ulong target_tv_addr)
610 fd_set rfds, wfds, efds;
611 fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
612 struct timeval tv, *tv_ptr;
613 abi_long ret;
615 if (rfd_addr) {
616 if (copy_from_user_fdset(&rfds, rfd_addr, n))
617 return -TARGET_EFAULT;
618 rfds_ptr = &rfds;
619 } else {
620 rfds_ptr = NULL;
622 if (wfd_addr) {
623 if (copy_from_user_fdset(&wfds, wfd_addr, n))
624 return -TARGET_EFAULT;
625 wfds_ptr = &wfds;
626 } else {
627 wfds_ptr = NULL;
629 if (efd_addr) {
630 if (copy_from_user_fdset(&efds, efd_addr, n))
631 return -TARGET_EFAULT;
632 efds_ptr = &efds;
633 } else {
634 efds_ptr = NULL;
637 if (target_tv_addr) {
638 if (copy_from_user_timeval(&tv, target_tv_addr))
639 return -TARGET_EFAULT;
640 tv_ptr = &tv;
641 } else {
642 tv_ptr = NULL;
645 ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
647 if (!is_error(ret)) {
648 if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
649 return -TARGET_EFAULT;
650 if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
651 return -TARGET_EFAULT;
652 if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
653 return -TARGET_EFAULT;
655 if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
656 return -TARGET_EFAULT;
659 return ret;
662 static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
663 abi_ulong target_addr,
664 socklen_t len)
666 struct target_sockaddr *target_saddr;
668 target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
669 if (!target_saddr)
670 return -TARGET_EFAULT;
671 memcpy(addr, target_saddr, len);
672 addr->sa_family = tswap16(target_saddr->sa_family);
673 unlock_user(target_saddr, target_addr, 0);
675 return 0;
678 static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
679 struct sockaddr *addr,
680 socklen_t len)
682 struct target_sockaddr *target_saddr;
684 target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
685 if (!target_saddr)
686 return -TARGET_EFAULT;
687 memcpy(target_saddr, addr, len);
688 target_saddr->sa_family = tswap16(addr->sa_family);
689 unlock_user(target_saddr, target_addr, len);
691 return 0;
694 /* ??? Should this also swap msgh->name? */
695 static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
696 struct target_msghdr *target_msgh)
698 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
699 abi_long msg_controllen;
700 abi_ulong target_cmsg_addr;
701 struct target_cmsghdr *target_cmsg;
702 socklen_t space = 0;
704 msg_controllen = tswapl(target_msgh->msg_controllen);
705 if (msg_controllen < sizeof (struct target_cmsghdr))
706 goto the_end;
707 target_cmsg_addr = tswapl(target_msgh->msg_control);
708 target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
709 if (!target_cmsg)
710 return -TARGET_EFAULT;
712 while (cmsg && target_cmsg) {
713 void *data = CMSG_DATA(cmsg);
714 void *target_data = TARGET_CMSG_DATA(target_cmsg);
716 int len = tswapl(target_cmsg->cmsg_len)
717 - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
719 space += CMSG_SPACE(len);
720 if (space > msgh->msg_controllen) {
721 space -= CMSG_SPACE(len);
722 gemu_log("Host cmsg overflow\n");
723 break;
726 cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
727 cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
728 cmsg->cmsg_len = CMSG_LEN(len);
730 if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
731 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
732 memcpy(data, target_data, len);
733 } else {
734 int *fd = (int *)data;
735 int *target_fd = (int *)target_data;
736 int i, numfds = len / sizeof(int);
738 for (i = 0; i < numfds; i++)
739 fd[i] = tswap32(target_fd[i]);
742 cmsg = CMSG_NXTHDR(msgh, cmsg);
743 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
745 unlock_user(target_cmsg, target_cmsg_addr, 0);
746 the_end:
747 msgh->msg_controllen = space;
748 return 0;
751 /* ??? Should this also swap msgh->name? */
752 static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
753 struct msghdr *msgh)
755 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
756 abi_long msg_controllen;
757 abi_ulong target_cmsg_addr;
758 struct target_cmsghdr *target_cmsg;
759 socklen_t space = 0;
761 msg_controllen = tswapl(target_msgh->msg_controllen);
762 if (msg_controllen < sizeof (struct target_cmsghdr))
763 goto the_end;
764 target_cmsg_addr = tswapl(target_msgh->msg_control);
765 target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
766 if (!target_cmsg)
767 return -TARGET_EFAULT;
769 while (cmsg && target_cmsg) {
770 void *data = CMSG_DATA(cmsg);
771 void *target_data = TARGET_CMSG_DATA(target_cmsg);
773 int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
775 space += TARGET_CMSG_SPACE(len);
776 if (space > msg_controllen) {
777 space -= TARGET_CMSG_SPACE(len);
778 gemu_log("Target cmsg overflow\n");
779 break;
782 target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
783 target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
784 target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
786 if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
787 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
788 memcpy(target_data, data, len);
789 } else {
790 int *fd = (int *)data;
791 int *target_fd = (int *)target_data;
792 int i, numfds = len / sizeof(int);
794 for (i = 0; i < numfds; i++)
795 target_fd[i] = tswap32(fd[i]);
798 cmsg = CMSG_NXTHDR(msgh, cmsg);
799 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
801 unlock_user(target_cmsg, target_cmsg_addr, space);
802 the_end:
803 target_msgh->msg_controllen = tswapl(space);
804 return 0;
807 /* do_setsockopt() Must return target values and target errnos. */
808 static abi_long do_setsockopt(int sockfd, int level, int optname,
809 abi_ulong optval_addr, socklen_t optlen)
811 abi_long ret;
812 int val;
814 switch(level) {
815 case SOL_TCP:
816 /* TCP options all take an 'int' value. */
817 if (optlen < sizeof(uint32_t))
818 return -TARGET_EINVAL;
820 if (get_user_u32(val, optval_addr))
821 return -TARGET_EFAULT;
822 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
823 break;
824 case SOL_IP:
825 switch(optname) {
826 case IP_TOS:
827 case IP_TTL:
828 case IP_HDRINCL:
829 case IP_ROUTER_ALERT:
830 case IP_RECVOPTS:
831 case IP_RETOPTS:
832 case IP_PKTINFO:
833 case IP_MTU_DISCOVER:
834 case IP_RECVERR:
835 case IP_RECVTOS:
836 #ifdef IP_FREEBIND
837 case IP_FREEBIND:
838 #endif
839 case IP_MULTICAST_TTL:
840 case IP_MULTICAST_LOOP:
841 val = 0;
842 if (optlen >= sizeof(uint32_t)) {
843 if (get_user_u32(val, optval_addr))
844 return -TARGET_EFAULT;
845 } else if (optlen >= 1) {
846 if (get_user_u8(val, optval_addr))
847 return -TARGET_EFAULT;
849 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
850 break;
851 default:
852 goto unimplemented;
854 break;
855 case TARGET_SOL_SOCKET:
856 switch (optname) {
857 /* Options with 'int' argument. */
858 case TARGET_SO_DEBUG:
859 optname = SO_DEBUG;
860 break;
861 case TARGET_SO_REUSEADDR:
862 optname = SO_REUSEADDR;
863 break;
864 case TARGET_SO_TYPE:
865 optname = SO_TYPE;
866 break;
867 case TARGET_SO_ERROR:
868 optname = SO_ERROR;
869 break;
870 case TARGET_SO_DONTROUTE:
871 optname = SO_DONTROUTE;
872 break;
873 case TARGET_SO_BROADCAST:
874 optname = SO_BROADCAST;
875 break;
876 case TARGET_SO_SNDBUF:
877 optname = SO_SNDBUF;
878 break;
879 case TARGET_SO_RCVBUF:
880 optname = SO_RCVBUF;
881 break;
882 case TARGET_SO_KEEPALIVE:
883 optname = SO_KEEPALIVE;
884 break;
885 case TARGET_SO_OOBINLINE:
886 optname = SO_OOBINLINE;
887 break;
888 case TARGET_SO_NO_CHECK:
889 optname = SO_NO_CHECK;
890 break;
891 case TARGET_SO_PRIORITY:
892 optname = SO_PRIORITY;
893 break;
894 #ifdef SO_BSDCOMPAT
895 case TARGET_SO_BSDCOMPAT:
896 optname = SO_BSDCOMPAT;
897 break;
898 #endif
899 case TARGET_SO_PASSCRED:
900 optname = SO_PASSCRED;
901 break;
902 case TARGET_SO_TIMESTAMP:
903 optname = SO_TIMESTAMP;
904 break;
905 case TARGET_SO_RCVLOWAT:
906 optname = SO_RCVLOWAT;
907 break;
908 case TARGET_SO_RCVTIMEO:
909 optname = SO_RCVTIMEO;
910 break;
911 case TARGET_SO_SNDTIMEO:
912 optname = SO_SNDTIMEO;
913 break;
914 break;
915 default:
916 goto unimplemented;
918 if (optlen < sizeof(uint32_t))
919 return -TARGET_EINVAL;
921 if (get_user_u32(val, optval_addr))
922 return -TARGET_EFAULT;
923 ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
924 break;
925 default:
926 unimplemented:
927 gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
928 ret = -TARGET_ENOPROTOOPT;
930 return ret;
933 /* do_getsockopt() Must return target values and target errnos. */
934 static abi_long do_getsockopt(int sockfd, int level, int optname,
935 abi_ulong optval_addr, abi_ulong optlen)
937 abi_long ret;
938 int len, lv, val;
940 switch(level) {
941 case TARGET_SOL_SOCKET:
942 level = SOL_SOCKET;
943 switch (optname) {
944 case TARGET_SO_LINGER:
945 case TARGET_SO_RCVTIMEO:
946 case TARGET_SO_SNDTIMEO:
947 case TARGET_SO_PEERCRED:
948 case TARGET_SO_PEERNAME:
949 /* These don't just return a single integer */
950 goto unimplemented;
951 default:
952 goto int_case;
954 break;
955 case SOL_TCP:
956 /* TCP options all take an 'int' value. */
957 int_case:
958 if (get_user_u32(len, optlen))
959 return -TARGET_EFAULT;
960 if (len < 0)
961 return -TARGET_EINVAL;
962 lv = sizeof(int);
963 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
964 if (ret < 0)
965 return ret;
966 val = tswap32(val);
967 if (len > lv)
968 len = lv;
969 if (len == 4) {
970 if (put_user_u32(val, optval_addr))
971 return -TARGET_EFAULT;
972 } else {
973 if (put_user_u8(val, optval_addr))
974 return -TARGET_EFAULT;
976 if (put_user_u32(len, optlen))
977 return -TARGET_EFAULT;
978 break;
979 case SOL_IP:
980 switch(optname) {
981 case IP_TOS:
982 case IP_TTL:
983 case IP_HDRINCL:
984 case IP_ROUTER_ALERT:
985 case IP_RECVOPTS:
986 case IP_RETOPTS:
987 case IP_PKTINFO:
988 case IP_MTU_DISCOVER:
989 case IP_RECVERR:
990 case IP_RECVTOS:
991 #ifdef IP_FREEBIND
992 case IP_FREEBIND:
993 #endif
994 case IP_MULTICAST_TTL:
995 case IP_MULTICAST_LOOP:
996 if (get_user_u32(len, optlen))
997 return -TARGET_EFAULT;
998 if (len < 0)
999 return -TARGET_EINVAL;
1000 lv = sizeof(int);
1001 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1002 if (ret < 0)
1003 return ret;
1004 if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
1005 len = 1;
1006 if (put_user_u32(len, optlen)
1007 || put_user_u8(val, optval_addr))
1008 return -TARGET_EFAULT;
1009 } else {
1010 if (len > sizeof(int))
1011 len = sizeof(int);
1012 if (put_user_u32(len, optlen)
1013 || put_user_u32(val, optval_addr))
1014 return -TARGET_EFAULT;
1016 break;
1017 default:
1018 ret = -TARGET_ENOPROTOOPT;
1019 break;
1021 break;
1022 default:
1023 unimplemented:
1024 gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1025 level, optname);
1026 ret = -TARGET_EOPNOTSUPP;
1027 break;
1029 return ret;
1032 /* FIXME
1033 * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1034 * other lock functions have a return code of 0 for failure.
1036 static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1037 int count, int copy)
1039 struct target_iovec *target_vec;
1040 abi_ulong base;
1041 int i, j;
1043 target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1044 if (!target_vec)
1045 return -TARGET_EFAULT;
1046 for(i = 0;i < count; i++) {
1047 base = tswapl(target_vec[i].iov_base);
1048 vec[i].iov_len = tswapl(target_vec[i].iov_len);
1049 if (vec[i].iov_len != 0) {
1050 vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
1051 if (!vec[i].iov_base && vec[i].iov_len)
1052 goto fail;
1053 } else {
1054 /* zero length pointer is ignored */
1055 vec[i].iov_base = NULL;
1058 unlock_user (target_vec, target_addr, 0);
1059 return 0;
1060 fail:
1061 /* failure - unwind locks */
1062 for (j = 0; j < i; j++) {
1063 base = tswapl(target_vec[j].iov_base);
1064 unlock_user(vec[j].iov_base, base, 0);
1066 unlock_user (target_vec, target_addr, 0);
1067 return -TARGET_EFAULT;
1070 static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1071 int count, int copy)
1073 struct target_iovec *target_vec;
1074 abi_ulong base;
1075 int i;
1077 target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1078 if (!target_vec)
1079 return -TARGET_EFAULT;
1080 for(i = 0;i < count; i++) {
1081 base = tswapl(target_vec[i].iov_base);
1082 unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1084 unlock_user (target_vec, target_addr, 0);
1086 return 0;
1089 /* do_socket() Must return target values and target errnos. */
1090 static abi_long do_socket(int domain, int type, int protocol)
1092 #if defined(TARGET_MIPS)
1093 switch(type) {
1094 case TARGET_SOCK_DGRAM:
1095 type = SOCK_DGRAM;
1096 break;
1097 case TARGET_SOCK_STREAM:
1098 type = SOCK_STREAM;
1099 break;
1100 case TARGET_SOCK_RAW:
1101 type = SOCK_RAW;
1102 break;
1103 case TARGET_SOCK_RDM:
1104 type = SOCK_RDM;
1105 break;
1106 case TARGET_SOCK_SEQPACKET:
1107 type = SOCK_SEQPACKET;
1108 break;
1109 case TARGET_SOCK_PACKET:
1110 type = SOCK_PACKET;
1111 break;
1113 #endif
1114 if (domain == PF_NETLINK)
1115 return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1116 return get_errno(socket(domain, type, protocol));
1119 /* do_bind() Must return target values and target errnos. */
1120 static abi_long do_bind(int sockfd, abi_ulong target_addr,
1121 socklen_t addrlen)
1123 void *addr = alloca(addrlen);
1125 target_to_host_sockaddr(addr, target_addr, addrlen);
1126 return get_errno(bind(sockfd, addr, addrlen));
1129 /* do_connect() Must return target values and target errnos. */
1130 static abi_long do_connect(int sockfd, abi_ulong target_addr,
1131 socklen_t addrlen)
1133 void *addr = alloca(addrlen);
1135 target_to_host_sockaddr(addr, target_addr, addrlen);
1136 return get_errno(connect(sockfd, addr, addrlen));
1139 /* do_sendrecvmsg() Must return target values and target errnos. */
1140 static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1141 int flags, int send)
1143 abi_long ret;
1144 struct target_msghdr *msgp;
1145 struct msghdr msg;
1146 int count;
1147 struct iovec *vec;
1148 abi_ulong target_vec;
1150 /* FIXME */
1151 if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1152 msgp,
1153 target_msg,
1154 send ? 1 : 0))
1155 return -TARGET_EFAULT;
1156 if (msgp->msg_name) {
1157 msg.msg_namelen = tswap32(msgp->msg_namelen);
1158 msg.msg_name = alloca(msg.msg_namelen);
1159 target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
1160 msg.msg_namelen);
1161 } else {
1162 msg.msg_name = NULL;
1163 msg.msg_namelen = 0;
1165 msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
1166 msg.msg_control = alloca(msg.msg_controllen);
1167 msg.msg_flags = tswap32(msgp->msg_flags);
1169 count = tswapl(msgp->msg_iovlen);
1170 vec = alloca(count * sizeof(struct iovec));
1171 target_vec = tswapl(msgp->msg_iov);
1172 lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1173 msg.msg_iovlen = count;
1174 msg.msg_iov = vec;
1176 if (send) {
1177 ret = target_to_host_cmsg(&msg, msgp);
1178 if (ret == 0)
1179 ret = get_errno(sendmsg(fd, &msg, flags));
1180 } else {
1181 ret = get_errno(recvmsg(fd, &msg, flags));
1182 if (!is_error(ret))
1183 ret = host_to_target_cmsg(msgp, &msg);
1185 unlock_iovec(vec, target_vec, count, !send);
1186 unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1187 return ret;
1190 /* do_accept() Must return target values and target errnos. */
1191 static abi_long do_accept(int fd, abi_ulong target_addr,
1192 abi_ulong target_addrlen_addr)
1194 socklen_t addrlen;
1195 void *addr;
1196 abi_long ret;
1198 if (get_user_u32(addrlen, target_addrlen_addr))
1199 return -TARGET_EFAULT;
1201 addr = alloca(addrlen);
1203 ret = get_errno(accept(fd, addr, &addrlen));
1204 if (!is_error(ret)) {
1205 host_to_target_sockaddr(target_addr, addr, addrlen);
1206 if (put_user_u32(addrlen, target_addrlen_addr))
1207 ret = -TARGET_EFAULT;
1209 return ret;
1212 /* do_getpeername() Must return target values and target errnos. */
1213 static abi_long do_getpeername(int fd, abi_ulong target_addr,
1214 abi_ulong target_addrlen_addr)
1216 socklen_t addrlen;
1217 void *addr;
1218 abi_long ret;
1220 if (get_user_u32(addrlen, target_addrlen_addr))
1221 return -TARGET_EFAULT;
1223 addr = alloca(addrlen);
1225 ret = get_errno(getpeername(fd, addr, &addrlen));
1226 if (!is_error(ret)) {
1227 host_to_target_sockaddr(target_addr, addr, addrlen);
1228 if (put_user_u32(addrlen, target_addrlen_addr))
1229 ret = -TARGET_EFAULT;
1231 return ret;
1234 /* do_getsockname() Must return target values and target errnos. */
1235 static abi_long do_getsockname(int fd, abi_ulong target_addr,
1236 abi_ulong target_addrlen_addr)
1238 socklen_t addrlen;
1239 void *addr;
1240 abi_long ret;
1242 if (get_user_u32(addrlen, target_addrlen_addr))
1243 return -TARGET_EFAULT;
1245 addr = alloca(addrlen);
1247 ret = get_errno(getsockname(fd, addr, &addrlen));
1248 if (!is_error(ret)) {
1249 host_to_target_sockaddr(target_addr, addr, addrlen);
1250 if (put_user_u32(addrlen, target_addrlen_addr))
1251 ret = -TARGET_EFAULT;
1253 return ret;
1256 /* do_socketpair() Must return target values and target errnos. */
1257 static abi_long do_socketpair(int domain, int type, int protocol,
1258 abi_ulong target_tab_addr)
1260 int tab[2];
1261 abi_long ret;
1263 ret = get_errno(socketpair(domain, type, protocol, tab));
1264 if (!is_error(ret)) {
1265 if (put_user_s32(tab[0], target_tab_addr)
1266 || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1267 ret = -TARGET_EFAULT;
1269 return ret;
1272 /* do_sendto() Must return target values and target errnos. */
1273 static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
1274 abi_ulong target_addr, socklen_t addrlen)
1276 void *addr;
1277 void *host_msg;
1278 abi_long ret;
1280 host_msg = lock_user(VERIFY_READ, msg, len, 1);
1281 if (!host_msg)
1282 return -TARGET_EFAULT;
1283 if (target_addr) {
1284 addr = alloca(addrlen);
1285 target_to_host_sockaddr(addr, target_addr, addrlen);
1286 ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
1287 } else {
1288 ret = get_errno(send(fd, host_msg, len, flags));
1290 unlock_user(host_msg, msg, 0);
1291 return ret;
1294 /* do_recvfrom() Must return target values and target errnos. */
1295 static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
1296 abi_ulong target_addr,
1297 abi_ulong target_addrlen)
1299 socklen_t addrlen;
1300 void *addr;
1301 void *host_msg;
1302 abi_long ret;
1304 host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
1305 if (!host_msg)
1306 return -TARGET_EFAULT;
1307 if (target_addr) {
1308 if (get_user_u32(addrlen, target_addrlen)) {
1309 ret = -TARGET_EFAULT;
1310 goto fail;
1312 addr = alloca(addrlen);
1313 ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
1314 } else {
1315 addr = NULL; /* To keep compiler quiet. */
1316 ret = get_errno(recv(fd, host_msg, len, flags));
1318 if (!is_error(ret)) {
1319 if (target_addr) {
1320 host_to_target_sockaddr(target_addr, addr, addrlen);
1321 if (put_user_u32(addrlen, target_addrlen)) {
1322 ret = -TARGET_EFAULT;
1323 goto fail;
1326 unlock_user(host_msg, msg, len);
1327 } else {
1328 fail:
1329 unlock_user(host_msg, msg, 0);
1331 return ret;
1334 #ifdef TARGET_NR_socketcall
1335 /* do_socketcall() Must return target values and target errnos. */
1336 static abi_long do_socketcall(int num, abi_ulong vptr)
1338 abi_long ret;
1339 const int n = sizeof(abi_ulong);
1341 switch(num) {
1342 case SOCKOP_socket:
1344 int domain, type, protocol;
1346 if (get_user_s32(domain, vptr)
1347 || get_user_s32(type, vptr + n)
1348 || get_user_s32(protocol, vptr + 2 * n))
1349 return -TARGET_EFAULT;
1351 ret = do_socket(domain, type, protocol);
1353 break;
1354 case SOCKOP_bind:
1356 int sockfd;
1357 abi_ulong target_addr;
1358 socklen_t addrlen;
1360 if (get_user_s32(sockfd, vptr)
1361 || get_user_ual(target_addr, vptr + n)
1362 || get_user_u32(addrlen, vptr + 2 * n))
1363 return -TARGET_EFAULT;
1365 ret = do_bind(sockfd, target_addr, addrlen);
1367 break;
1368 case SOCKOP_connect:
1370 int sockfd;
1371 abi_ulong target_addr;
1372 socklen_t addrlen;
1374 if (get_user_s32(sockfd, vptr)
1375 || get_user_ual(target_addr, vptr + n)
1376 || get_user_u32(addrlen, vptr + 2 * n))
1377 return -TARGET_EFAULT;
1379 ret = do_connect(sockfd, target_addr, addrlen);
1381 break;
1382 case SOCKOP_listen:
1384 int sockfd, backlog;
1386 if (get_user_s32(sockfd, vptr)
1387 || get_user_s32(backlog, vptr + n))
1388 return -TARGET_EFAULT;
1390 ret = get_errno(listen(sockfd, backlog));
1392 break;
1393 case SOCKOP_accept:
1395 int sockfd;
1396 abi_ulong target_addr, target_addrlen;
1398 if (get_user_s32(sockfd, vptr)
1399 || get_user_ual(target_addr, vptr + n)
1400 || get_user_u32(target_addrlen, vptr + 2 * n))
1401 return -TARGET_EFAULT;
1403 ret = do_accept(sockfd, target_addr, target_addrlen);
1405 break;
1406 case SOCKOP_getsockname:
1408 int sockfd;
1409 abi_ulong target_addr, target_addrlen;
1411 if (get_user_s32(sockfd, vptr)
1412 || get_user_ual(target_addr, vptr + n)
1413 || get_user_u32(target_addrlen, vptr + 2 * n))
1414 return -TARGET_EFAULT;
1416 ret = do_getsockname(sockfd, target_addr, target_addrlen);
1418 break;
1419 case SOCKOP_getpeername:
1421 int sockfd;
1422 abi_ulong target_addr, target_addrlen;
1424 if (get_user_s32(sockfd, vptr)
1425 || get_user_ual(target_addr, vptr + n)
1426 || get_user_u32(target_addrlen, vptr + 2 * n))
1427 return -TARGET_EFAULT;
1429 ret = do_getpeername(sockfd, target_addr, target_addrlen);
1431 break;
1432 case SOCKOP_socketpair:
1434 int domain, type, protocol;
1435 abi_ulong tab;
1437 if (get_user_s32(domain, vptr)
1438 || get_user_s32(type, vptr + n)
1439 || get_user_s32(protocol, vptr + 2 * n)
1440 || get_user_ual(tab, vptr + 3 * n))
1441 return -TARGET_EFAULT;
1443 ret = do_socketpair(domain, type, protocol, tab);
1445 break;
1446 case SOCKOP_send:
1448 int sockfd;
1449 abi_ulong msg;
1450 size_t len;
1451 int flags;
1453 if (get_user_s32(sockfd, vptr)
1454 || get_user_ual(msg, vptr + n)
1455 || get_user_ual(len, vptr + 2 * n)
1456 || get_user_s32(flags, vptr + 3 * n))
1457 return -TARGET_EFAULT;
1459 ret = do_sendto(sockfd, msg, len, flags, 0, 0);
1461 break;
1462 case SOCKOP_recv:
1464 int sockfd;
1465 abi_ulong msg;
1466 size_t len;
1467 int flags;
1469 if (get_user_s32(sockfd, vptr)
1470 || get_user_ual(msg, vptr + n)
1471 || get_user_ual(len, vptr + 2 * n)
1472 || get_user_s32(flags, vptr + 3 * n))
1473 return -TARGET_EFAULT;
1475 ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
1477 break;
1478 case SOCKOP_sendto:
1480 int sockfd;
1481 abi_ulong msg;
1482 size_t len;
1483 int flags;
1484 abi_ulong addr;
1485 socklen_t addrlen;
1487 if (get_user_s32(sockfd, vptr)
1488 || get_user_ual(msg, vptr + n)
1489 || get_user_ual(len, vptr + 2 * n)
1490 || get_user_s32(flags, vptr + 3 * n)
1491 || get_user_ual(addr, vptr + 4 * n)
1492 || get_user_u32(addrlen, vptr + 5 * n))
1493 return -TARGET_EFAULT;
1495 ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
1497 break;
1498 case SOCKOP_recvfrom:
1500 int sockfd;
1501 abi_ulong msg;
1502 size_t len;
1503 int flags;
1504 abi_ulong addr;
1505 socklen_t addrlen;
1507 if (get_user_s32(sockfd, vptr)
1508 || get_user_ual(msg, vptr + n)
1509 || get_user_ual(len, vptr + 2 * n)
1510 || get_user_s32(flags, vptr + 3 * n)
1511 || get_user_ual(addr, vptr + 4 * n)
1512 || get_user_u32(addrlen, vptr + 5 * n))
1513 return -TARGET_EFAULT;
1515 ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
1517 break;
1518 case SOCKOP_shutdown:
1520 int sockfd, how;
1522 if (get_user_s32(sockfd, vptr)
1523 || get_user_s32(how, vptr + n))
1524 return -TARGET_EFAULT;
1526 ret = get_errno(shutdown(sockfd, how));
1528 break;
1529 case SOCKOP_sendmsg:
1530 case SOCKOP_recvmsg:
1532 int fd;
1533 abi_ulong target_msg;
1534 int flags;
1536 if (get_user_s32(fd, vptr)
1537 || get_user_ual(target_msg, vptr + n)
1538 || get_user_s32(flags, vptr + 2 * n))
1539 return -TARGET_EFAULT;
1541 ret = do_sendrecvmsg(fd, target_msg, flags,
1542 (num == SOCKOP_sendmsg));
1544 break;
1545 case SOCKOP_setsockopt:
1547 int sockfd;
1548 int level;
1549 int optname;
1550 abi_ulong optval;
1551 socklen_t optlen;
1553 if (get_user_s32(sockfd, vptr)
1554 || get_user_s32(level, vptr + n)
1555 || get_user_s32(optname, vptr + 2 * n)
1556 || get_user_ual(optval, vptr + 3 * n)
1557 || get_user_u32(optlen, vptr + 4 * n))
1558 return -TARGET_EFAULT;
1560 ret = do_setsockopt(sockfd, level, optname, optval, optlen);
1562 break;
1563 case SOCKOP_getsockopt:
1565 int sockfd;
1566 int level;
1567 int optname;
1568 abi_ulong optval;
1569 socklen_t optlen;
1571 if (get_user_s32(sockfd, vptr)
1572 || get_user_s32(level, vptr + n)
1573 || get_user_s32(optname, vptr + 2 * n)
1574 || get_user_ual(optval, vptr + 3 * n)
1575 || get_user_u32(optlen, vptr + 4 * n))
1576 return -TARGET_EFAULT;
1578 ret = do_getsockopt(sockfd, level, optname, optval, optlen);
1580 break;
1581 default:
1582 gemu_log("Unsupported socketcall: %d\n", num);
1583 ret = -TARGET_ENOSYS;
1584 break;
1586 return ret;
1588 #endif
1590 #ifdef TARGET_NR_ipc
1591 #define N_SHM_REGIONS 32
1593 static struct shm_region {
1594 abi_ulong start;
1595 abi_ulong size;
1596 } shm_regions[N_SHM_REGIONS];
1598 struct target_ipc_perm
1600 abi_long __key;
1601 abi_ulong uid;
1602 abi_ulong gid;
1603 abi_ulong cuid;
1604 abi_ulong cgid;
1605 unsigned short int mode;
1606 unsigned short int __pad1;
1607 unsigned short int __seq;
1608 unsigned short int __pad2;
1609 abi_ulong __unused1;
1610 abi_ulong __unused2;
1613 struct target_semid_ds
1615 struct target_ipc_perm sem_perm;
1616 abi_ulong sem_otime;
1617 abi_ulong __unused1;
1618 abi_ulong sem_ctime;
1619 abi_ulong __unused2;
1620 abi_ulong sem_nsems;
1621 abi_ulong __unused3;
1622 abi_ulong __unused4;
1625 static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
1626 abi_ulong target_addr)
1628 struct target_ipc_perm *target_ip;
1629 struct target_semid_ds *target_sd;
1631 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
1632 return -TARGET_EFAULT;
1633 target_ip=&(target_sd->sem_perm);
1634 host_ip->__key = tswapl(target_ip->__key);
1635 host_ip->uid = tswapl(target_ip->uid);
1636 host_ip->gid = tswapl(target_ip->gid);
1637 host_ip->cuid = tswapl(target_ip->cuid);
1638 host_ip->cgid = tswapl(target_ip->cgid);
1639 host_ip->mode = tswapl(target_ip->mode);
1640 unlock_user_struct(target_sd, target_addr, 0);
1641 return 0;
1644 static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
1645 struct ipc_perm *host_ip)
1647 struct target_ipc_perm *target_ip;
1648 struct target_semid_ds *target_sd;
1650 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
1651 return -TARGET_EFAULT;
1652 target_ip = &(target_sd->sem_perm);
1653 target_ip->__key = tswapl(host_ip->__key);
1654 target_ip->uid = tswapl(host_ip->uid);
1655 target_ip->gid = tswapl(host_ip->gid);
1656 target_ip->cuid = tswapl(host_ip->cuid);
1657 target_ip->cgid = tswapl(host_ip->cgid);
1658 target_ip->mode = tswapl(host_ip->mode);
1659 unlock_user_struct(target_sd, target_addr, 1);
1660 return 0;
1663 static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
1664 abi_ulong target_addr)
1666 struct target_semid_ds *target_sd;
1668 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
1669 return -TARGET_EFAULT;
1670 target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr);
1671 host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
1672 host_sd->sem_otime = tswapl(target_sd->sem_otime);
1673 host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
1674 unlock_user_struct(target_sd, target_addr, 0);
1675 return 0;
1678 static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
1679 struct semid_ds *host_sd)
1681 struct target_semid_ds *target_sd;
1683 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
1684 return -TARGET_EFAULT;
1685 host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm));
1686 target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
1687 target_sd->sem_otime = tswapl(host_sd->sem_otime);
1688 target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
1689 unlock_user_struct(target_sd, target_addr, 1);
1690 return 0;
1693 union semun {
1694 int val;
1695 struct semid_ds *buf;
1696 unsigned short *array;
1699 union target_semun {
1700 int val;
1701 abi_long buf;
1702 unsigned short int *array;
1705 static inline abi_long target_to_host_semun(int cmd,
1706 union semun *host_su,
1707 abi_ulong target_addr,
1708 struct semid_ds *ds)
1710 union target_semun *target_su;
1712 switch( cmd ) {
1713 case IPC_STAT:
1714 case IPC_SET:
1715 if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1716 return -TARGET_EFAULT;
1717 target_to_host_semid_ds(ds,target_su->buf);
1718 host_su->buf = ds;
1719 unlock_user_struct(target_su, target_addr, 0);
1720 break;
1721 case GETVAL:
1722 case SETVAL:
1723 if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1724 return -TARGET_EFAULT;
1725 host_su->val = tswapl(target_su->val);
1726 unlock_user_struct(target_su, target_addr, 0);
1727 break;
1728 case GETALL:
1729 case SETALL:
1730 if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1731 return -TARGET_EFAULT;
1732 *host_su->array = tswap16(*target_su->array);
1733 unlock_user_struct(target_su, target_addr, 0);
1734 break;
1735 default:
1736 gemu_log("semun operation not fully supported: %d\n", (int)cmd);
1738 return 0;
1741 static inline abi_long host_to_target_semun(int cmd,
1742 abi_ulong target_addr,
1743 union semun *host_su,
1744 struct semid_ds *ds)
1746 union target_semun *target_su;
1748 switch( cmd ) {
1749 case IPC_STAT:
1750 case IPC_SET:
1751 if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1752 return -TARGET_EFAULT;
1753 host_to_target_semid_ds(target_su->buf,ds);
1754 unlock_user_struct(target_su, target_addr, 1);
1755 break;
1756 case GETVAL:
1757 case SETVAL:
1758 if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1759 return -TARGET_EFAULT;
1760 target_su->val = tswapl(host_su->val);
1761 unlock_user_struct(target_su, target_addr, 1);
1762 break;
1763 case GETALL:
1764 case SETALL:
1765 if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1766 return -TARGET_EFAULT;
1767 *target_su->array = tswap16(*host_su->array);
1768 unlock_user_struct(target_su, target_addr, 1);
1769 break;
1770 default:
1771 gemu_log("semun operation not fully supported: %d\n", (int)cmd);
1773 return 0;
1776 static inline abi_long do_semctl(int first, int second, int third,
1777 abi_long ptr)
1779 union semun arg;
1780 struct semid_ds dsarg;
1781 int cmd = third&0xff;
1782 abi_long ret = 0;
1784 switch( cmd ) {
1785 case GETVAL:
1786 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1787 ret = get_errno(semctl(first, second, cmd, arg));
1788 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1789 break;
1790 case SETVAL:
1791 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1792 ret = get_errno(semctl(first, second, cmd, arg));
1793 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1794 break;
1795 case GETALL:
1796 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1797 ret = get_errno(semctl(first, second, cmd, arg));
1798 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1799 break;
1800 case SETALL:
1801 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1802 ret = get_errno(semctl(first, second, cmd, arg));
1803 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1804 break;
1805 case IPC_STAT:
1806 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1807 ret = get_errno(semctl(first, second, cmd, arg));
1808 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1809 break;
1810 case IPC_SET:
1811 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1812 ret = get_errno(semctl(first, second, cmd, arg));
1813 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1814 break;
1815 default:
1816 ret = get_errno(semctl(first, second, cmd, arg));
1819 return ret;
1822 struct target_msqid_ds
1824 struct target_ipc_perm msg_perm;
1825 abi_ulong msg_stime;
1826 abi_ulong __unused1;
1827 abi_ulong msg_rtime;
1828 abi_ulong __unused2;
1829 abi_ulong msg_ctime;
1830 abi_ulong __unused3;
1831 abi_ulong __msg_cbytes;
1832 abi_ulong msg_qnum;
1833 abi_ulong msg_qbytes;
1834 abi_ulong msg_lspid;
1835 abi_ulong msg_lrpid;
1836 abi_ulong __unused4;
1837 abi_ulong __unused5;
1840 static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
1841 abi_ulong target_addr)
1843 struct target_msqid_ds *target_md;
1845 if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
1846 return -TARGET_EFAULT;
1847 target_to_host_ipc_perm(&(host_md->msg_perm),target_addr);
1848 host_md->msg_stime = tswapl(target_md->msg_stime);
1849 host_md->msg_rtime = tswapl(target_md->msg_rtime);
1850 host_md->msg_ctime = tswapl(target_md->msg_ctime);
1851 host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
1852 host_md->msg_qnum = tswapl(target_md->msg_qnum);
1853 host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
1854 host_md->msg_lspid = tswapl(target_md->msg_lspid);
1855 host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
1856 unlock_user_struct(target_md, target_addr, 0);
1857 return 0;
1860 static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
1861 struct msqid_ds *host_md)
1863 struct target_msqid_ds *target_md;
1865 if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
1866 return -TARGET_EFAULT;
1867 host_to_target_ipc_perm(target_addr,&(host_md->msg_perm));
1868 target_md->msg_stime = tswapl(host_md->msg_stime);
1869 target_md->msg_rtime = tswapl(host_md->msg_rtime);
1870 target_md->msg_ctime = tswapl(host_md->msg_ctime);
1871 target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
1872 target_md->msg_qnum = tswapl(host_md->msg_qnum);
1873 target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
1874 target_md->msg_lspid = tswapl(host_md->msg_lspid);
1875 target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
1876 unlock_user_struct(target_md, target_addr, 1);
1877 return 0;
1880 static inline abi_long do_msgctl(int first, int second, abi_long ptr)
1882 struct msqid_ds dsarg;
1883 int cmd = second&0xff;
1884 abi_long ret = 0;
1885 switch( cmd ) {
1886 case IPC_STAT:
1887 case IPC_SET:
1888 target_to_host_msqid_ds(&dsarg,ptr);
1889 ret = get_errno(msgctl(first, cmd, &dsarg));
1890 host_to_target_msqid_ds(ptr,&dsarg);
1891 default:
1892 ret = get_errno(msgctl(first, cmd, &dsarg));
1894 return ret;
1897 struct target_msgbuf {
1898 abi_ulong mtype;
1899 char mtext[1];
1902 static inline abi_long do_msgsnd(int msqid, abi_long msgp,
1903 unsigned int msgsz, int msgflg)
1905 struct target_msgbuf *target_mb;
1906 struct msgbuf *host_mb;
1907 abi_long ret = 0;
1909 if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
1910 return -TARGET_EFAULT;
1911 host_mb = malloc(msgsz+sizeof(long));
1912 host_mb->mtype = tswapl(target_mb->mtype);
1913 memcpy(host_mb->mtext,target_mb->mtext,msgsz);
1914 ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
1915 free(host_mb);
1916 unlock_user_struct(target_mb, msgp, 0);
1918 return ret;
1921 static inline abi_long do_msgrcv(int msqid, abi_long msgp,
1922 unsigned int msgsz, int msgtype,
1923 int msgflg)
1925 struct target_msgbuf *target_mb;
1926 char *target_mtext;
1927 struct msgbuf *host_mb;
1928 abi_long ret = 0;
1930 if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
1931 return -TARGET_EFAULT;
1932 host_mb = malloc(msgsz+sizeof(long));
1933 ret = get_errno(msgrcv(msqid, host_mb, msgsz, 1, msgflg));
1934 if (ret > 0) {
1935 abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
1936 target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
1937 if (!target_mtext) {
1938 ret = -TARGET_EFAULT;
1939 goto end;
1941 memcpy(target_mb->mtext, host_mb->mtext, ret);
1942 unlock_user(target_mtext, target_mtext_addr, ret);
1944 target_mb->mtype = tswapl(host_mb->mtype);
1945 free(host_mb);
1947 end:
1948 if (target_mb)
1949 unlock_user_struct(target_mb, msgp, 1);
1950 return ret;
1953 /* ??? This only works with linear mappings. */
1954 /* do_ipc() must return target values and target errnos. */
1955 static abi_long do_ipc(unsigned int call, int first,
1956 int second, int third,
1957 abi_long ptr, abi_long fifth)
1959 int version;
1960 abi_long ret = 0;
1961 struct shmid_ds shm_info;
1962 int i;
1964 version = call >> 16;
1965 call &= 0xffff;
1967 switch (call) {
1968 case IPCOP_semop:
1969 ret = get_errno(semop(first,(struct sembuf *)g2h(ptr), second));
1970 break;
1972 case IPCOP_semget:
1973 ret = get_errno(semget(first, second, third));
1974 break;
1976 case IPCOP_semctl:
1977 ret = do_semctl(first, second, third, ptr);
1978 break;
1980 case IPCOP_semtimedop:
1981 gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
1982 ret = -TARGET_ENOSYS;
1983 break;
1985 case IPCOP_msgget:
1986 ret = get_errno(msgget(first, second));
1987 break;
1989 case IPCOP_msgsnd:
1990 ret = do_msgsnd(first, ptr, second, third);
1991 break;
1993 case IPCOP_msgctl:
1994 ret = do_msgctl(first, second, ptr);
1995 break;
1997 case IPCOP_msgrcv:
1999 /* XXX: this code is not correct */
2000 struct ipc_kludge
2002 void *__unbounded msgp;
2003 long int msgtyp;
2006 struct ipc_kludge *foo = (struct ipc_kludge *)g2h(ptr);
2007 struct msgbuf *msgp = (struct msgbuf *) foo->msgp;
2009 ret = do_msgrcv(first, (long)msgp, second, 0, third);
2012 break;
2014 case IPCOP_shmat:
2016 abi_ulong raddr;
2017 void *host_addr;
2018 /* SHM_* flags are the same on all linux platforms */
2019 host_addr = shmat(first, (void *)g2h(ptr), second);
2020 if (host_addr == (void *)-1) {
2021 ret = get_errno((long)host_addr);
2022 break;
2024 raddr = h2g((unsigned long)host_addr);
2025 /* find out the length of the shared memory segment */
2027 ret = get_errno(shmctl(first, IPC_STAT, &shm_info));
2028 if (is_error(ret)) {
2029 /* can't get length, bail out */
2030 shmdt(host_addr);
2031 break;
2033 page_set_flags(raddr, raddr + shm_info.shm_segsz,
2034 PAGE_VALID | PAGE_READ |
2035 ((second & SHM_RDONLY)? 0: PAGE_WRITE));
2036 for (i = 0; i < N_SHM_REGIONS; ++i) {
2037 if (shm_regions[i].start == 0) {
2038 shm_regions[i].start = raddr;
2039 shm_regions[i].size = shm_info.shm_segsz;
2040 break;
2043 if (put_user_ual(raddr, third))
2044 return -TARGET_EFAULT;
2045 ret = 0;
2047 break;
2048 case IPCOP_shmdt:
2049 for (i = 0; i < N_SHM_REGIONS; ++i) {
2050 if (shm_regions[i].start == ptr) {
2051 shm_regions[i].start = 0;
2052 page_set_flags(ptr, shm_regions[i].size, 0);
2053 break;
2056 ret = get_errno(shmdt((void *)g2h(ptr)));
2057 break;
2059 case IPCOP_shmget:
2060 /* IPC_* flag values are the same on all linux platforms */
2061 ret = get_errno(shmget(first, second, third));
2062 break;
2064 /* IPC_* and SHM_* command values are the same on all linux platforms */
2065 case IPCOP_shmctl:
2066 switch(second) {
2067 case IPC_RMID:
2068 case SHM_LOCK:
2069 case SHM_UNLOCK:
2070 ret = get_errno(shmctl(first, second, NULL));
2071 break;
2072 default:
2073 goto unimplemented;
2075 break;
2076 default:
2077 unimplemented:
2078 gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2079 ret = -TARGET_ENOSYS;
2080 break;
2082 return ret;
2084 #endif
2086 /* kernel structure types definitions */
2087 #define IFNAMSIZ 16
2089 #define STRUCT(name, list...) STRUCT_ ## name,
2090 #define STRUCT_SPECIAL(name) STRUCT_ ## name,
2091 enum {
2092 #include "syscall_types.h"
2094 #undef STRUCT
2095 #undef STRUCT_SPECIAL
2097 #define STRUCT(name, list...) const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };
2098 #define STRUCT_SPECIAL(name)
2099 #include "syscall_types.h"
2100 #undef STRUCT
2101 #undef STRUCT_SPECIAL
2103 typedef struct IOCTLEntry {
2104 unsigned int target_cmd;
2105 unsigned int host_cmd;
2106 const char *name;
2107 int access;
2108 const argtype arg_type[5];
2109 } IOCTLEntry;
2111 #define IOC_R 0x0001
2112 #define IOC_W 0x0002
2113 #define IOC_RW (IOC_R | IOC_W)
2115 #define MAX_STRUCT_SIZE 4096
2117 IOCTLEntry ioctl_entries[] = {
2118 #define IOCTL(cmd, access, types...) \
2119 { TARGET_ ## cmd, cmd, #cmd, access, { types } },
2120 #include "ioctls.h"
2121 { 0, 0, },
2124 /* ??? Implement proper locking for ioctls. */
2125 /* do_ioctl() Must return target values and target errnos. */
2126 static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
2128 const IOCTLEntry *ie;
2129 const argtype *arg_type;
2130 abi_long ret;
2131 uint8_t buf_temp[MAX_STRUCT_SIZE];
2132 int target_size;
2133 void *argptr;
2135 ie = ioctl_entries;
2136 for(;;) {
2137 if (ie->target_cmd == 0) {
2138 gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
2139 return -TARGET_ENOSYS;
2141 if (ie->target_cmd == cmd)
2142 break;
2143 ie++;
2145 arg_type = ie->arg_type;
2146 #if defined(DEBUG)
2147 gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
2148 #endif
2149 switch(arg_type[0]) {
2150 case TYPE_NULL:
2151 /* no argument */
2152 ret = get_errno(ioctl(fd, ie->host_cmd));
2153 break;
2154 case TYPE_PTRVOID:
2155 case TYPE_INT:
2156 /* int argment */
2157 ret = get_errno(ioctl(fd, ie->host_cmd, arg));
2158 break;
2159 case TYPE_PTR:
2160 arg_type++;
2161 target_size = thunk_type_size(arg_type, 0);
2162 switch(ie->access) {
2163 case IOC_R:
2164 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2165 if (!is_error(ret)) {
2166 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2167 if (!argptr)
2168 return -TARGET_EFAULT;
2169 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2170 unlock_user(argptr, arg, target_size);
2172 break;
2173 case IOC_W:
2174 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2175 if (!argptr)
2176 return -TARGET_EFAULT;
2177 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2178 unlock_user(argptr, arg, 0);
2179 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2180 break;
2181 default:
2182 case IOC_RW:
2183 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2184 if (!argptr)
2185 return -TARGET_EFAULT;
2186 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2187 unlock_user(argptr, arg, 0);
2188 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2189 if (!is_error(ret)) {
2190 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2191 if (!argptr)
2192 return -TARGET_EFAULT;
2193 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2194 unlock_user(argptr, arg, target_size);
2196 break;
2198 break;
2199 default:
2200 gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
2201 (long)cmd, arg_type[0]);
2202 ret = -TARGET_ENOSYS;
2203 break;
2205 return ret;
2208 bitmask_transtbl iflag_tbl[] = {
2209 { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
2210 { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
2211 { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
2212 { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
2213 { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
2214 { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
2215 { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
2216 { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
2217 { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
2218 { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
2219 { TARGET_IXON, TARGET_IXON, IXON, IXON },
2220 { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
2221 { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
2222 { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
2223 { 0, 0, 0, 0 }
2226 bitmask_transtbl oflag_tbl[] = {
2227 { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
2228 { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
2229 { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
2230 { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
2231 { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
2232 { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
2233 { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
2234 { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
2235 { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
2236 { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
2237 { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
2238 { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
2239 { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
2240 { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
2241 { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
2242 { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
2243 { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
2244 { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
2245 { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
2246 { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
2247 { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
2248 { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
2249 { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
2250 { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
2251 { 0, 0, 0, 0 }
2254 bitmask_transtbl cflag_tbl[] = {
2255 { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
2256 { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
2257 { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
2258 { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
2259 { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
2260 { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
2261 { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
2262 { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
2263 { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
2264 { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
2265 { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
2266 { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
2267 { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
2268 { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
2269 { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
2270 { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
2271 { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
2272 { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
2273 { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
2274 { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
2275 { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
2276 { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
2277 { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
2278 { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
2279 { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
2280 { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
2281 { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
2282 { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
2283 { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
2284 { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
2285 { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
2286 { 0, 0, 0, 0 }
2289 bitmask_transtbl lflag_tbl[] = {
2290 { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
2291 { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
2292 { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
2293 { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
2294 { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
2295 { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
2296 { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
2297 { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
2298 { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
2299 { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
2300 { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
2301 { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
2302 { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
2303 { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
2304 { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
2305 { 0, 0, 0, 0 }
2308 static void target_to_host_termios (void *dst, const void *src)
2310 struct host_termios *host = dst;
2311 const struct target_termios *target = src;
2313 host->c_iflag =
2314 target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
2315 host->c_oflag =
2316 target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
2317 host->c_cflag =
2318 target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
2319 host->c_lflag =
2320 target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
2321 host->c_line = target->c_line;
2323 host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
2324 host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
2325 host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
2326 host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
2327 host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
2328 host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
2329 host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
2330 host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
2331 host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
2332 host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
2333 host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
2334 host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
2335 host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
2336 host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
2337 host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
2338 host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
2339 host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
2342 static void host_to_target_termios (void *dst, const void *src)
2344 struct target_termios *target = dst;
2345 const struct host_termios *host = src;
2347 target->c_iflag =
2348 tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
2349 target->c_oflag =
2350 tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
2351 target->c_cflag =
2352 tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
2353 target->c_lflag =
2354 tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
2355 target->c_line = host->c_line;
2357 target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
2358 target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
2359 target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
2360 target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
2361 target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
2362 target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
2363 target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
2364 target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
2365 target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
2366 target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
2367 target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
2368 target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
2369 target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
2370 target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
2371 target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
2372 target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
2373 target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
2376 StructEntry struct_termios_def = {
2377 .convert = { host_to_target_termios, target_to_host_termios },
2378 .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
2379 .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
2382 static bitmask_transtbl mmap_flags_tbl[] = {
2383 { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
2384 { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
2385 { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
2386 { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
2387 { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
2388 { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
2389 { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
2390 { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
2391 { 0, 0, 0, 0 }
2394 static bitmask_transtbl fcntl_flags_tbl[] = {
2395 { TARGET_O_ACCMODE, TARGET_O_WRONLY, O_ACCMODE, O_WRONLY, },
2396 { TARGET_O_ACCMODE, TARGET_O_RDWR, O_ACCMODE, O_RDWR, },
2397 { TARGET_O_CREAT, TARGET_O_CREAT, O_CREAT, O_CREAT, },
2398 { TARGET_O_EXCL, TARGET_O_EXCL, O_EXCL, O_EXCL, },
2399 { TARGET_O_NOCTTY, TARGET_O_NOCTTY, O_NOCTTY, O_NOCTTY, },
2400 { TARGET_O_TRUNC, TARGET_O_TRUNC, O_TRUNC, O_TRUNC, },
2401 { TARGET_O_APPEND, TARGET_O_APPEND, O_APPEND, O_APPEND, },
2402 { TARGET_O_NONBLOCK, TARGET_O_NONBLOCK, O_NONBLOCK, O_NONBLOCK, },
2403 { TARGET_O_SYNC, TARGET_O_SYNC, O_SYNC, O_SYNC, },
2404 { TARGET_FASYNC, TARGET_FASYNC, FASYNC, FASYNC, },
2405 { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
2406 { TARGET_O_NOFOLLOW, TARGET_O_NOFOLLOW, O_NOFOLLOW, O_NOFOLLOW, },
2407 { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
2408 #if defined(O_DIRECT)
2409 { TARGET_O_DIRECT, TARGET_O_DIRECT, O_DIRECT, O_DIRECT, },
2410 #endif
2411 { 0, 0, 0, 0 }
2414 #if defined(TARGET_I386)
2416 /* NOTE: there is really one LDT for all the threads */
2417 uint8_t *ldt_table;
2419 static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
2421 int size;
2422 void *p;
2424 if (!ldt_table)
2425 return 0;
2426 size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
2427 if (size > bytecount)
2428 size = bytecount;
2429 p = lock_user(VERIFY_WRITE, ptr, size, 0);
2430 if (!p)
2431 return -TARGET_EFAULT;
2432 /* ??? Should this by byteswapped? */
2433 memcpy(p, ldt_table, size);
2434 unlock_user(p, ptr, size);
2435 return size;
2438 /* XXX: add locking support */
2439 static abi_long write_ldt(CPUX86State *env,
2440 abi_ulong ptr, unsigned long bytecount, int oldmode)
2442 struct target_modify_ldt_ldt_s ldt_info;
2443 struct target_modify_ldt_ldt_s *target_ldt_info;
2444 int seg_32bit, contents, read_exec_only, limit_in_pages;
2445 int seg_not_present, useable, lm;
2446 uint32_t *lp, entry_1, entry_2;
2448 if (bytecount != sizeof(ldt_info))
2449 return -TARGET_EINVAL;
2450 if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
2451 return -TARGET_EFAULT;
2452 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2453 ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2454 ldt_info.limit = tswap32(target_ldt_info->limit);
2455 ldt_info.flags = tswap32(target_ldt_info->flags);
2456 unlock_user_struct(target_ldt_info, ptr, 0);
2458 if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
2459 return -TARGET_EINVAL;
2460 seg_32bit = ldt_info.flags & 1;
2461 contents = (ldt_info.flags >> 1) & 3;
2462 read_exec_only = (ldt_info.flags >> 3) & 1;
2463 limit_in_pages = (ldt_info.flags >> 4) & 1;
2464 seg_not_present = (ldt_info.flags >> 5) & 1;
2465 useable = (ldt_info.flags >> 6) & 1;
2466 #ifdef TARGET_ABI32
2467 lm = 0;
2468 #else
2469 lm = (ldt_info.flags >> 7) & 1;
2470 #endif
2471 if (contents == 3) {
2472 if (oldmode)
2473 return -TARGET_EINVAL;
2474 if (seg_not_present == 0)
2475 return -TARGET_EINVAL;
2477 /* allocate the LDT */
2478 if (!ldt_table) {
2479 ldt_table = malloc(TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
2480 if (!ldt_table)
2481 return -TARGET_ENOMEM;
2482 memset(ldt_table, 0, TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
2483 env->ldt.base = h2g((unsigned long)ldt_table);
2484 env->ldt.limit = 0xffff;
2487 /* NOTE: same code as Linux kernel */
2488 /* Allow LDTs to be cleared by the user. */
2489 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2490 if (oldmode ||
2491 (contents == 0 &&
2492 read_exec_only == 1 &&
2493 seg_32bit == 0 &&
2494 limit_in_pages == 0 &&
2495 seg_not_present == 1 &&
2496 useable == 0 )) {
2497 entry_1 = 0;
2498 entry_2 = 0;
2499 goto install;
2503 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2504 (ldt_info.limit & 0x0ffff);
2505 entry_2 = (ldt_info.base_addr & 0xff000000) |
2506 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2507 (ldt_info.limit & 0xf0000) |
2508 ((read_exec_only ^ 1) << 9) |
2509 (contents << 10) |
2510 ((seg_not_present ^ 1) << 15) |
2511 (seg_32bit << 22) |
2512 (limit_in_pages << 23) |
2513 (lm << 21) |
2514 0x7000;
2515 if (!oldmode)
2516 entry_2 |= (useable << 20);
2518 /* Install the new entry ... */
2519 install:
2520 lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
2521 lp[0] = tswap32(entry_1);
2522 lp[1] = tswap32(entry_2);
2523 return 0;
2526 /* specific and weird i386 syscalls */
2527 static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
2528 unsigned long bytecount)
2530 abi_long ret;
2532 switch (func) {
2533 case 0:
2534 ret = read_ldt(ptr, bytecount);
2535 break;
2536 case 1:
2537 ret = write_ldt(env, ptr, bytecount, 1);
2538 break;
2539 case 0x11:
2540 ret = write_ldt(env, ptr, bytecount, 0);
2541 break;
2542 default:
2543 ret = -TARGET_ENOSYS;
2544 break;
2546 return ret;
2549 #if defined(TARGET_I386) && defined(TARGET_ABI32)
2550 static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
2552 uint64_t *gdt_table = g2h(env->gdt.base);
2553 struct target_modify_ldt_ldt_s ldt_info;
2554 struct target_modify_ldt_ldt_s *target_ldt_info;
2555 int seg_32bit, contents, read_exec_only, limit_in_pages;
2556 int seg_not_present, useable, lm;
2557 uint32_t *lp, entry_1, entry_2;
2558 int i;
2560 lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
2561 if (!target_ldt_info)
2562 return -TARGET_EFAULT;
2563 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2564 ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2565 ldt_info.limit = tswap32(target_ldt_info->limit);
2566 ldt_info.flags = tswap32(target_ldt_info->flags);
2567 if (ldt_info.entry_number == -1) {
2568 for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
2569 if (gdt_table[i] == 0) {
2570 ldt_info.entry_number = i;
2571 target_ldt_info->entry_number = tswap32(i);
2572 break;
2576 unlock_user_struct(target_ldt_info, ptr, 1);
2578 if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN ||
2579 ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
2580 return -TARGET_EINVAL;
2581 seg_32bit = ldt_info.flags & 1;
2582 contents = (ldt_info.flags >> 1) & 3;
2583 read_exec_only = (ldt_info.flags >> 3) & 1;
2584 limit_in_pages = (ldt_info.flags >> 4) & 1;
2585 seg_not_present = (ldt_info.flags >> 5) & 1;
2586 useable = (ldt_info.flags >> 6) & 1;
2587 #ifdef TARGET_ABI32
2588 lm = 0;
2589 #else
2590 lm = (ldt_info.flags >> 7) & 1;
2591 #endif
2593 if (contents == 3) {
2594 if (seg_not_present == 0)
2595 return -TARGET_EINVAL;
2598 /* NOTE: same code as Linux kernel */
2599 /* Allow LDTs to be cleared by the user. */
2600 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2601 if ((contents == 0 &&
2602 read_exec_only == 1 &&
2603 seg_32bit == 0 &&
2604 limit_in_pages == 0 &&
2605 seg_not_present == 1 &&
2606 useable == 0 )) {
2607 entry_1 = 0;
2608 entry_2 = 0;
2609 goto install;
2613 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2614 (ldt_info.limit & 0x0ffff);
2615 entry_2 = (ldt_info.base_addr & 0xff000000) |
2616 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2617 (ldt_info.limit & 0xf0000) |
2618 ((read_exec_only ^ 1) << 9) |
2619 (contents << 10) |
2620 ((seg_not_present ^ 1) << 15) |
2621 (seg_32bit << 22) |
2622 (limit_in_pages << 23) |
2623 (useable << 20) |
2624 (lm << 21) |
2625 0x7000;
2627 /* Install the new entry ... */
2628 install:
2629 lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
2630 lp[0] = tswap32(entry_1);
2631 lp[1] = tswap32(entry_2);
2632 return 0;
2635 static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
2637 struct target_modify_ldt_ldt_s *target_ldt_info;
2638 uint64_t *gdt_table = g2h(env->gdt.base);
2639 uint32_t base_addr, limit, flags;
2640 int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
2641 int seg_not_present, useable, lm;
2642 uint32_t *lp, entry_1, entry_2;
2644 lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
2645 if (!target_ldt_info)
2646 return -TARGET_EFAULT;
2647 idx = tswap32(target_ldt_info->entry_number);
2648 if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
2649 idx > TARGET_GDT_ENTRY_TLS_MAX) {
2650 unlock_user_struct(target_ldt_info, ptr, 1);
2651 return -TARGET_EINVAL;
2653 lp = (uint32_t *)(gdt_table + idx);
2654 entry_1 = tswap32(lp[0]);
2655 entry_2 = tswap32(lp[1]);
2657 read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
2658 contents = (entry_2 >> 10) & 3;
2659 seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
2660 seg_32bit = (entry_2 >> 22) & 1;
2661 limit_in_pages = (entry_2 >> 23) & 1;
2662 useable = (entry_2 >> 20) & 1;
2663 #ifdef TARGET_ABI32
2664 lm = 0;
2665 #else
2666 lm = (entry_2 >> 21) & 1;
2667 #endif
2668 flags = (seg_32bit << 0) | (contents << 1) |
2669 (read_exec_only << 3) | (limit_in_pages << 4) |
2670 (seg_not_present << 5) | (useable << 6) | (lm << 7);
2671 limit = (entry_1 & 0xffff) | (entry_2 & 0xf0000);
2672 base_addr = (entry_1 >> 16) |
2673 (entry_2 & 0xff000000) |
2674 ((entry_2 & 0xff) << 16);
2675 target_ldt_info->base_addr = tswapl(base_addr);
2676 target_ldt_info->limit = tswap32(limit);
2677 target_ldt_info->flags = tswap32(flags);
2678 unlock_user_struct(target_ldt_info, ptr, 1);
2679 return 0;
2681 #endif /* TARGET_I386 && TARGET_ABI32 */
2683 #ifndef TARGET_ABI32
2684 static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
2686 abi_long ret;
2687 abi_ulong val;
2688 int idx;
2690 switch(code) {
2691 case TARGET_ARCH_SET_GS:
2692 case TARGET_ARCH_SET_FS:
2693 if (code == TARGET_ARCH_SET_GS)
2694 idx = R_GS;
2695 else
2696 idx = R_FS;
2697 cpu_x86_load_seg(env, idx, 0);
2698 env->segs[idx].base = addr;
2699 break;
2700 case TARGET_ARCH_GET_GS:
2701 case TARGET_ARCH_GET_FS:
2702 if (code == TARGET_ARCH_GET_GS)
2703 idx = R_GS;
2704 else
2705 idx = R_FS;
2706 val = env->segs[idx].base;
2707 if (put_user(val, addr, abi_ulong))
2708 return -TARGET_EFAULT;
2709 break;
2710 default:
2711 ret = -TARGET_EINVAL;
2712 break;
2714 return 0;
2716 #endif
2718 #endif /* defined(TARGET_I386) */
2720 #if defined(USE_NPTL)
2722 #define NEW_STACK_SIZE PTHREAD_STACK_MIN
2724 static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
2725 typedef struct {
2726 CPUState *env;
2727 pthread_mutex_t mutex;
2728 pthread_cond_t cond;
2729 pthread_t thread;
2730 uint32_t tid;
2731 abi_ulong child_tidptr;
2732 abi_ulong parent_tidptr;
2733 sigset_t sigmask;
2734 } new_thread_info;
2736 static void *clone_func(void *arg)
2738 new_thread_info *info = arg;
2739 CPUState *env;
2741 env = info->env;
2742 thread_env = env;
2743 info->tid = gettid();
2744 if (info->child_tidptr)
2745 put_user_u32(info->tid, info->child_tidptr);
2746 if (info->parent_tidptr)
2747 put_user_u32(info->tid, info->parent_tidptr);
2748 /* Enable signals. */
2749 sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
2750 /* Signal to the parent that we're ready. */
2751 pthread_mutex_lock(&info->mutex);
2752 pthread_cond_broadcast(&info->cond);
2753 pthread_mutex_unlock(&info->mutex);
2754 /* Wait until the parent has finshed initializing the tls state. */
2755 pthread_mutex_lock(&clone_lock);
2756 pthread_mutex_unlock(&clone_lock);
2757 cpu_loop(env);
2758 /* never exits */
2759 return NULL;
2761 #else
2762 /* this stack is the equivalent of the kernel stack associated with a
2763 thread/process */
2764 #define NEW_STACK_SIZE 8192
2766 static int clone_func(void *arg)
2768 CPUState *env = arg;
2769 cpu_loop(env);
2770 /* never exits */
2771 return 0;
2773 #endif
2775 /* do_fork() Must return host values and target errnos (unlike most
2776 do_*() functions). */
2777 static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
2778 abi_ulong parent_tidptr, target_ulong newtls,
2779 abi_ulong child_tidptr)
2781 int ret;
2782 TaskState *ts;
2783 uint8_t *new_stack;
2784 CPUState *new_env;
2785 #if defined(USE_NPTL)
2786 unsigned int nptl_flags;
2787 sigset_t sigmask;
2788 #endif
2790 if (flags & CLONE_VM) {
2791 #if defined(USE_NPTL)
2792 new_thread_info info;
2793 pthread_attr_t attr;
2794 #endif
2795 ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
2796 init_task_state(ts);
2797 new_stack = ts->stack;
2798 /* we create a new CPU instance. */
2799 new_env = cpu_copy(env);
2800 /* Init regs that differ from the parent. */
2801 cpu_clone_regs(new_env, newsp);
2802 new_env->opaque = ts;
2803 #if defined(USE_NPTL)
2804 nptl_flags = flags;
2805 flags &= ~CLONE_NPTL_FLAGS2;
2807 /* TODO: Implement CLONE_CHILD_CLEARTID. */
2808 if (nptl_flags & CLONE_SETTLS)
2809 cpu_set_tls (new_env, newtls);
2811 /* Grab a mutex so that thread setup appears atomic. */
2812 pthread_mutex_lock(&clone_lock);
2814 memset(&info, 0, sizeof(info));
2815 pthread_mutex_init(&info.mutex, NULL);
2816 pthread_mutex_lock(&info.mutex);
2817 pthread_cond_init(&info.cond, NULL);
2818 info.env = new_env;
2819 if (nptl_flags & CLONE_CHILD_SETTID)
2820 info.child_tidptr = child_tidptr;
2821 if (nptl_flags & CLONE_PARENT_SETTID)
2822 info.parent_tidptr = parent_tidptr;
2824 ret = pthread_attr_init(&attr);
2825 ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE);
2826 /* It is not safe to deliver signals until the child has finished
2827 initializing, so temporarily block all signals. */
2828 sigfillset(&sigmask);
2829 sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
2831 ret = pthread_create(&info.thread, &attr, clone_func, &info);
2833 sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
2834 pthread_attr_destroy(&attr);
2835 if (ret == 0) {
2836 /* Wait for the child to initialize. */
2837 pthread_cond_wait(&info.cond, &info.mutex);
2838 ret = info.tid;
2839 if (flags & CLONE_PARENT_SETTID)
2840 put_user_u32(ret, parent_tidptr);
2841 } else {
2842 ret = -1;
2844 pthread_mutex_unlock(&info.mutex);
2845 pthread_cond_destroy(&info.cond);
2846 pthread_mutex_destroy(&info.mutex);
2847 pthread_mutex_unlock(&clone_lock);
2848 #else
2849 if (flags & CLONE_NPTL_FLAGS2)
2850 return -EINVAL;
2851 /* This is probably going to die very quickly, but do it anyway. */
2852 #ifdef __ia64__
2853 ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
2854 #else
2855 ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
2856 #endif
2857 #endif
2858 } else {
2859 /* if no CLONE_VM, we consider it is a fork */
2860 if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
2861 return -EINVAL;
2862 fork_start();
2863 ret = fork();
2864 #if defined(USE_NPTL)
2865 /* There is a race condition here. The parent process could
2866 theoretically read the TID in the child process before the child
2867 tid is set. This would require using either ptrace
2868 (not implemented) or having *_tidptr to point at a shared memory
2869 mapping. We can't repeat the spinlock hack used above because
2870 the child process gets its own copy of the lock. */
2871 if (ret == 0) {
2872 cpu_clone_regs(env, newsp);
2873 fork_end(1);
2874 /* Child Process. */
2875 if (flags & CLONE_CHILD_SETTID)
2876 put_user_u32(gettid(), child_tidptr);
2877 if (flags & CLONE_PARENT_SETTID)
2878 put_user_u32(gettid(), parent_tidptr);
2879 ts = (TaskState *)env->opaque;
2880 if (flags & CLONE_SETTLS)
2881 cpu_set_tls (env, newtls);
2882 /* TODO: Implement CLONE_CHILD_CLEARTID. */
2883 } else {
2884 fork_end(0);
2886 #else
2887 if (ret == 0) {
2888 cpu_clone_regs(env, newsp);
2890 #endif
2892 return ret;
2895 static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
2897 struct flock fl;
2898 struct target_flock *target_fl;
2899 struct flock64 fl64;
2900 struct target_flock64 *target_fl64;
2901 abi_long ret;
2903 switch(cmd) {
2904 case TARGET_F_GETLK:
2905 if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
2906 return -TARGET_EFAULT;
2907 fl.l_type = tswap16(target_fl->l_type);
2908 fl.l_whence = tswap16(target_fl->l_whence);
2909 fl.l_start = tswapl(target_fl->l_start);
2910 fl.l_len = tswapl(target_fl->l_len);
2911 fl.l_pid = tswapl(target_fl->l_pid);
2912 unlock_user_struct(target_fl, arg, 0);
2913 ret = get_errno(fcntl(fd, cmd, &fl));
2914 if (ret == 0) {
2915 if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
2916 return -TARGET_EFAULT;
2917 target_fl->l_type = tswap16(fl.l_type);
2918 target_fl->l_whence = tswap16(fl.l_whence);
2919 target_fl->l_start = tswapl(fl.l_start);
2920 target_fl->l_len = tswapl(fl.l_len);
2921 target_fl->l_pid = tswapl(fl.l_pid);
2922 unlock_user_struct(target_fl, arg, 1);
2924 break;
2926 case TARGET_F_SETLK:
2927 case TARGET_F_SETLKW:
2928 if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
2929 return -TARGET_EFAULT;
2930 fl.l_type = tswap16(target_fl->l_type);
2931 fl.l_whence = tswap16(target_fl->l_whence);
2932 fl.l_start = tswapl(target_fl->l_start);
2933 fl.l_len = tswapl(target_fl->l_len);
2934 fl.l_pid = tswapl(target_fl->l_pid);
2935 unlock_user_struct(target_fl, arg, 0);
2936 ret = get_errno(fcntl(fd, cmd, &fl));
2937 break;
2939 case TARGET_F_GETLK64:
2940 if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
2941 return -TARGET_EFAULT;
2942 fl64.l_type = tswap16(target_fl64->l_type) >> 1;
2943 fl64.l_whence = tswap16(target_fl64->l_whence);
2944 fl64.l_start = tswapl(target_fl64->l_start);
2945 fl64.l_len = tswapl(target_fl64->l_len);
2946 fl64.l_pid = tswap16(target_fl64->l_pid);
2947 unlock_user_struct(target_fl64, arg, 0);
2948 ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
2949 if (ret == 0) {
2950 if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
2951 return -TARGET_EFAULT;
2952 target_fl64->l_type = tswap16(fl64.l_type) >> 1;
2953 target_fl64->l_whence = tswap16(fl64.l_whence);
2954 target_fl64->l_start = tswapl(fl64.l_start);
2955 target_fl64->l_len = tswapl(fl64.l_len);
2956 target_fl64->l_pid = tswapl(fl64.l_pid);
2957 unlock_user_struct(target_fl64, arg, 1);
2959 break;
2960 case TARGET_F_SETLK64:
2961 case TARGET_F_SETLKW64:
2962 if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
2963 return -TARGET_EFAULT;
2964 fl64.l_type = tswap16(target_fl64->l_type) >> 1;
2965 fl64.l_whence = tswap16(target_fl64->l_whence);
2966 fl64.l_start = tswapl(target_fl64->l_start);
2967 fl64.l_len = tswapl(target_fl64->l_len);
2968 fl64.l_pid = tswap16(target_fl64->l_pid);
2969 unlock_user_struct(target_fl64, arg, 0);
2970 ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
2971 break;
2973 case F_GETFL:
2974 ret = get_errno(fcntl(fd, cmd, arg));
2975 if (ret >= 0) {
2976 ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
2978 break;
2980 case F_SETFL:
2981 ret = get_errno(fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
2982 break;
2984 default:
2985 ret = get_errno(fcntl(fd, cmd, arg));
2986 break;
2988 return ret;
2991 #ifdef USE_UID16
2993 static inline int high2lowuid(int uid)
2995 if (uid > 65535)
2996 return 65534;
2997 else
2998 return uid;
3001 static inline int high2lowgid(int gid)
3003 if (gid > 65535)
3004 return 65534;
3005 else
3006 return gid;
3009 static inline int low2highuid(int uid)
3011 if ((int16_t)uid == -1)
3012 return -1;
3013 else
3014 return uid;
3017 static inline int low2highgid(int gid)
3019 if ((int16_t)gid == -1)
3020 return -1;
3021 else
3022 return gid;
3025 #endif /* USE_UID16 */
3027 void syscall_init(void)
3029 IOCTLEntry *ie;
3030 const argtype *arg_type;
3031 int size;
3032 int i;
3034 #define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3035 #define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3036 #include "syscall_types.h"
3037 #undef STRUCT
3038 #undef STRUCT_SPECIAL
3040 /* we patch the ioctl size if necessary. We rely on the fact that
3041 no ioctl has all the bits at '1' in the size field */
3042 ie = ioctl_entries;
3043 while (ie->target_cmd != 0) {
3044 if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
3045 TARGET_IOC_SIZEMASK) {
3046 arg_type = ie->arg_type;
3047 if (arg_type[0] != TYPE_PTR) {
3048 fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
3049 ie->target_cmd);
3050 exit(1);
3052 arg_type++;
3053 size = thunk_type_size(arg_type, 0);
3054 ie->target_cmd = (ie->target_cmd &
3055 ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
3056 (size << TARGET_IOC_SIZESHIFT);
3059 /* Build target_to_host_errno_table[] table from
3060 * host_to_target_errno_table[]. */
3061 for (i=0; i < ERRNO_TABLE_SIZE; i++)
3062 target_to_host_errno_table[host_to_target_errno_table[i]] = i;
3064 /* automatic consistency check if same arch */
3065 #if defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)
3066 if (ie->target_cmd != ie->host_cmd) {
3067 fprintf(stderr, "ERROR: ioctl: target=0x%x host=0x%x\n",
3068 ie->target_cmd, ie->host_cmd);
3070 #endif
3071 ie++;
3075 #if TARGET_ABI_BITS == 32
3076 static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
3078 #ifdef TARGET_WORDS_BIGENDIAN
3079 return ((uint64_t)word0 << 32) | word1;
3080 #else
3081 return ((uint64_t)word1 << 32) | word0;
3082 #endif
3084 #else /* TARGET_ABI_BITS == 32 */
3085 static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
3087 return word0;
3089 #endif /* TARGET_ABI_BITS != 32 */
3091 #ifdef TARGET_NR_truncate64
3092 static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
3093 abi_long arg2,
3094 abi_long arg3,
3095 abi_long arg4)
3097 #ifdef TARGET_ARM
3098 if (((CPUARMState *)cpu_env)->eabi)
3100 arg2 = arg3;
3101 arg3 = arg4;
3103 #endif
3104 return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
3106 #endif
3108 #ifdef TARGET_NR_ftruncate64
3109 static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
3110 abi_long arg2,
3111 abi_long arg3,
3112 abi_long arg4)
3114 #ifdef TARGET_ARM
3115 if (((CPUARMState *)cpu_env)->eabi)
3117 arg2 = arg3;
3118 arg3 = arg4;
3120 #endif
3121 return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
3123 #endif
3125 static inline abi_long target_to_host_timespec(struct timespec *host_ts,
3126 abi_ulong target_addr)
3128 struct target_timespec *target_ts;
3130 if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
3131 return -TARGET_EFAULT;
3132 host_ts->tv_sec = tswapl(target_ts->tv_sec);
3133 host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
3134 unlock_user_struct(target_ts, target_addr, 0);
3135 return 0;
3138 static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3139 struct timespec *host_ts)
3141 struct target_timespec *target_ts;
3143 if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
3144 return -TARGET_EFAULT;
3145 target_ts->tv_sec = tswapl(host_ts->tv_sec);
3146 target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
3147 unlock_user_struct(target_ts, target_addr, 1);
3148 return 0;
3151 #if defined(USE_NPTL)
3152 /* ??? Using host futex calls even when target atomic operations
3153 are not really atomic probably breaks things. However implementing
3154 futexes locally would make futexes shared between multiple processes
3155 tricky. However they're probably useless because guest atomic
3156 operations won't work either. */
3157 static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
3158 target_ulong uaddr2, int val3)
3160 struct timespec ts, *pts;
3162 /* ??? We assume FUTEX_* constants are the same on both host
3163 and target. */
3164 switch (op) {
3165 case FUTEX_WAIT:
3166 if (timeout) {
3167 pts = &ts;
3168 target_to_host_timespec(pts, timeout);
3169 } else {
3170 pts = NULL;
3172 return get_errno(sys_futex(g2h(uaddr), FUTEX_WAIT, tswap32(val),
3173 pts, NULL, 0));
3174 case FUTEX_WAKE:
3175 return get_errno(sys_futex(g2h(uaddr), FUTEX_WAKE, val, NULL, NULL, 0));
3176 case FUTEX_FD:
3177 return get_errno(sys_futex(g2h(uaddr), FUTEX_FD, val, NULL, NULL, 0));
3178 case FUTEX_REQUEUE:
3179 return get_errno(sys_futex(g2h(uaddr), FUTEX_REQUEUE, val,
3180 NULL, g2h(uaddr2), 0));
3181 case FUTEX_CMP_REQUEUE:
3182 return get_errno(sys_futex(g2h(uaddr), FUTEX_CMP_REQUEUE, val,
3183 NULL, g2h(uaddr2), tswap32(val3)));
3184 default:
3185 return -TARGET_ENOSYS;
3188 #endif
3190 int get_osversion(void)
3192 static int osversion;
3193 struct new_utsname buf;
3194 const char *s;
3195 int i, n, tmp;
3196 if (osversion)
3197 return osversion;
3198 if (qemu_uname_release && *qemu_uname_release) {
3199 s = qemu_uname_release;
3200 } else {
3201 if (sys_uname(&buf))
3202 return 0;
3203 s = buf.release;
3205 tmp = 0;
3206 for (i = 0; i < 3; i++) {
3207 n = 0;
3208 while (*s >= '0' && *s <= '9') {
3209 n *= 10;
3210 n += *s - '0';
3211 s++;
3213 tmp = (tmp << 8) + n;
3214 if (*s == '.')
3215 s++;
3217 osversion = tmp;
3218 return osversion;
3221 /* do_syscall() should always have a single exit point at the end so
3222 that actions, such as logging of syscall results, can be performed.
3223 All errnos that do_syscall() returns must be -TARGET_<errcode>. */
3224 abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3225 abi_long arg2, abi_long arg3, abi_long arg4,
3226 abi_long arg5, abi_long arg6)
3228 abi_long ret;
3229 struct stat st;
3230 struct statfs stfs;
3231 void *p;
3233 #ifdef DEBUG
3234 gemu_log("syscall %d", num);
3235 #endif
3236 if(do_strace)
3237 print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
3239 switch(num) {
3240 case TARGET_NR_exit:
3241 #ifdef HAVE_GPROF
3242 _mcleanup();
3243 #endif
3244 gdb_exit(cpu_env, arg1);
3245 /* XXX: should free thread stack and CPU env */
3246 _exit(arg1);
3247 ret = 0; /* avoid warning */
3248 break;
3249 case TARGET_NR_read:
3250 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
3251 goto efault;
3252 ret = get_errno(read(arg1, p, arg3));
3253 unlock_user(p, arg2, ret);
3254 break;
3255 case TARGET_NR_write:
3256 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
3257 goto efault;
3258 ret = get_errno(write(arg1, p, arg3));
3259 unlock_user(p, arg2, 0);
3260 break;
3261 case TARGET_NR_open:
3262 if (!(p = lock_user_string(arg1)))
3263 goto efault;
3264 ret = get_errno(open(path(p),
3265 target_to_host_bitmask(arg2, fcntl_flags_tbl),
3266 arg3));
3267 unlock_user(p, arg1, 0);
3268 break;
3269 #if defined(TARGET_NR_openat) && defined(__NR_openat)
3270 case TARGET_NR_openat:
3271 if (!(p = lock_user_string(arg2)))
3272 goto efault;
3273 ret = get_errno(sys_openat(arg1,
3274 path(p),
3275 target_to_host_bitmask(arg3, fcntl_flags_tbl),
3276 arg4));
3277 unlock_user(p, arg2, 0);
3278 break;
3279 #endif
3280 case TARGET_NR_close:
3281 ret = get_errno(close(arg1));
3282 break;
3283 case TARGET_NR_brk:
3284 ret = do_brk(arg1);
3285 break;
3286 case TARGET_NR_fork:
3287 ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
3288 break;
3289 #ifdef TARGET_NR_waitpid
3290 case TARGET_NR_waitpid:
3292 int status;
3293 ret = get_errno(waitpid(arg1, &status, arg3));
3294 if (!is_error(ret) && arg2
3295 && put_user_s32(status, arg2))
3296 goto efault;
3298 break;
3299 #endif
3300 #ifdef TARGET_NR_waitid
3301 case TARGET_NR_waitid:
3303 siginfo_t info;
3304 info.si_pid = 0;
3305 ret = get_errno(waitid(arg1, arg2, &info, arg4));
3306 if (!is_error(ret) && arg3 && info.si_pid != 0) {
3307 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
3308 goto efault;
3309 host_to_target_siginfo(p, &info);
3310 unlock_user(p, arg3, sizeof(target_siginfo_t));
3313 break;
3314 #endif
3315 #ifdef TARGET_NR_creat /* not on alpha */
3316 case TARGET_NR_creat:
3317 if (!(p = lock_user_string(arg1)))
3318 goto efault;
3319 ret = get_errno(creat(p, arg2));
3320 unlock_user(p, arg1, 0);
3321 break;
3322 #endif
3323 case TARGET_NR_link:
3325 void * p2;
3326 p = lock_user_string(arg1);
3327 p2 = lock_user_string(arg2);
3328 if (!p || !p2)
3329 ret = -TARGET_EFAULT;
3330 else
3331 ret = get_errno(link(p, p2));
3332 unlock_user(p2, arg2, 0);
3333 unlock_user(p, arg1, 0);
3335 break;
3336 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
3337 case TARGET_NR_linkat:
3339 void * p2 = NULL;
3340 if (!arg2 || !arg4)
3341 goto efault;
3342 p = lock_user_string(arg2);
3343 p2 = lock_user_string(arg4);
3344 if (!p || !p2)
3345 ret = -TARGET_EFAULT;
3346 else
3347 ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
3348 unlock_user(p, arg2, 0);
3349 unlock_user(p2, arg4, 0);
3351 break;
3352 #endif
3353 case TARGET_NR_unlink:
3354 if (!(p = lock_user_string(arg1)))
3355 goto efault;
3356 ret = get_errno(unlink(p));
3357 unlock_user(p, arg1, 0);
3358 break;
3359 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
3360 case TARGET_NR_unlinkat:
3361 if (!(p = lock_user_string(arg2)))
3362 goto efault;
3363 ret = get_errno(sys_unlinkat(arg1, p, arg3));
3364 unlock_user(p, arg2, 0);
3365 break;
3366 #endif
3367 case TARGET_NR_execve:
3369 char **argp, **envp;
3370 int argc, envc;
3371 abi_ulong gp;
3372 abi_ulong guest_argp;
3373 abi_ulong guest_envp;
3374 abi_ulong addr;
3375 char **q;
3377 argc = 0;
3378 guest_argp = arg2;
3379 for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
3380 if (get_user_ual(addr, gp))
3381 goto efault;
3382 if (!addr)
3383 break;
3384 argc++;
3386 envc = 0;
3387 guest_envp = arg3;
3388 for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
3389 if (get_user_ual(addr, gp))
3390 goto efault;
3391 if (!addr)
3392 break;
3393 envc++;
3396 argp = alloca((argc + 1) * sizeof(void *));
3397 envp = alloca((envc + 1) * sizeof(void *));
3399 for (gp = guest_argp, q = argp; gp;
3400 gp += sizeof(abi_ulong), q++) {
3401 if (get_user_ual(addr, gp))
3402 goto execve_efault;
3403 if (!addr)
3404 break;
3405 if (!(*q = lock_user_string(addr)))
3406 goto execve_efault;
3408 *q = NULL;
3410 for (gp = guest_envp, q = envp; gp;
3411 gp += sizeof(abi_ulong), q++) {
3412 if (get_user_ual(addr, gp))
3413 goto execve_efault;
3414 if (!addr)
3415 break;
3416 if (!(*q = lock_user_string(addr)))
3417 goto execve_efault;
3419 *q = NULL;
3421 if (!(p = lock_user_string(arg1)))
3422 goto execve_efault;
3423 ret = get_errno(execve(p, argp, envp));
3424 unlock_user(p, arg1, 0);
3426 goto execve_end;
3428 execve_efault:
3429 ret = -TARGET_EFAULT;
3431 execve_end:
3432 for (gp = guest_argp, q = argp; *q;
3433 gp += sizeof(abi_ulong), q++) {
3434 if (get_user_ual(addr, gp)
3435 || !addr)
3436 break;
3437 unlock_user(*q, addr, 0);
3439 for (gp = guest_envp, q = envp; *q;
3440 gp += sizeof(abi_ulong), q++) {
3441 if (get_user_ual(addr, gp)
3442 || !addr)
3443 break;
3444 unlock_user(*q, addr, 0);
3447 break;
3448 case TARGET_NR_chdir:
3449 if (!(p = lock_user_string(arg1)))
3450 goto efault;
3451 ret = get_errno(chdir(p));
3452 unlock_user(p, arg1, 0);
3453 break;
3454 #ifdef TARGET_NR_time
3455 case TARGET_NR_time:
3457 time_t host_time;
3458 ret = get_errno(time(&host_time));
3459 if (!is_error(ret)
3460 && arg1
3461 && put_user_sal(host_time, arg1))
3462 goto efault;
3464 break;
3465 #endif
3466 case TARGET_NR_mknod:
3467 if (!(p = lock_user_string(arg1)))
3468 goto efault;
3469 ret = get_errno(mknod(p, arg2, arg3));
3470 unlock_user(p, arg1, 0);
3471 break;
3472 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
3473 case TARGET_NR_mknodat:
3474 if (!(p = lock_user_string(arg2)))
3475 goto efault;
3476 ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
3477 unlock_user(p, arg2, 0);
3478 break;
3479 #endif
3480 case TARGET_NR_chmod:
3481 if (!(p = lock_user_string(arg1)))
3482 goto efault;
3483 ret = get_errno(chmod(p, arg2));
3484 unlock_user(p, arg1, 0);
3485 break;
3486 #ifdef TARGET_NR_break
3487 case TARGET_NR_break:
3488 goto unimplemented;
3489 #endif
3490 #ifdef TARGET_NR_oldstat
3491 case TARGET_NR_oldstat:
3492 goto unimplemented;
3493 #endif
3494 case TARGET_NR_lseek:
3495 ret = get_errno(lseek(arg1, arg2, arg3));
3496 break;
3497 #ifdef TARGET_NR_getxpid
3498 case TARGET_NR_getxpid:
3499 #else
3500 case TARGET_NR_getpid:
3501 #endif
3502 ret = get_errno(getpid());
3503 break;
3504 case TARGET_NR_mount:
3506 /* need to look at the data field */
3507 void *p2, *p3;
3508 p = lock_user_string(arg1);
3509 p2 = lock_user_string(arg2);
3510 p3 = lock_user_string(arg3);
3511 if (!p || !p2 || !p3)
3512 ret = -TARGET_EFAULT;
3513 else
3514 /* FIXME - arg5 should be locked, but it isn't clear how to
3515 * do that since it's not guaranteed to be a NULL-terminated
3516 * string.
3518 ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
3519 unlock_user(p, arg1, 0);
3520 unlock_user(p2, arg2, 0);
3521 unlock_user(p3, arg3, 0);
3522 break;
3524 #ifdef TARGET_NR_umount
3525 case TARGET_NR_umount:
3526 if (!(p = lock_user_string(arg1)))
3527 goto efault;
3528 ret = get_errno(umount(p));
3529 unlock_user(p, arg1, 0);
3530 break;
3531 #endif
3532 #ifdef TARGET_NR_stime /* not on alpha */
3533 case TARGET_NR_stime:
3535 time_t host_time;
3536 if (get_user_sal(host_time, arg1))
3537 goto efault;
3538 ret = get_errno(stime(&host_time));
3540 break;
3541 #endif
3542 case TARGET_NR_ptrace:
3543 goto unimplemented;
3544 #ifdef TARGET_NR_alarm /* not on alpha */
3545 case TARGET_NR_alarm:
3546 ret = alarm(arg1);
3547 break;
3548 #endif
3549 #ifdef TARGET_NR_oldfstat
3550 case TARGET_NR_oldfstat:
3551 goto unimplemented;
3552 #endif
3553 #ifdef TARGET_NR_pause /* not on alpha */
3554 case TARGET_NR_pause:
3555 ret = get_errno(pause());
3556 break;
3557 #endif
3558 #ifdef TARGET_NR_utime
3559 case TARGET_NR_utime:
3561 struct utimbuf tbuf, *host_tbuf;
3562 struct target_utimbuf *target_tbuf;
3563 if (arg2) {
3564 if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
3565 goto efault;
3566 tbuf.actime = tswapl(target_tbuf->actime);
3567 tbuf.modtime = tswapl(target_tbuf->modtime);
3568 unlock_user_struct(target_tbuf, arg2, 0);
3569 host_tbuf = &tbuf;
3570 } else {
3571 host_tbuf = NULL;
3573 if (!(p = lock_user_string(arg1)))
3574 goto efault;
3575 ret = get_errno(utime(p, host_tbuf));
3576 unlock_user(p, arg1, 0);
3578 break;
3579 #endif
3580 case TARGET_NR_utimes:
3582 struct timeval *tvp, tv[2];
3583 if (arg2) {
3584 if (copy_from_user_timeval(&tv[0], arg2)
3585 || copy_from_user_timeval(&tv[1],
3586 arg2 + sizeof(struct target_timeval)))
3587 goto efault;
3588 tvp = tv;
3589 } else {
3590 tvp = NULL;
3592 if (!(p = lock_user_string(arg1)))
3593 goto efault;
3594 ret = get_errno(utimes(p, tvp));
3595 unlock_user(p, arg1, 0);
3597 break;
3598 #ifdef TARGET_NR_stty
3599 case TARGET_NR_stty:
3600 goto unimplemented;
3601 #endif
3602 #ifdef TARGET_NR_gtty
3603 case TARGET_NR_gtty:
3604 goto unimplemented;
3605 #endif
3606 case TARGET_NR_access:
3607 if (!(p = lock_user_string(arg1)))
3608 goto efault;
3609 ret = get_errno(access(p, arg2));
3610 unlock_user(p, arg1, 0);
3611 break;
3612 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
3613 case TARGET_NR_faccessat:
3614 if (!(p = lock_user_string(arg2)))
3615 goto efault;
3616 ret = get_errno(sys_faccessat(arg1, p, arg3, arg4));
3617 unlock_user(p, arg2, 0);
3618 break;
3619 #endif
3620 #ifdef TARGET_NR_nice /* not on alpha */
3621 case TARGET_NR_nice:
3622 ret = get_errno(nice(arg1));
3623 break;
3624 #endif
3625 #ifdef TARGET_NR_ftime
3626 case TARGET_NR_ftime:
3627 goto unimplemented;
3628 #endif
3629 case TARGET_NR_sync:
3630 sync();
3631 ret = 0;
3632 break;
3633 case TARGET_NR_kill:
3634 ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
3635 break;
3636 case TARGET_NR_rename:
3638 void *p2;
3639 p = lock_user_string(arg1);
3640 p2 = lock_user_string(arg2);
3641 if (!p || !p2)
3642 ret = -TARGET_EFAULT;
3643 else
3644 ret = get_errno(rename(p, p2));
3645 unlock_user(p2, arg2, 0);
3646 unlock_user(p, arg1, 0);
3648 break;
3649 #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
3650 case TARGET_NR_renameat:
3652 void *p2;
3653 p = lock_user_string(arg2);
3654 p2 = lock_user_string(arg4);
3655 if (!p || !p2)
3656 ret = -TARGET_EFAULT;
3657 else
3658 ret = get_errno(sys_renameat(arg1, p, arg3, p2));
3659 unlock_user(p2, arg4, 0);
3660 unlock_user(p, arg2, 0);
3662 break;
3663 #endif
3664 case TARGET_NR_mkdir:
3665 if (!(p = lock_user_string(arg1)))
3666 goto efault;
3667 ret = get_errno(mkdir(p, arg2));
3668 unlock_user(p, arg1, 0);
3669 break;
3670 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
3671 case TARGET_NR_mkdirat:
3672 if (!(p = lock_user_string(arg2)))
3673 goto efault;
3674 ret = get_errno(sys_mkdirat(arg1, p, arg3));
3675 unlock_user(p, arg2, 0);
3676 break;
3677 #endif
3678 case TARGET_NR_rmdir:
3679 if (!(p = lock_user_string(arg1)))
3680 goto efault;
3681 ret = get_errno(rmdir(p));
3682 unlock_user(p, arg1, 0);
3683 break;
3684 case TARGET_NR_dup:
3685 ret = get_errno(dup(arg1));
3686 break;
3687 case TARGET_NR_pipe:
3689 int host_pipe[2];
3690 ret = get_errno(pipe(host_pipe));
3691 if (!is_error(ret)) {
3692 #if defined(TARGET_MIPS)
3693 CPUMIPSState *env = (CPUMIPSState*)cpu_env;
3694 env->active_tc.gpr[3] = host_pipe[1];
3695 ret = host_pipe[0];
3696 #elif defined(TARGET_SH4)
3697 ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
3698 ret = host_pipe[0];
3699 #else
3700 if (put_user_s32(host_pipe[0], arg1)
3701 || put_user_s32(host_pipe[1], arg1 + sizeof(host_pipe[0])))
3702 goto efault;
3703 #endif
3706 break;
3707 case TARGET_NR_times:
3709 struct target_tms *tmsp;
3710 struct tms tms;
3711 ret = get_errno(times(&tms));
3712 if (arg1) {
3713 tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
3714 if (!tmsp)
3715 goto efault;
3716 tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
3717 tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
3718 tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
3719 tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime));
3721 if (!is_error(ret))
3722 ret = host_to_target_clock_t(ret);
3724 break;
3725 #ifdef TARGET_NR_prof
3726 case TARGET_NR_prof:
3727 goto unimplemented;
3728 #endif
3729 #ifdef TARGET_NR_signal
3730 case TARGET_NR_signal:
3731 goto unimplemented;
3732 #endif
3733 case TARGET_NR_acct:
3734 if (!(p = lock_user_string(arg1)))
3735 goto efault;
3736 ret = get_errno(acct(path(p)));
3737 unlock_user(p, arg1, 0);
3738 break;
3739 #ifdef TARGET_NR_umount2 /* not on alpha */
3740 case TARGET_NR_umount2:
3741 if (!(p = lock_user_string(arg1)))
3742 goto efault;
3743 ret = get_errno(umount2(p, arg2));
3744 unlock_user(p, arg1, 0);
3745 break;
3746 #endif
3747 #ifdef TARGET_NR_lock
3748 case TARGET_NR_lock:
3749 goto unimplemented;
3750 #endif
3751 case TARGET_NR_ioctl:
3752 ret = do_ioctl(arg1, arg2, arg3);
3753 break;
3754 case TARGET_NR_fcntl:
3755 ret = do_fcntl(arg1, arg2, arg3);
3756 break;
3757 #ifdef TARGET_NR_mpx
3758 case TARGET_NR_mpx:
3759 goto unimplemented;
3760 #endif
3761 case TARGET_NR_setpgid:
3762 ret = get_errno(setpgid(arg1, arg2));
3763 break;
3764 #ifdef TARGET_NR_ulimit
3765 case TARGET_NR_ulimit:
3766 goto unimplemented;
3767 #endif
3768 #ifdef TARGET_NR_oldolduname
3769 case TARGET_NR_oldolduname:
3770 goto unimplemented;
3771 #endif
3772 case TARGET_NR_umask:
3773 ret = get_errno(umask(arg1));
3774 break;
3775 case TARGET_NR_chroot:
3776 if (!(p = lock_user_string(arg1)))
3777 goto efault;
3778 ret = get_errno(chroot(p));
3779 unlock_user(p, arg1, 0);
3780 break;
3781 case TARGET_NR_ustat:
3782 goto unimplemented;
3783 case TARGET_NR_dup2:
3784 ret = get_errno(dup2(arg1, arg2));
3785 break;
3786 #ifdef TARGET_NR_getppid /* not on alpha */
3787 case TARGET_NR_getppid:
3788 ret = get_errno(getppid());
3789 break;
3790 #endif
3791 case TARGET_NR_getpgrp:
3792 ret = get_errno(getpgrp());
3793 break;
3794 case TARGET_NR_setsid:
3795 ret = get_errno(setsid());
3796 break;
3797 #ifdef TARGET_NR_sigaction
3798 case TARGET_NR_sigaction:
3800 #if !defined(TARGET_MIPS)
3801 struct target_old_sigaction *old_act;
3802 struct target_sigaction act, oact, *pact;
3803 if (arg2) {
3804 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
3805 goto efault;
3806 act._sa_handler = old_act->_sa_handler;
3807 target_siginitset(&act.sa_mask, old_act->sa_mask);
3808 act.sa_flags = old_act->sa_flags;
3809 act.sa_restorer = old_act->sa_restorer;
3810 unlock_user_struct(old_act, arg2, 0);
3811 pact = &act;
3812 } else {
3813 pact = NULL;
3815 ret = get_errno(do_sigaction(arg1, pact, &oact));
3816 if (!is_error(ret) && arg3) {
3817 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
3818 goto efault;
3819 old_act->_sa_handler = oact._sa_handler;
3820 old_act->sa_mask = oact.sa_mask.sig[0];
3821 old_act->sa_flags = oact.sa_flags;
3822 old_act->sa_restorer = oact.sa_restorer;
3823 unlock_user_struct(old_act, arg3, 1);
3825 #else
3826 struct target_sigaction act, oact, *pact, *old_act;
3828 if (arg2) {
3829 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
3830 goto efault;
3831 act._sa_handler = old_act->_sa_handler;
3832 target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
3833 act.sa_flags = old_act->sa_flags;
3834 unlock_user_struct(old_act, arg2, 0);
3835 pact = &act;
3836 } else {
3837 pact = NULL;
3840 ret = get_errno(do_sigaction(arg1, pact, &oact));
3842 if (!is_error(ret) && arg3) {
3843 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
3844 goto efault;
3845 old_act->_sa_handler = oact._sa_handler;
3846 old_act->sa_flags = oact.sa_flags;
3847 old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
3848 old_act->sa_mask.sig[1] = 0;
3849 old_act->sa_mask.sig[2] = 0;
3850 old_act->sa_mask.sig[3] = 0;
3851 unlock_user_struct(old_act, arg3, 1);
3853 #endif
3855 break;
3856 #endif
3857 case TARGET_NR_rt_sigaction:
3859 struct target_sigaction *act;
3860 struct target_sigaction *oact;
3862 if (arg2) {
3863 if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
3864 goto efault;
3865 } else
3866 act = NULL;
3867 if (arg3) {
3868 if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
3869 ret = -TARGET_EFAULT;
3870 goto rt_sigaction_fail;
3872 } else
3873 oact = NULL;
3874 ret = get_errno(do_sigaction(arg1, act, oact));
3875 rt_sigaction_fail:
3876 if (act)
3877 unlock_user_struct(act, arg2, 0);
3878 if (oact)
3879 unlock_user_struct(oact, arg3, 1);
3881 break;
3882 #ifdef TARGET_NR_sgetmask /* not on alpha */
3883 case TARGET_NR_sgetmask:
3885 sigset_t cur_set;
3886 abi_ulong target_set;
3887 sigprocmask(0, NULL, &cur_set);
3888 host_to_target_old_sigset(&target_set, &cur_set);
3889 ret = target_set;
3891 break;
3892 #endif
3893 #ifdef TARGET_NR_ssetmask /* not on alpha */
3894 case TARGET_NR_ssetmask:
3896 sigset_t set, oset, cur_set;
3897 abi_ulong target_set = arg1;
3898 sigprocmask(0, NULL, &cur_set);
3899 target_to_host_old_sigset(&set, &target_set);
3900 sigorset(&set, &set, &cur_set);
3901 sigprocmask(SIG_SETMASK, &set, &oset);
3902 host_to_target_old_sigset(&target_set, &oset);
3903 ret = target_set;
3905 break;
3906 #endif
3907 #ifdef TARGET_NR_sigprocmask
3908 case TARGET_NR_sigprocmask:
3910 int how = arg1;
3911 sigset_t set, oldset, *set_ptr;
3913 if (arg2) {
3914 switch(how) {
3915 case TARGET_SIG_BLOCK:
3916 how = SIG_BLOCK;
3917 break;
3918 case TARGET_SIG_UNBLOCK:
3919 how = SIG_UNBLOCK;
3920 break;
3921 case TARGET_SIG_SETMASK:
3922 how = SIG_SETMASK;
3923 break;
3924 default:
3925 ret = -TARGET_EINVAL;
3926 goto fail;
3928 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
3929 goto efault;
3930 target_to_host_old_sigset(&set, p);
3931 unlock_user(p, arg2, 0);
3932 set_ptr = &set;
3933 } else {
3934 how = 0;
3935 set_ptr = NULL;
3937 ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
3938 if (!is_error(ret) && arg3) {
3939 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
3940 goto efault;
3941 host_to_target_old_sigset(p, &oldset);
3942 unlock_user(p, arg3, sizeof(target_sigset_t));
3945 break;
3946 #endif
3947 case TARGET_NR_rt_sigprocmask:
3949 int how = arg1;
3950 sigset_t set, oldset, *set_ptr;
3952 if (arg2) {
3953 switch(how) {
3954 case TARGET_SIG_BLOCK:
3955 how = SIG_BLOCK;
3956 break;
3957 case TARGET_SIG_UNBLOCK:
3958 how = SIG_UNBLOCK;
3959 break;
3960 case TARGET_SIG_SETMASK:
3961 how = SIG_SETMASK;
3962 break;
3963 default:
3964 ret = -TARGET_EINVAL;
3965 goto fail;
3967 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
3968 goto efault;
3969 target_to_host_sigset(&set, p);
3970 unlock_user(p, arg2, 0);
3971 set_ptr = &set;
3972 } else {
3973 how = 0;
3974 set_ptr = NULL;
3976 ret = get_errno(sigprocmask(how, set_ptr, &oldset));
3977 if (!is_error(ret) && arg3) {
3978 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
3979 goto efault;
3980 host_to_target_sigset(p, &oldset);
3981 unlock_user(p, arg3, sizeof(target_sigset_t));
3984 break;
3985 #ifdef TARGET_NR_sigpending
3986 case TARGET_NR_sigpending:
3988 sigset_t set;
3989 ret = get_errno(sigpending(&set));
3990 if (!is_error(ret)) {
3991 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
3992 goto efault;
3993 host_to_target_old_sigset(p, &set);
3994 unlock_user(p, arg1, sizeof(target_sigset_t));
3997 break;
3998 #endif
3999 case TARGET_NR_rt_sigpending:
4001 sigset_t set;
4002 ret = get_errno(sigpending(&set));
4003 if (!is_error(ret)) {
4004 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4005 goto efault;
4006 host_to_target_sigset(p, &set);
4007 unlock_user(p, arg1, sizeof(target_sigset_t));
4010 break;
4011 #ifdef TARGET_NR_sigsuspend
4012 case TARGET_NR_sigsuspend:
4014 sigset_t set;
4015 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4016 goto efault;
4017 target_to_host_old_sigset(&set, p);
4018 unlock_user(p, arg1, 0);
4019 ret = get_errno(sigsuspend(&set));
4021 break;
4022 #endif
4023 case TARGET_NR_rt_sigsuspend:
4025 sigset_t set;
4026 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4027 goto efault;
4028 target_to_host_sigset(&set, p);
4029 unlock_user(p, arg1, 0);
4030 ret = get_errno(sigsuspend(&set));
4032 break;
4033 case TARGET_NR_rt_sigtimedwait:
4035 sigset_t set;
4036 struct timespec uts, *puts;
4037 siginfo_t uinfo;
4039 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4040 goto efault;
4041 target_to_host_sigset(&set, p);
4042 unlock_user(p, arg1, 0);
4043 if (arg3) {
4044 puts = &uts;
4045 target_to_host_timespec(puts, arg3);
4046 } else {
4047 puts = NULL;
4049 ret = get_errno(sigtimedwait(&set, &uinfo, puts));
4050 if (!is_error(ret) && arg2) {
4051 if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
4052 goto efault;
4053 host_to_target_siginfo(p, &uinfo);
4054 unlock_user(p, arg2, sizeof(target_siginfo_t));
4057 break;
4058 case TARGET_NR_rt_sigqueueinfo:
4060 siginfo_t uinfo;
4061 if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
4062 goto efault;
4063 target_to_host_siginfo(&uinfo, p);
4064 unlock_user(p, arg1, 0);
4065 ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
4067 break;
4068 #ifdef TARGET_NR_sigreturn
4069 case TARGET_NR_sigreturn:
4070 /* NOTE: ret is eax, so not transcoding must be done */
4071 ret = do_sigreturn(cpu_env);
4072 break;
4073 #endif
4074 case TARGET_NR_rt_sigreturn:
4075 /* NOTE: ret is eax, so not transcoding must be done */
4076 ret = do_rt_sigreturn(cpu_env);
4077 break;
4078 case TARGET_NR_sethostname:
4079 if (!(p = lock_user_string(arg1)))
4080 goto efault;
4081 ret = get_errno(sethostname(p, arg2));
4082 unlock_user(p, arg1, 0);
4083 break;
4084 case TARGET_NR_setrlimit:
4086 /* XXX: convert resource ? */
4087 int resource = arg1;
4088 struct target_rlimit *target_rlim;
4089 struct rlimit rlim;
4090 if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
4091 goto efault;
4092 rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4093 rlim.rlim_max = tswapl(target_rlim->rlim_max);
4094 unlock_user_struct(target_rlim, arg2, 0);
4095 ret = get_errno(setrlimit(resource, &rlim));
4097 break;
4098 case TARGET_NR_getrlimit:
4100 /* XXX: convert resource ? */
4101 int resource = arg1;
4102 struct target_rlimit *target_rlim;
4103 struct rlimit rlim;
4105 ret = get_errno(getrlimit(resource, &rlim));
4106 if (!is_error(ret)) {
4107 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
4108 goto efault;
4109 rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4110 rlim.rlim_max = tswapl(target_rlim->rlim_max);
4111 unlock_user_struct(target_rlim, arg2, 1);
4114 break;
4115 case TARGET_NR_getrusage:
4117 struct rusage rusage;
4118 ret = get_errno(getrusage(arg1, &rusage));
4119 if (!is_error(ret)) {
4120 host_to_target_rusage(arg2, &rusage);
4123 break;
4124 case TARGET_NR_gettimeofday:
4126 struct timeval tv;
4127 ret = get_errno(gettimeofday(&tv, NULL));
4128 if (!is_error(ret)) {
4129 if (copy_to_user_timeval(arg1, &tv))
4130 goto efault;
4133 break;
4134 case TARGET_NR_settimeofday:
4136 struct timeval tv;
4137 if (copy_from_user_timeval(&tv, arg1))
4138 goto efault;
4139 ret = get_errno(settimeofday(&tv, NULL));
4141 break;
4142 #ifdef TARGET_NR_select
4143 case TARGET_NR_select:
4145 struct target_sel_arg_struct *sel;
4146 abi_ulong inp, outp, exp, tvp;
4147 long nsel;
4149 if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
4150 goto efault;
4151 nsel = tswapl(sel->n);
4152 inp = tswapl(sel->inp);
4153 outp = tswapl(sel->outp);
4154 exp = tswapl(sel->exp);
4155 tvp = tswapl(sel->tvp);
4156 unlock_user_struct(sel, arg1, 0);
4157 ret = do_select(nsel, inp, outp, exp, tvp);
4159 break;
4160 #endif
4161 case TARGET_NR_symlink:
4163 void *p2;
4164 p = lock_user_string(arg1);
4165 p2 = lock_user_string(arg2);
4166 if (!p || !p2)
4167 ret = -TARGET_EFAULT;
4168 else
4169 ret = get_errno(symlink(p, p2));
4170 unlock_user(p2, arg2, 0);
4171 unlock_user(p, arg1, 0);
4173 break;
4174 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
4175 case TARGET_NR_symlinkat:
4177 void *p2;
4178 p = lock_user_string(arg1);
4179 p2 = lock_user_string(arg3);
4180 if (!p || !p2)
4181 ret = -TARGET_EFAULT;
4182 else
4183 ret = get_errno(sys_symlinkat(p, arg2, p2));
4184 unlock_user(p2, arg3, 0);
4185 unlock_user(p, arg1, 0);
4187 break;
4188 #endif
4189 #ifdef TARGET_NR_oldlstat
4190 case TARGET_NR_oldlstat:
4191 goto unimplemented;
4192 #endif
4193 case TARGET_NR_readlink:
4195 void *p2;
4196 p = lock_user_string(arg1);
4197 p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
4198 if (!p || !p2)
4199 ret = -TARGET_EFAULT;
4200 else
4201 ret = get_errno(readlink(path(p), p2, arg3));
4202 unlock_user(p2, arg2, ret);
4203 unlock_user(p, arg1, 0);
4205 break;
4206 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
4207 case TARGET_NR_readlinkat:
4209 void *p2;
4210 p = lock_user_string(arg2);
4211 p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
4212 if (!p || !p2)
4213 ret = -TARGET_EFAULT;
4214 else
4215 ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
4216 unlock_user(p2, arg3, ret);
4217 unlock_user(p, arg2, 0);
4219 break;
4220 #endif
4221 #ifdef TARGET_NR_uselib
4222 case TARGET_NR_uselib:
4223 goto unimplemented;
4224 #endif
4225 #ifdef TARGET_NR_swapon
4226 case TARGET_NR_swapon:
4227 if (!(p = lock_user_string(arg1)))
4228 goto efault;
4229 ret = get_errno(swapon(p, arg2));
4230 unlock_user(p, arg1, 0);
4231 break;
4232 #endif
4233 case TARGET_NR_reboot:
4234 goto unimplemented;
4235 #ifdef TARGET_NR_readdir
4236 case TARGET_NR_readdir:
4237 goto unimplemented;
4238 #endif
4239 #ifdef TARGET_NR_mmap
4240 case TARGET_NR_mmap:
4241 #if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS)
4243 abi_ulong *v;
4244 abi_ulong v1, v2, v3, v4, v5, v6;
4245 if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
4246 goto efault;
4247 v1 = tswapl(v[0]);
4248 v2 = tswapl(v[1]);
4249 v3 = tswapl(v[2]);
4250 v4 = tswapl(v[3]);
4251 v5 = tswapl(v[4]);
4252 v6 = tswapl(v[5]);
4253 unlock_user(v, arg1, 0);
4254 ret = get_errno(target_mmap(v1, v2, v3,
4255 target_to_host_bitmask(v4, mmap_flags_tbl),
4256 v5, v6));
4258 #else
4259 ret = get_errno(target_mmap(arg1, arg2, arg3,
4260 target_to_host_bitmask(arg4, mmap_flags_tbl),
4261 arg5,
4262 arg6));
4263 #endif
4264 break;
4265 #endif
4266 #ifdef TARGET_NR_mmap2
4267 case TARGET_NR_mmap2:
4268 #ifndef MMAP_SHIFT
4269 #define MMAP_SHIFT 12
4270 #endif
4271 ret = get_errno(target_mmap(arg1, arg2, arg3,
4272 target_to_host_bitmask(arg4, mmap_flags_tbl),
4273 arg5,
4274 arg6 << MMAP_SHIFT));
4275 break;
4276 #endif
4277 case TARGET_NR_munmap:
4278 ret = get_errno(target_munmap(arg1, arg2));
4279 break;
4280 case TARGET_NR_mprotect:
4281 ret = get_errno(target_mprotect(arg1, arg2, arg3));
4282 break;
4283 #ifdef TARGET_NR_mremap
4284 case TARGET_NR_mremap:
4285 ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
4286 break;
4287 #endif
4288 /* ??? msync/mlock/munlock are broken for softmmu. */
4289 #ifdef TARGET_NR_msync
4290 case TARGET_NR_msync:
4291 ret = get_errno(msync(g2h(arg1), arg2, arg3));
4292 break;
4293 #endif
4294 #ifdef TARGET_NR_mlock
4295 case TARGET_NR_mlock:
4296 ret = get_errno(mlock(g2h(arg1), arg2));
4297 break;
4298 #endif
4299 #ifdef TARGET_NR_munlock
4300 case TARGET_NR_munlock:
4301 ret = get_errno(munlock(g2h(arg1), arg2));
4302 break;
4303 #endif
4304 #ifdef TARGET_NR_mlockall
4305 case TARGET_NR_mlockall:
4306 ret = get_errno(mlockall(arg1));
4307 break;
4308 #endif
4309 #ifdef TARGET_NR_munlockall
4310 case TARGET_NR_munlockall:
4311 ret = get_errno(munlockall());
4312 break;
4313 #endif
4314 case TARGET_NR_truncate:
4315 if (!(p = lock_user_string(arg1)))
4316 goto efault;
4317 ret = get_errno(truncate(p, arg2));
4318 unlock_user(p, arg1, 0);
4319 break;
4320 case TARGET_NR_ftruncate:
4321 ret = get_errno(ftruncate(arg1, arg2));
4322 break;
4323 case TARGET_NR_fchmod:
4324 ret = get_errno(fchmod(arg1, arg2));
4325 break;
4326 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
4327 case TARGET_NR_fchmodat:
4328 if (!(p = lock_user_string(arg2)))
4329 goto efault;
4330 ret = get_errno(sys_fchmodat(arg1, p, arg3, arg4));
4331 unlock_user(p, arg2, 0);
4332 break;
4333 #endif
4334 case TARGET_NR_getpriority:
4335 /* libc does special remapping of the return value of
4336 * sys_getpriority() so it's just easiest to call
4337 * sys_getpriority() directly rather than through libc. */
4338 ret = sys_getpriority(arg1, arg2);
4339 break;
4340 case TARGET_NR_setpriority:
4341 ret = get_errno(setpriority(arg1, arg2, arg3));
4342 break;
4343 #ifdef TARGET_NR_profil
4344 case TARGET_NR_profil:
4345 goto unimplemented;
4346 #endif
4347 case TARGET_NR_statfs:
4348 if (!(p = lock_user_string(arg1)))
4349 goto efault;
4350 ret = get_errno(statfs(path(p), &stfs));
4351 unlock_user(p, arg1, 0);
4352 convert_statfs:
4353 if (!is_error(ret)) {
4354 struct target_statfs *target_stfs;
4356 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
4357 goto efault;
4358 __put_user(stfs.f_type, &target_stfs->f_type);
4359 __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4360 __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4361 __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4362 __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4363 __put_user(stfs.f_files, &target_stfs->f_files);
4364 __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4365 __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4366 __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4367 __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4368 unlock_user_struct(target_stfs, arg2, 1);
4370 break;
4371 case TARGET_NR_fstatfs:
4372 ret = get_errno(fstatfs(arg1, &stfs));
4373 goto convert_statfs;
4374 #ifdef TARGET_NR_statfs64
4375 case TARGET_NR_statfs64:
4376 if (!(p = lock_user_string(arg1)))
4377 goto efault;
4378 ret = get_errno(statfs(path(p), &stfs));
4379 unlock_user(p, arg1, 0);
4380 convert_statfs64:
4381 if (!is_error(ret)) {
4382 struct target_statfs64 *target_stfs;
4384 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
4385 goto efault;
4386 __put_user(stfs.f_type, &target_stfs->f_type);
4387 __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4388 __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4389 __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4390 __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4391 __put_user(stfs.f_files, &target_stfs->f_files);
4392 __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4393 __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4394 __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4395 __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4396 unlock_user_struct(target_stfs, arg3, 1);
4398 break;
4399 case TARGET_NR_fstatfs64:
4400 ret = get_errno(fstatfs(arg1, &stfs));
4401 goto convert_statfs64;
4402 #endif
4403 #ifdef TARGET_NR_ioperm
4404 case TARGET_NR_ioperm:
4405 goto unimplemented;
4406 #endif
4407 #ifdef TARGET_NR_socketcall
4408 case TARGET_NR_socketcall:
4409 ret = do_socketcall(arg1, arg2);
4410 break;
4411 #endif
4412 #ifdef TARGET_NR_accept
4413 case TARGET_NR_accept:
4414 ret = do_accept(arg1, arg2, arg3);
4415 break;
4416 #endif
4417 #ifdef TARGET_NR_bind
4418 case TARGET_NR_bind:
4419 ret = do_bind(arg1, arg2, arg3);
4420 break;
4421 #endif
4422 #ifdef TARGET_NR_connect
4423 case TARGET_NR_connect:
4424 ret = do_connect(arg1, arg2, arg3);
4425 break;
4426 #endif
4427 #ifdef TARGET_NR_getpeername
4428 case TARGET_NR_getpeername:
4429 ret = do_getpeername(arg1, arg2, arg3);
4430 break;
4431 #endif
4432 #ifdef TARGET_NR_getsockname
4433 case TARGET_NR_getsockname:
4434 ret = do_getsockname(arg1, arg2, arg3);
4435 break;
4436 #endif
4437 #ifdef TARGET_NR_getsockopt
4438 case TARGET_NR_getsockopt:
4439 ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
4440 break;
4441 #endif
4442 #ifdef TARGET_NR_listen
4443 case TARGET_NR_listen:
4444 ret = get_errno(listen(arg1, arg2));
4445 break;
4446 #endif
4447 #ifdef TARGET_NR_recv
4448 case TARGET_NR_recv:
4449 ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
4450 break;
4451 #endif
4452 #ifdef TARGET_NR_recvfrom
4453 case TARGET_NR_recvfrom:
4454 ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
4455 break;
4456 #endif
4457 #ifdef TARGET_NR_recvmsg
4458 case TARGET_NR_recvmsg:
4459 ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
4460 break;
4461 #endif
4462 #ifdef TARGET_NR_send
4463 case TARGET_NR_send:
4464 ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
4465 break;
4466 #endif
4467 #ifdef TARGET_NR_sendmsg
4468 case TARGET_NR_sendmsg:
4469 ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
4470 break;
4471 #endif
4472 #ifdef TARGET_NR_sendto
4473 case TARGET_NR_sendto:
4474 ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
4475 break;
4476 #endif
4477 #ifdef TARGET_NR_shutdown
4478 case TARGET_NR_shutdown:
4479 ret = get_errno(shutdown(arg1, arg2));
4480 break;
4481 #endif
4482 #ifdef TARGET_NR_socket
4483 case TARGET_NR_socket:
4484 ret = do_socket(arg1, arg2, arg3);
4485 break;
4486 #endif
4487 #ifdef TARGET_NR_socketpair
4488 case TARGET_NR_socketpair:
4489 ret = do_socketpair(arg1, arg2, arg3, arg4);
4490 break;
4491 #endif
4492 #ifdef TARGET_NR_setsockopt
4493 case TARGET_NR_setsockopt:
4494 ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
4495 break;
4496 #endif
4498 case TARGET_NR_syslog:
4499 if (!(p = lock_user_string(arg2)))
4500 goto efault;
4501 ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
4502 unlock_user(p, arg2, 0);
4503 break;
4505 case TARGET_NR_setitimer:
4507 struct itimerval value, ovalue, *pvalue;
4509 if (arg2) {
4510 pvalue = &value;
4511 if (copy_from_user_timeval(&pvalue->it_interval, arg2)
4512 || copy_from_user_timeval(&pvalue->it_value,
4513 arg2 + sizeof(struct target_timeval)))
4514 goto efault;
4515 } else {
4516 pvalue = NULL;
4518 ret = get_errno(setitimer(arg1, pvalue, &ovalue));
4519 if (!is_error(ret) && arg3) {
4520 if (copy_to_user_timeval(arg3,
4521 &ovalue.it_interval)
4522 || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
4523 &ovalue.it_value))
4524 goto efault;
4527 break;
4528 case TARGET_NR_getitimer:
4530 struct itimerval value;
4532 ret = get_errno(getitimer(arg1, &value));
4533 if (!is_error(ret) && arg2) {
4534 if (copy_to_user_timeval(arg2,
4535 &value.it_interval)
4536 || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
4537 &value.it_value))
4538 goto efault;
4541 break;
4542 case TARGET_NR_stat:
4543 if (!(p = lock_user_string(arg1)))
4544 goto efault;
4545 ret = get_errno(stat(path(p), &st));
4546 unlock_user(p, arg1, 0);
4547 goto do_stat;
4548 case TARGET_NR_lstat:
4549 if (!(p = lock_user_string(arg1)))
4550 goto efault;
4551 ret = get_errno(lstat(path(p), &st));
4552 unlock_user(p, arg1, 0);
4553 goto do_stat;
4554 case TARGET_NR_fstat:
4556 ret = get_errno(fstat(arg1, &st));
4557 do_stat:
4558 if (!is_error(ret)) {
4559 struct target_stat *target_st;
4561 if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
4562 goto efault;
4563 __put_user(st.st_dev, &target_st->st_dev);
4564 __put_user(st.st_ino, &target_st->st_ino);
4565 __put_user(st.st_mode, &target_st->st_mode);
4566 __put_user(st.st_uid, &target_st->st_uid);
4567 __put_user(st.st_gid, &target_st->st_gid);
4568 __put_user(st.st_nlink, &target_st->st_nlink);
4569 __put_user(st.st_rdev, &target_st->st_rdev);
4570 __put_user(st.st_size, &target_st->st_size);
4571 __put_user(st.st_blksize, &target_st->st_blksize);
4572 __put_user(st.st_blocks, &target_st->st_blocks);
4573 __put_user(st.st_atime, &target_st->target_st_atime);
4574 __put_user(st.st_mtime, &target_st->target_st_mtime);
4575 __put_user(st.st_ctime, &target_st->target_st_ctime);
4576 unlock_user_struct(target_st, arg2, 1);
4579 break;
4580 #ifdef TARGET_NR_olduname
4581 case TARGET_NR_olduname:
4582 goto unimplemented;
4583 #endif
4584 #ifdef TARGET_NR_iopl
4585 case TARGET_NR_iopl:
4586 goto unimplemented;
4587 #endif
4588 case TARGET_NR_vhangup:
4589 ret = get_errno(vhangup());
4590 break;
4591 #ifdef TARGET_NR_idle
4592 case TARGET_NR_idle:
4593 goto unimplemented;
4594 #endif
4595 #ifdef TARGET_NR_syscall
4596 case TARGET_NR_syscall:
4597 ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
4598 break;
4599 #endif
4600 case TARGET_NR_wait4:
4602 int status;
4603 abi_long status_ptr = arg2;
4604 struct rusage rusage, *rusage_ptr;
4605 abi_ulong target_rusage = arg4;
4606 if (target_rusage)
4607 rusage_ptr = &rusage;
4608 else
4609 rusage_ptr = NULL;
4610 ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
4611 if (!is_error(ret)) {
4612 if (status_ptr) {
4613 if (put_user_s32(status, status_ptr))
4614 goto efault;
4616 if (target_rusage)
4617 host_to_target_rusage(target_rusage, &rusage);
4620 break;
4621 #ifdef TARGET_NR_swapoff
4622 case TARGET_NR_swapoff:
4623 if (!(p = lock_user_string(arg1)))
4624 goto efault;
4625 ret = get_errno(swapoff(p));
4626 unlock_user(p, arg1, 0);
4627 break;
4628 #endif
4629 case TARGET_NR_sysinfo:
4631 struct target_sysinfo *target_value;
4632 struct sysinfo value;
4633 ret = get_errno(sysinfo(&value));
4634 if (!is_error(ret) && arg1)
4636 if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
4637 goto efault;
4638 __put_user(value.uptime, &target_value->uptime);
4639 __put_user(value.loads[0], &target_value->loads[0]);
4640 __put_user(value.loads[1], &target_value->loads[1]);
4641 __put_user(value.loads[2], &target_value->loads[2]);
4642 __put_user(value.totalram, &target_value->totalram);
4643 __put_user(value.freeram, &target_value->freeram);
4644 __put_user(value.sharedram, &target_value->sharedram);
4645 __put_user(value.bufferram, &target_value->bufferram);
4646 __put_user(value.totalswap, &target_value->totalswap);
4647 __put_user(value.freeswap, &target_value->freeswap);
4648 __put_user(value.procs, &target_value->procs);
4649 __put_user(value.totalhigh, &target_value->totalhigh);
4650 __put_user(value.freehigh, &target_value->freehigh);
4651 __put_user(value.mem_unit, &target_value->mem_unit);
4652 unlock_user_struct(target_value, arg1, 1);
4655 break;
4656 #ifdef TARGET_NR_ipc
4657 case TARGET_NR_ipc:
4658 ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
4659 break;
4660 #endif
4661 case TARGET_NR_fsync:
4662 ret = get_errno(fsync(arg1));
4663 break;
4664 case TARGET_NR_clone:
4665 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
4666 break;
4667 #ifdef __NR_exit_group
4668 /* new thread calls */
4669 case TARGET_NR_exit_group:
4670 gdb_exit(cpu_env, arg1);
4671 ret = get_errno(exit_group(arg1));
4672 break;
4673 #endif
4674 case TARGET_NR_setdomainname:
4675 if (!(p = lock_user_string(arg1)))
4676 goto efault;
4677 ret = get_errno(setdomainname(p, arg2));
4678 unlock_user(p, arg1, 0);
4679 break;
4680 case TARGET_NR_uname:
4681 /* no need to transcode because we use the linux syscall */
4683 struct new_utsname * buf;
4685 if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
4686 goto efault;
4687 ret = get_errno(sys_uname(buf));
4688 if (!is_error(ret)) {
4689 /* Overrite the native machine name with whatever is being
4690 emulated. */
4691 strcpy (buf->machine, UNAME_MACHINE);
4692 /* Allow the user to override the reported release. */
4693 if (qemu_uname_release && *qemu_uname_release)
4694 strcpy (buf->release, qemu_uname_release);
4696 unlock_user_struct(buf, arg1, 1);
4698 break;
4699 #ifdef TARGET_I386
4700 case TARGET_NR_modify_ldt:
4701 ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
4702 break;
4703 #if !defined(TARGET_X86_64)
4704 case TARGET_NR_vm86old:
4705 goto unimplemented;
4706 case TARGET_NR_vm86:
4707 ret = do_vm86(cpu_env, arg1, arg2);
4708 break;
4709 #endif
4710 #endif
4711 case TARGET_NR_adjtimex:
4712 goto unimplemented;
4713 #ifdef TARGET_NR_create_module
4714 case TARGET_NR_create_module:
4715 #endif
4716 case TARGET_NR_init_module:
4717 case TARGET_NR_delete_module:
4718 #ifdef TARGET_NR_get_kernel_syms
4719 case TARGET_NR_get_kernel_syms:
4720 #endif
4721 goto unimplemented;
4722 case TARGET_NR_quotactl:
4723 goto unimplemented;
4724 case TARGET_NR_getpgid:
4725 ret = get_errno(getpgid(arg1));
4726 break;
4727 case TARGET_NR_fchdir:
4728 ret = get_errno(fchdir(arg1));
4729 break;
4730 #ifdef TARGET_NR_bdflush /* not on x86_64 */
4731 case TARGET_NR_bdflush:
4732 goto unimplemented;
4733 #endif
4734 #ifdef TARGET_NR_sysfs
4735 case TARGET_NR_sysfs:
4736 goto unimplemented;
4737 #endif
4738 case TARGET_NR_personality:
4739 ret = get_errno(personality(arg1));
4740 break;
4741 #ifdef TARGET_NR_afs_syscall
4742 case TARGET_NR_afs_syscall:
4743 goto unimplemented;
4744 #endif
4745 #ifdef TARGET_NR__llseek /* Not on alpha */
4746 case TARGET_NR__llseek:
4748 #if defined (__x86_64__)
4749 ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
4750 if (put_user_s64(ret, arg4))
4751 goto efault;
4752 #else
4753 int64_t res;
4754 ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
4755 if (put_user_s64(res, arg4))
4756 goto efault;
4757 #endif
4759 break;
4760 #endif
4761 case TARGET_NR_getdents:
4762 #if TARGET_ABI_BITS != 32
4763 goto unimplemented;
4764 #elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
4766 struct target_dirent *target_dirp;
4767 struct dirent *dirp;
4768 abi_long count = arg3;
4770 dirp = malloc(count);
4771 if (!dirp) {
4772 ret = -TARGET_ENOMEM;
4773 goto fail;
4776 ret = get_errno(sys_getdents(arg1, dirp, count));
4777 if (!is_error(ret)) {
4778 struct dirent *de;
4779 struct target_dirent *tde;
4780 int len = ret;
4781 int reclen, treclen;
4782 int count1, tnamelen;
4784 count1 = 0;
4785 de = dirp;
4786 if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4787 goto efault;
4788 tde = target_dirp;
4789 while (len > 0) {
4790 reclen = de->d_reclen;
4791 treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
4792 tde->d_reclen = tswap16(treclen);
4793 tde->d_ino = tswapl(de->d_ino);
4794 tde->d_off = tswapl(de->d_off);
4795 tnamelen = treclen - (2 * sizeof(abi_long) + 2);
4796 if (tnamelen > 256)
4797 tnamelen = 256;
4798 /* XXX: may not be correct */
4799 strncpy(tde->d_name, de->d_name, tnamelen);
4800 de = (struct dirent *)((char *)de + reclen);
4801 len -= reclen;
4802 tde = (struct target_dirent *)((char *)tde + treclen);
4803 count1 += treclen;
4805 ret = count1;
4806 unlock_user(target_dirp, arg2, ret);
4808 free(dirp);
4810 #else
4812 struct dirent *dirp;
4813 abi_long count = arg3;
4815 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4816 goto efault;
4817 ret = get_errno(sys_getdents(arg1, dirp, count));
4818 if (!is_error(ret)) {
4819 struct dirent *de;
4820 int len = ret;
4821 int reclen;
4822 de = dirp;
4823 while (len > 0) {
4824 reclen = de->d_reclen;
4825 if (reclen > len)
4826 break;
4827 de->d_reclen = tswap16(reclen);
4828 tswapls(&de->d_ino);
4829 tswapls(&de->d_off);
4830 de = (struct dirent *)((char *)de + reclen);
4831 len -= reclen;
4834 unlock_user(dirp, arg2, ret);
4836 #endif
4837 break;
4838 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
4839 case TARGET_NR_getdents64:
4841 struct dirent64 *dirp;
4842 abi_long count = arg3;
4843 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4844 goto efault;
4845 ret = get_errno(sys_getdents64(arg1, dirp, count));
4846 if (!is_error(ret)) {
4847 struct dirent64 *de;
4848 int len = ret;
4849 int reclen;
4850 de = dirp;
4851 while (len > 0) {
4852 reclen = de->d_reclen;
4853 if (reclen > len)
4854 break;
4855 de->d_reclen = tswap16(reclen);
4856 tswap64s((uint64_t *)&de->d_ino);
4857 tswap64s((uint64_t *)&de->d_off);
4858 de = (struct dirent64 *)((char *)de + reclen);
4859 len -= reclen;
4862 unlock_user(dirp, arg2, ret);
4864 break;
4865 #endif /* TARGET_NR_getdents64 */
4866 #ifdef TARGET_NR__newselect
4867 case TARGET_NR__newselect:
4868 ret = do_select(arg1, arg2, arg3, arg4, arg5);
4869 break;
4870 #endif
4871 #ifdef TARGET_NR_poll
4872 case TARGET_NR_poll:
4874 struct target_pollfd *target_pfd;
4875 unsigned int nfds = arg2;
4876 int timeout = arg3;
4877 struct pollfd *pfd;
4878 unsigned int i;
4880 target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
4881 if (!target_pfd)
4882 goto efault;
4883 pfd = alloca(sizeof(struct pollfd) * nfds);
4884 for(i = 0; i < nfds; i++) {
4885 pfd[i].fd = tswap32(target_pfd[i].fd);
4886 pfd[i].events = tswap16(target_pfd[i].events);
4888 ret = get_errno(poll(pfd, nfds, timeout));
4889 if (!is_error(ret)) {
4890 for(i = 0; i < nfds; i++) {
4891 target_pfd[i].revents = tswap16(pfd[i].revents);
4893 ret += nfds * (sizeof(struct target_pollfd)
4894 - sizeof(struct pollfd));
4896 unlock_user(target_pfd, arg1, ret);
4898 break;
4899 #endif
4900 case TARGET_NR_flock:
4901 /* NOTE: the flock constant seems to be the same for every
4902 Linux platform */
4903 ret = get_errno(flock(arg1, arg2));
4904 break;
4905 case TARGET_NR_readv:
4907 int count = arg3;
4908 struct iovec *vec;
4910 vec = alloca(count * sizeof(struct iovec));
4911 if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
4912 goto efault;
4913 ret = get_errno(readv(arg1, vec, count));
4914 unlock_iovec(vec, arg2, count, 1);
4916 break;
4917 case TARGET_NR_writev:
4919 int count = arg3;
4920 struct iovec *vec;
4922 vec = alloca(count * sizeof(struct iovec));
4923 if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
4924 goto efault;
4925 ret = get_errno(writev(arg1, vec, count));
4926 unlock_iovec(vec, arg2, count, 0);
4928 break;
4929 case TARGET_NR_getsid:
4930 ret = get_errno(getsid(arg1));
4931 break;
4932 #if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
4933 case TARGET_NR_fdatasync:
4934 ret = get_errno(fdatasync(arg1));
4935 break;
4936 #endif
4937 case TARGET_NR__sysctl:
4938 /* We don't implement this, but ENOTDIR is always a safe
4939 return value. */
4940 ret = -TARGET_ENOTDIR;
4941 break;
4942 case TARGET_NR_sched_setparam:
4944 struct sched_param *target_schp;
4945 struct sched_param schp;
4947 if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
4948 goto efault;
4949 schp.sched_priority = tswap32(target_schp->sched_priority);
4950 unlock_user_struct(target_schp, arg2, 0);
4951 ret = get_errno(sched_setparam(arg1, &schp));
4953 break;
4954 case TARGET_NR_sched_getparam:
4956 struct sched_param *target_schp;
4957 struct sched_param schp;
4958 ret = get_errno(sched_getparam(arg1, &schp));
4959 if (!is_error(ret)) {
4960 if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
4961 goto efault;
4962 target_schp->sched_priority = tswap32(schp.sched_priority);
4963 unlock_user_struct(target_schp, arg2, 1);
4966 break;
4967 case TARGET_NR_sched_setscheduler:
4969 struct sched_param *target_schp;
4970 struct sched_param schp;
4971 if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
4972 goto efault;
4973 schp.sched_priority = tswap32(target_schp->sched_priority);
4974 unlock_user_struct(target_schp, arg3, 0);
4975 ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
4977 break;
4978 case TARGET_NR_sched_getscheduler:
4979 ret = get_errno(sched_getscheduler(arg1));
4980 break;
4981 case TARGET_NR_sched_yield:
4982 ret = get_errno(sched_yield());
4983 break;
4984 case TARGET_NR_sched_get_priority_max:
4985 ret = get_errno(sched_get_priority_max(arg1));
4986 break;
4987 case TARGET_NR_sched_get_priority_min:
4988 ret = get_errno(sched_get_priority_min(arg1));
4989 break;
4990 case TARGET_NR_sched_rr_get_interval:
4992 struct timespec ts;
4993 ret = get_errno(sched_rr_get_interval(arg1, &ts));
4994 if (!is_error(ret)) {
4995 host_to_target_timespec(arg2, &ts);
4998 break;
4999 case TARGET_NR_nanosleep:
5001 struct timespec req, rem;
5002 target_to_host_timespec(&req, arg1);
5003 ret = get_errno(nanosleep(&req, &rem));
5004 if (is_error(ret) && arg2) {
5005 host_to_target_timespec(arg2, &rem);
5008 break;
5009 #ifdef TARGET_NR_query_module
5010 case TARGET_NR_query_module:
5011 goto unimplemented;
5012 #endif
5013 #ifdef TARGET_NR_nfsservctl
5014 case TARGET_NR_nfsservctl:
5015 goto unimplemented;
5016 #endif
5017 case TARGET_NR_prctl:
5018 switch (arg1)
5020 case PR_GET_PDEATHSIG:
5022 int deathsig;
5023 ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
5024 if (!is_error(ret) && arg2
5025 && put_user_ual(deathsig, arg2))
5026 goto efault;
5028 break;
5029 default:
5030 ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
5031 break;
5033 break;
5034 #ifdef TARGET_NR_arch_prctl
5035 case TARGET_NR_arch_prctl:
5036 #if defined(TARGET_I386) && !defined(TARGET_ABI32)
5037 ret = do_arch_prctl(cpu_env, arg1, arg2);
5038 break;
5039 #else
5040 goto unimplemented;
5041 #endif
5042 #endif
5043 #ifdef TARGET_NR_pread
5044 case TARGET_NR_pread:
5045 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5046 goto efault;
5047 ret = get_errno(pread(arg1, p, arg3, arg4));
5048 unlock_user(p, arg2, ret);
5049 break;
5050 case TARGET_NR_pwrite:
5051 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5052 goto efault;
5053 ret = get_errno(pwrite(arg1, p, arg3, arg4));
5054 unlock_user(p, arg2, 0);
5055 break;
5056 #endif
5057 #ifdef TARGET_NR_pread64
5058 case TARGET_NR_pread64:
5059 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5060 goto efault;
5061 ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
5062 unlock_user(p, arg2, ret);
5063 break;
5064 case TARGET_NR_pwrite64:
5065 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5066 goto efault;
5067 ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
5068 unlock_user(p, arg2, 0);
5069 break;
5070 #endif
5071 case TARGET_NR_getcwd:
5072 if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
5073 goto efault;
5074 ret = get_errno(sys_getcwd1(p, arg2));
5075 unlock_user(p, arg1, ret);
5076 break;
5077 case TARGET_NR_capget:
5078 goto unimplemented;
5079 case TARGET_NR_capset:
5080 goto unimplemented;
5081 case TARGET_NR_sigaltstack:
5082 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
5083 defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA)
5084 ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env));
5085 break;
5086 #else
5087 goto unimplemented;
5088 #endif
5089 case TARGET_NR_sendfile:
5090 goto unimplemented;
5091 #ifdef TARGET_NR_getpmsg
5092 case TARGET_NR_getpmsg:
5093 goto unimplemented;
5094 #endif
5095 #ifdef TARGET_NR_putpmsg
5096 case TARGET_NR_putpmsg:
5097 goto unimplemented;
5098 #endif
5099 #ifdef TARGET_NR_vfork
5100 case TARGET_NR_vfork:
5101 ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
5102 0, 0, 0, 0));
5103 break;
5104 #endif
5105 #ifdef TARGET_NR_ugetrlimit
5106 case TARGET_NR_ugetrlimit:
5108 struct rlimit rlim;
5109 ret = get_errno(getrlimit(arg1, &rlim));
5110 if (!is_error(ret)) {
5111 struct target_rlimit *target_rlim;
5112 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
5113 goto efault;
5114 target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
5115 target_rlim->rlim_max = tswapl(rlim.rlim_max);
5116 unlock_user_struct(target_rlim, arg2, 1);
5118 break;
5120 #endif
5121 #ifdef TARGET_NR_truncate64
5122 case TARGET_NR_truncate64:
5123 if (!(p = lock_user_string(arg1)))
5124 goto efault;
5125 ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
5126 unlock_user(p, arg1, 0);
5127 break;
5128 #endif
5129 #ifdef TARGET_NR_ftruncate64
5130 case TARGET_NR_ftruncate64:
5131 ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
5132 break;
5133 #endif
5134 #ifdef TARGET_NR_stat64
5135 case TARGET_NR_stat64:
5136 if (!(p = lock_user_string(arg1)))
5137 goto efault;
5138 ret = get_errno(stat(path(p), &st));
5139 unlock_user(p, arg1, 0);
5140 goto do_stat64;
5141 #endif
5142 #ifdef TARGET_NR_lstat64
5143 case TARGET_NR_lstat64:
5144 if (!(p = lock_user_string(arg1)))
5145 goto efault;
5146 ret = get_errno(lstat(path(p), &st));
5147 unlock_user(p, arg1, 0);
5148 goto do_stat64;
5149 #endif
5150 #ifdef TARGET_NR_fstat64
5151 case TARGET_NR_fstat64:
5153 ret = get_errno(fstat(arg1, &st));
5154 do_stat64:
5155 if (!is_error(ret)) {
5156 #ifdef TARGET_ARM
5157 if (((CPUARMState *)cpu_env)->eabi) {
5158 struct target_eabi_stat64 *target_st;
5160 if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
5161 goto efault;
5162 memset(target_st, 0, sizeof(struct target_eabi_stat64));
5163 __put_user(st.st_dev, &target_st->st_dev);
5164 __put_user(st.st_ino, &target_st->st_ino);
5165 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
5166 __put_user(st.st_ino, &target_st->__st_ino);
5167 #endif
5168 __put_user(st.st_mode, &target_st->st_mode);
5169 __put_user(st.st_nlink, &target_st->st_nlink);
5170 __put_user(st.st_uid, &target_st->st_uid);
5171 __put_user(st.st_gid, &target_st->st_gid);
5172 __put_user(st.st_rdev, &target_st->st_rdev);
5173 __put_user(st.st_size, &target_st->st_size);
5174 __put_user(st.st_blksize, &target_st->st_blksize);
5175 __put_user(st.st_blocks, &target_st->st_blocks);
5176 __put_user(st.st_atime, &target_st->target_st_atime);
5177 __put_user(st.st_mtime, &target_st->target_st_mtime);
5178 __put_user(st.st_ctime, &target_st->target_st_ctime);
5179 unlock_user_struct(target_st, arg2, 1);
5180 } else
5181 #endif
5183 struct target_stat64 *target_st;
5185 if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
5186 goto efault;
5187 memset(target_st, 0, sizeof(struct target_stat64));
5188 __put_user(st.st_dev, &target_st->st_dev);
5189 __put_user(st.st_ino, &target_st->st_ino);
5190 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
5191 __put_user(st.st_ino, &target_st->__st_ino);
5192 #endif
5193 __put_user(st.st_mode, &target_st->st_mode);
5194 __put_user(st.st_nlink, &target_st->st_nlink);
5195 __put_user(st.st_uid, &target_st->st_uid);
5196 __put_user(st.st_gid, &target_st->st_gid);
5197 __put_user(st.st_rdev, &target_st->st_rdev);
5198 /* XXX: better use of kernel struct */
5199 __put_user(st.st_size, &target_st->st_size);
5200 __put_user(st.st_blksize, &target_st->st_blksize);
5201 __put_user(st.st_blocks, &target_st->st_blocks);
5202 __put_user(st.st_atime, &target_st->target_st_atime);
5203 __put_user(st.st_mtime, &target_st->target_st_mtime);
5204 __put_user(st.st_ctime, &target_st->target_st_ctime);
5205 unlock_user_struct(target_st, arg2, 1);
5209 break;
5210 #endif
5211 #ifdef USE_UID16
5212 case TARGET_NR_lchown:
5213 if (!(p = lock_user_string(arg1)))
5214 goto efault;
5215 ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
5216 unlock_user(p, arg1, 0);
5217 break;
5218 case TARGET_NR_getuid:
5219 ret = get_errno(high2lowuid(getuid()));
5220 break;
5221 case TARGET_NR_getgid:
5222 ret = get_errno(high2lowgid(getgid()));
5223 break;
5224 case TARGET_NR_geteuid:
5225 ret = get_errno(high2lowuid(geteuid()));
5226 break;
5227 case TARGET_NR_getegid:
5228 ret = get_errno(high2lowgid(getegid()));
5229 break;
5230 case TARGET_NR_setreuid:
5231 ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
5232 break;
5233 case TARGET_NR_setregid:
5234 ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
5235 break;
5236 case TARGET_NR_getgroups:
5238 int gidsetsize = arg1;
5239 uint16_t *target_grouplist;
5240 gid_t *grouplist;
5241 int i;
5243 grouplist = alloca(gidsetsize * sizeof(gid_t));
5244 ret = get_errno(getgroups(gidsetsize, grouplist));
5245 if (!is_error(ret)) {
5246 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
5247 if (!target_grouplist)
5248 goto efault;
5249 for(i = 0;i < gidsetsize; i++)
5250 target_grouplist[i] = tswap16(grouplist[i]);
5251 unlock_user(target_grouplist, arg2, gidsetsize * 2);
5254 break;
5255 case TARGET_NR_setgroups:
5257 int gidsetsize = arg1;
5258 uint16_t *target_grouplist;
5259 gid_t *grouplist;
5260 int i;
5262 grouplist = alloca(gidsetsize * sizeof(gid_t));
5263 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
5264 if (!target_grouplist) {
5265 ret = -TARGET_EFAULT;
5266 goto fail;
5268 for(i = 0;i < gidsetsize; i++)
5269 grouplist[i] = tswap16(target_grouplist[i]);
5270 unlock_user(target_grouplist, arg2, 0);
5271 ret = get_errno(setgroups(gidsetsize, grouplist));
5273 break;
5274 case TARGET_NR_fchown:
5275 ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
5276 break;
5277 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
5278 case TARGET_NR_fchownat:
5279 if (!(p = lock_user_string(arg2)))
5280 goto efault;
5281 ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
5282 unlock_user(p, arg2, 0);
5283 break;
5284 #endif
5285 #ifdef TARGET_NR_setresuid
5286 case TARGET_NR_setresuid:
5287 ret = get_errno(setresuid(low2highuid(arg1),
5288 low2highuid(arg2),
5289 low2highuid(arg3)));
5290 break;
5291 #endif
5292 #ifdef TARGET_NR_getresuid
5293 case TARGET_NR_getresuid:
5295 uid_t ruid, euid, suid;
5296 ret = get_errno(getresuid(&ruid, &euid, &suid));
5297 if (!is_error(ret)) {
5298 if (put_user_u16(high2lowuid(ruid), arg1)
5299 || put_user_u16(high2lowuid(euid), arg2)
5300 || put_user_u16(high2lowuid(suid), arg3))
5301 goto efault;
5304 break;
5305 #endif
5306 #ifdef TARGET_NR_getresgid
5307 case TARGET_NR_setresgid:
5308 ret = get_errno(setresgid(low2highgid(arg1),
5309 low2highgid(arg2),
5310 low2highgid(arg3)));
5311 break;
5312 #endif
5313 #ifdef TARGET_NR_getresgid
5314 case TARGET_NR_getresgid:
5316 gid_t rgid, egid, sgid;
5317 ret = get_errno(getresgid(&rgid, &egid, &sgid));
5318 if (!is_error(ret)) {
5319 if (put_user_u16(high2lowgid(rgid), arg1)
5320 || put_user_u16(high2lowgid(egid), arg2)
5321 || put_user_u16(high2lowgid(sgid), arg3))
5322 goto efault;
5325 break;
5326 #endif
5327 case TARGET_NR_chown:
5328 if (!(p = lock_user_string(arg1)))
5329 goto efault;
5330 ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
5331 unlock_user(p, arg1, 0);
5332 break;
5333 case TARGET_NR_setuid:
5334 ret = get_errno(setuid(low2highuid(arg1)));
5335 break;
5336 case TARGET_NR_setgid:
5337 ret = get_errno(setgid(low2highgid(arg1)));
5338 break;
5339 case TARGET_NR_setfsuid:
5340 ret = get_errno(setfsuid(arg1));
5341 break;
5342 case TARGET_NR_setfsgid:
5343 ret = get_errno(setfsgid(arg1));
5344 break;
5345 #endif /* USE_UID16 */
5347 #ifdef TARGET_NR_lchown32
5348 case TARGET_NR_lchown32:
5349 if (!(p = lock_user_string(arg1)))
5350 goto efault;
5351 ret = get_errno(lchown(p, arg2, arg3));
5352 unlock_user(p, arg1, 0);
5353 break;
5354 #endif
5355 #ifdef TARGET_NR_getuid32
5356 case TARGET_NR_getuid32:
5357 ret = get_errno(getuid());
5358 break;
5359 #endif
5360 #ifdef TARGET_NR_getgid32
5361 case TARGET_NR_getgid32:
5362 ret = get_errno(getgid());
5363 break;
5364 #endif
5365 #ifdef TARGET_NR_geteuid32
5366 case TARGET_NR_geteuid32:
5367 ret = get_errno(geteuid());
5368 break;
5369 #endif
5370 #ifdef TARGET_NR_getegid32
5371 case TARGET_NR_getegid32:
5372 ret = get_errno(getegid());
5373 break;
5374 #endif
5375 #ifdef TARGET_NR_setreuid32
5376 case TARGET_NR_setreuid32:
5377 ret = get_errno(setreuid(arg1, arg2));
5378 break;
5379 #endif
5380 #ifdef TARGET_NR_setregid32
5381 case TARGET_NR_setregid32:
5382 ret = get_errno(setregid(arg1, arg2));
5383 break;
5384 #endif
5385 #ifdef TARGET_NR_getgroups32
5386 case TARGET_NR_getgroups32:
5388 int gidsetsize = arg1;
5389 uint32_t *target_grouplist;
5390 gid_t *grouplist;
5391 int i;
5393 grouplist = alloca(gidsetsize * sizeof(gid_t));
5394 ret = get_errno(getgroups(gidsetsize, grouplist));
5395 if (!is_error(ret)) {
5396 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
5397 if (!target_grouplist) {
5398 ret = -TARGET_EFAULT;
5399 goto fail;
5401 for(i = 0;i < gidsetsize; i++)
5402 target_grouplist[i] = tswap32(grouplist[i]);
5403 unlock_user(target_grouplist, arg2, gidsetsize * 4);
5406 break;
5407 #endif
5408 #ifdef TARGET_NR_setgroups32
5409 case TARGET_NR_setgroups32:
5411 int gidsetsize = arg1;
5412 uint32_t *target_grouplist;
5413 gid_t *grouplist;
5414 int i;
5416 grouplist = alloca(gidsetsize * sizeof(gid_t));
5417 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
5418 if (!target_grouplist) {
5419 ret = -TARGET_EFAULT;
5420 goto fail;
5422 for(i = 0;i < gidsetsize; i++)
5423 grouplist[i] = tswap32(target_grouplist[i]);
5424 unlock_user(target_grouplist, arg2, 0);
5425 ret = get_errno(setgroups(gidsetsize, grouplist));
5427 break;
5428 #endif
5429 #ifdef TARGET_NR_fchown32
5430 case TARGET_NR_fchown32:
5431 ret = get_errno(fchown(arg1, arg2, arg3));
5432 break;
5433 #endif
5434 #ifdef TARGET_NR_setresuid32
5435 case TARGET_NR_setresuid32:
5436 ret = get_errno(setresuid(arg1, arg2, arg3));
5437 break;
5438 #endif
5439 #ifdef TARGET_NR_getresuid32
5440 case TARGET_NR_getresuid32:
5442 uid_t ruid, euid, suid;
5443 ret = get_errno(getresuid(&ruid, &euid, &suid));
5444 if (!is_error(ret)) {
5445 if (put_user_u32(ruid, arg1)
5446 || put_user_u32(euid, arg2)
5447 || put_user_u32(suid, arg3))
5448 goto efault;
5451 break;
5452 #endif
5453 #ifdef TARGET_NR_setresgid32
5454 case TARGET_NR_setresgid32:
5455 ret = get_errno(setresgid(arg1, arg2, arg3));
5456 break;
5457 #endif
5458 #ifdef TARGET_NR_getresgid32
5459 case TARGET_NR_getresgid32:
5461 gid_t rgid, egid, sgid;
5462 ret = get_errno(getresgid(&rgid, &egid, &sgid));
5463 if (!is_error(ret)) {
5464 if (put_user_u32(rgid, arg1)
5465 || put_user_u32(egid, arg2)
5466 || put_user_u32(sgid, arg3))
5467 goto efault;
5470 break;
5471 #endif
5472 #ifdef TARGET_NR_chown32
5473 case TARGET_NR_chown32:
5474 if (!(p = lock_user_string(arg1)))
5475 goto efault;
5476 ret = get_errno(chown(p, arg2, arg3));
5477 unlock_user(p, arg1, 0);
5478 break;
5479 #endif
5480 #ifdef TARGET_NR_setuid32
5481 case TARGET_NR_setuid32:
5482 ret = get_errno(setuid(arg1));
5483 break;
5484 #endif
5485 #ifdef TARGET_NR_setgid32
5486 case TARGET_NR_setgid32:
5487 ret = get_errno(setgid(arg1));
5488 break;
5489 #endif
5490 #ifdef TARGET_NR_setfsuid32
5491 case TARGET_NR_setfsuid32:
5492 ret = get_errno(setfsuid(arg1));
5493 break;
5494 #endif
5495 #ifdef TARGET_NR_setfsgid32
5496 case TARGET_NR_setfsgid32:
5497 ret = get_errno(setfsgid(arg1));
5498 break;
5499 #endif
5501 case TARGET_NR_pivot_root:
5502 goto unimplemented;
5503 #ifdef TARGET_NR_mincore
5504 case TARGET_NR_mincore:
5505 goto unimplemented;
5506 #endif
5507 #ifdef TARGET_NR_madvise
5508 case TARGET_NR_madvise:
5509 /* A straight passthrough may not be safe because qemu sometimes
5510 turns private flie-backed mappings into anonymous mappings.
5511 This will break MADV_DONTNEED.
5512 This is a hint, so ignoring and returning success is ok. */
5513 ret = get_errno(0);
5514 break;
5515 #endif
5516 #if TARGET_ABI_BITS == 32
5517 case TARGET_NR_fcntl64:
5519 int cmd;
5520 struct flock64 fl;
5521 struct target_flock64 *target_fl;
5522 #ifdef TARGET_ARM
5523 struct target_eabi_flock64 *target_efl;
5524 #endif
5526 switch(arg2){
5527 case TARGET_F_GETLK64:
5528 cmd = F_GETLK64;
5529 break;
5530 case TARGET_F_SETLK64:
5531 cmd = F_SETLK64;
5532 break;
5533 case TARGET_F_SETLKW64:
5534 cmd = F_SETLK64;
5535 break;
5536 default:
5537 cmd = arg2;
5538 break;
5541 switch(arg2) {
5542 case TARGET_F_GETLK64:
5543 #ifdef TARGET_ARM
5544 if (((CPUARMState *)cpu_env)->eabi) {
5545 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1))
5546 goto efault;
5547 fl.l_type = tswap16(target_efl->l_type);
5548 fl.l_whence = tswap16(target_efl->l_whence);
5549 fl.l_start = tswap64(target_efl->l_start);
5550 fl.l_len = tswap64(target_efl->l_len);
5551 fl.l_pid = tswapl(target_efl->l_pid);
5552 unlock_user_struct(target_efl, arg3, 0);
5553 } else
5554 #endif
5556 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1))
5557 goto efault;
5558 fl.l_type = tswap16(target_fl->l_type);
5559 fl.l_whence = tswap16(target_fl->l_whence);
5560 fl.l_start = tswap64(target_fl->l_start);
5561 fl.l_len = tswap64(target_fl->l_len);
5562 fl.l_pid = tswapl(target_fl->l_pid);
5563 unlock_user_struct(target_fl, arg3, 0);
5565 ret = get_errno(fcntl(arg1, cmd, &fl));
5566 if (ret == 0) {
5567 #ifdef TARGET_ARM
5568 if (((CPUARMState *)cpu_env)->eabi) {
5569 if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0))
5570 goto efault;
5571 target_efl->l_type = tswap16(fl.l_type);
5572 target_efl->l_whence = tswap16(fl.l_whence);
5573 target_efl->l_start = tswap64(fl.l_start);
5574 target_efl->l_len = tswap64(fl.l_len);
5575 target_efl->l_pid = tswapl(fl.l_pid);
5576 unlock_user_struct(target_efl, arg3, 1);
5577 } else
5578 #endif
5580 if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0))
5581 goto efault;
5582 target_fl->l_type = tswap16(fl.l_type);
5583 target_fl->l_whence = tswap16(fl.l_whence);
5584 target_fl->l_start = tswap64(fl.l_start);
5585 target_fl->l_len = tswap64(fl.l_len);
5586 target_fl->l_pid = tswapl(fl.l_pid);
5587 unlock_user_struct(target_fl, arg3, 1);
5590 break;
5592 case TARGET_F_SETLK64:
5593 case TARGET_F_SETLKW64:
5594 #ifdef TARGET_ARM
5595 if (((CPUARMState *)cpu_env)->eabi) {
5596 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1))
5597 goto efault;
5598 fl.l_type = tswap16(target_efl->l_type);
5599 fl.l_whence = tswap16(target_efl->l_whence);
5600 fl.l_start = tswap64(target_efl->l_start);
5601 fl.l_len = tswap64(target_efl->l_len);
5602 fl.l_pid = tswapl(target_efl->l_pid);
5603 unlock_user_struct(target_efl, arg3, 0);
5604 } else
5605 #endif
5607 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1))
5608 goto efault;
5609 fl.l_type = tswap16(target_fl->l_type);
5610 fl.l_whence = tswap16(target_fl->l_whence);
5611 fl.l_start = tswap64(target_fl->l_start);
5612 fl.l_len = tswap64(target_fl->l_len);
5613 fl.l_pid = tswapl(target_fl->l_pid);
5614 unlock_user_struct(target_fl, arg3, 0);
5616 ret = get_errno(fcntl(arg1, cmd, &fl));
5617 break;
5618 default:
5619 ret = do_fcntl(arg1, cmd, arg3);
5620 break;
5622 break;
5624 #endif
5625 #ifdef TARGET_NR_cacheflush
5626 case TARGET_NR_cacheflush:
5627 /* self-modifying code is handled automatically, so nothing needed */
5628 ret = 0;
5629 break;
5630 #endif
5631 #ifdef TARGET_NR_security
5632 case TARGET_NR_security:
5633 goto unimplemented;
5634 #endif
5635 #ifdef TARGET_NR_getpagesize
5636 case TARGET_NR_getpagesize:
5637 ret = TARGET_PAGE_SIZE;
5638 break;
5639 #endif
5640 case TARGET_NR_gettid:
5641 ret = get_errno(gettid());
5642 break;
5643 #ifdef TARGET_NR_readahead
5644 case TARGET_NR_readahead:
5645 goto unimplemented;
5646 #endif
5647 #ifdef TARGET_NR_setxattr
5648 case TARGET_NR_setxattr:
5649 case TARGET_NR_lsetxattr:
5650 case TARGET_NR_fsetxattr:
5651 case TARGET_NR_getxattr:
5652 case TARGET_NR_lgetxattr:
5653 case TARGET_NR_fgetxattr:
5654 case TARGET_NR_listxattr:
5655 case TARGET_NR_llistxattr:
5656 case TARGET_NR_flistxattr:
5657 case TARGET_NR_removexattr:
5658 case TARGET_NR_lremovexattr:
5659 case TARGET_NR_fremovexattr:
5660 goto unimplemented_nowarn;
5661 #endif
5662 #ifdef TARGET_NR_set_thread_area
5663 case TARGET_NR_set_thread_area:
5664 #if defined(TARGET_MIPS)
5665 ((CPUMIPSState *) cpu_env)->tls_value = arg1;
5666 ret = 0;
5667 break;
5668 #elif defined(TARGET_I386) && defined(TARGET_ABI32)
5669 ret = do_set_thread_area(cpu_env, arg1);
5670 break;
5671 #else
5672 goto unimplemented_nowarn;
5673 #endif
5674 #endif
5675 #ifdef TARGET_NR_get_thread_area
5676 case TARGET_NR_get_thread_area:
5677 #if defined(TARGET_I386) && defined(TARGET_ABI32)
5678 ret = do_get_thread_area(cpu_env, arg1);
5679 #else
5680 goto unimplemented_nowarn;
5681 #endif
5682 #endif
5683 #ifdef TARGET_NR_getdomainname
5684 case TARGET_NR_getdomainname:
5685 goto unimplemented_nowarn;
5686 #endif
5688 #ifdef TARGET_NR_clock_gettime
5689 case TARGET_NR_clock_gettime:
5691 struct timespec ts;
5692 ret = get_errno(clock_gettime(arg1, &ts));
5693 if (!is_error(ret)) {
5694 host_to_target_timespec(arg2, &ts);
5696 break;
5698 #endif
5699 #ifdef TARGET_NR_clock_getres
5700 case TARGET_NR_clock_getres:
5702 struct timespec ts;
5703 ret = get_errno(clock_getres(arg1, &ts));
5704 if (!is_error(ret)) {
5705 host_to_target_timespec(arg2, &ts);
5707 break;
5709 #endif
5710 #ifdef TARGET_NR_clock_nanosleep
5711 case TARGET_NR_clock_nanosleep:
5713 struct timespec ts;
5714 target_to_host_timespec(&ts, arg3);
5715 ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
5716 if (arg4)
5717 host_to_target_timespec(arg4, &ts);
5718 break;
5720 #endif
5722 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
5723 case TARGET_NR_set_tid_address:
5724 ret = get_errno(set_tid_address((int *)g2h(arg1)));
5725 break;
5726 #endif
5728 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
5729 case TARGET_NR_tkill:
5730 ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
5731 break;
5732 #endif
5734 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
5735 case TARGET_NR_tgkill:
5736 ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
5737 target_to_host_signal(arg3)));
5738 break;
5739 #endif
5741 #ifdef TARGET_NR_set_robust_list
5742 case TARGET_NR_set_robust_list:
5743 goto unimplemented_nowarn;
5744 #endif
5746 #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
5747 case TARGET_NR_utimensat:
5749 struct timespec ts[2];
5750 target_to_host_timespec(ts, arg3);
5751 target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
5752 if (!arg2)
5753 ret = get_errno(sys_utimensat(arg1, NULL, ts, arg4));
5754 else {
5755 if (!(p = lock_user_string(arg2))) {
5756 ret = -TARGET_EFAULT;
5757 goto fail;
5759 ret = get_errno(sys_utimensat(arg1, path(p), ts, arg4));
5760 unlock_user(p, arg2, 0);
5763 break;
5764 #endif
5765 #if defined(USE_NPTL)
5766 case TARGET_NR_futex:
5767 ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
5768 break;
5769 #endif
5771 default:
5772 unimplemented:
5773 gemu_log("qemu: Unsupported syscall: %d\n", num);
5774 #if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
5775 unimplemented_nowarn:
5776 #endif
5777 ret = -TARGET_ENOSYS;
5778 break;
5780 fail:
5781 #ifdef DEBUG
5782 gemu_log(" = %ld\n", ret);
5783 #endif
5784 if(do_strace)
5785 print_syscall_ret(num, ret);
5786 return ret;
5787 efault:
5788 ret = -TARGET_EFAULT;
5789 goto fail;