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