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