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