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