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