Add vsplt{b,h,w} instructions.
[qemu/qemu-JZ.git] / linux-user / syscall.c
blobbd60494bcf483fa7afa3fd33026564dfe2e557d6
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>
56 #include <qemu-common.h>
57 #ifdef HAVE_GPROF
58 #include <sys/gmon.h>
59 #endif
61 #define termios host_termios
62 #define winsize host_winsize
63 #define termio host_termio
64 #define sgttyb host_sgttyb /* same as target */
65 #define tchars host_tchars /* same as target */
66 #define ltchars host_ltchars /* same as target */
68 #include <linux/termios.h>
69 #include <linux/unistd.h>
70 #include <linux/utsname.h>
71 #include <linux/cdrom.h>
72 #include <linux/hdreg.h>
73 #include <linux/soundcard.h>
74 #include <linux/kd.h>
75 #include <linux/mtio.h>
76 #include "linux_loop.h"
78 #include "qemu.h"
79 #include "qemu-common.h"
81 #if defined(USE_NPTL)
82 #include <linux/futex.h>
83 #define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
84 CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
85 #else
86 /* XXX: Hardcode the above values. */
87 #define CLONE_NPTL_FLAGS2 0
88 #endif
90 //#define DEBUG
92 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \
93 || defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS)
94 /* 16 bit uid wrappers emulation */
95 #define USE_UID16
96 #endif
98 //#include <linux/msdos_fs.h>
99 #define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct linux_dirent [2])
100 #define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct linux_dirent [2])
103 #undef _syscall0
104 #undef _syscall1
105 #undef _syscall2
106 #undef _syscall3
107 #undef _syscall4
108 #undef _syscall5
109 #undef _syscall6
111 #define _syscall0(type,name) \
112 static type name (void) \
114 return syscall(__NR_##name); \
117 #define _syscall1(type,name,type1,arg1) \
118 static type name (type1 arg1) \
120 return syscall(__NR_##name, arg1); \
123 #define _syscall2(type,name,type1,arg1,type2,arg2) \
124 static type name (type1 arg1,type2 arg2) \
126 return syscall(__NR_##name, arg1, arg2); \
129 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
130 static type name (type1 arg1,type2 arg2,type3 arg3) \
132 return syscall(__NR_##name, arg1, arg2, arg3); \
135 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
136 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4) \
138 return syscall(__NR_##name, arg1, arg2, arg3, arg4); \
141 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
142 type5,arg5) \
143 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
145 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5); \
149 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
150 type5,arg5,type6,arg6) \
151 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \
152 type6 arg6) \
154 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6); \
158 #define __NR_sys_exit __NR_exit
159 #define __NR_sys_uname __NR_uname
160 #define __NR_sys_faccessat __NR_faccessat
161 #define __NR_sys_fchmodat __NR_fchmodat
162 #define __NR_sys_fchownat __NR_fchownat
163 #define __NR_sys_fstatat64 __NR_fstatat64
164 #define __NR_sys_futimesat __NR_futimesat
165 #define __NR_sys_getcwd1 __NR_getcwd
166 #define __NR_sys_getdents __NR_getdents
167 #define __NR_sys_getdents64 __NR_getdents64
168 #define __NR_sys_getpriority __NR_getpriority
169 #define __NR_sys_linkat __NR_linkat
170 #define __NR_sys_mkdirat __NR_mkdirat
171 #define __NR_sys_mknodat __NR_mknodat
172 #define __NR_sys_openat __NR_openat
173 #define __NR_sys_readlinkat __NR_readlinkat
174 #define __NR_sys_renameat __NR_renameat
175 #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
176 #define __NR_sys_symlinkat __NR_symlinkat
177 #define __NR_sys_syslog __NR_syslog
178 #define __NR_sys_tgkill __NR_tgkill
179 #define __NR_sys_tkill __NR_tkill
180 #define __NR_sys_unlinkat __NR_unlinkat
181 #define __NR_sys_utimensat __NR_utimensat
182 #define __NR_sys_futex __NR_futex
183 #define __NR_sys_inotify_init __NR_inotify_init
184 #define __NR_sys_inotify_add_watch __NR_inotify_add_watch
185 #define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
187 #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
188 #define __NR__llseek __NR_lseek
189 #endif
191 #ifdef __NR_gettid
192 _syscall0(int, gettid)
193 #else
194 /* This is a replacement for the host gettid() and must return a host
195 errno. */
196 static int gettid(void) {
197 return -ENOSYS;
199 #endif
200 _syscall1(int,sys_exit,int,status)
201 _syscall1(int,sys_uname,struct new_utsname *,buf)
202 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
203 _syscall4(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode,int,flags)
204 #endif
205 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
206 _syscall4(int,sys_fchmodat,int,dirfd,const char *,pathname,
207 mode_t,mode,int,flags)
208 #endif
209 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) && defined(USE_UID16)
210 _syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
211 uid_t,owner,gid_t,group,int,flags)
212 #endif
213 #if defined(TARGET_NR_fstatat64) && defined(__NR_fstatat64)
214 _syscall4(int,sys_fstatat64,int,dirfd,const char *,pathname,
215 struct stat *,buf,int,flags)
216 #endif
217 #if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
218 _syscall3(int,sys_futimesat,int,dirfd,const char *,pathname,
219 const struct timeval *,times)
220 #endif
221 _syscall2(int,sys_getcwd1,char *,buf,size_t,size)
222 #if TARGET_ABI_BITS == 32
223 _syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
224 #endif
225 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
226 _syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
227 #endif
228 _syscall2(int, sys_getpriority, int, which, int, who);
229 #if !defined (__x86_64__)
230 _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo,
231 loff_t *, res, uint, wh);
232 #endif
233 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
234 _syscall5(int,sys_linkat,int,olddirfd,const char *,oldpath,
235 int,newdirfd,const char *,newpath,int,flags)
236 #endif
237 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
238 _syscall3(int,sys_mkdirat,int,dirfd,const char *,pathname,mode_t,mode)
239 #endif
240 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
241 _syscall4(int,sys_mknodat,int,dirfd,const char *,pathname,
242 mode_t,mode,dev_t,dev)
243 #endif
244 #if defined(TARGET_NR_openat) && defined(__NR_openat)
245 _syscall4(int,sys_openat,int,dirfd,const char *,pathname,int,flags,mode_t,mode)
246 #endif
247 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
248 _syscall4(int,sys_readlinkat,int,dirfd,const char *,pathname,
249 char *,buf,size_t,bufsize)
250 #endif
251 #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
252 _syscall4(int,sys_renameat,int,olddirfd,const char *,oldpath,
253 int,newdirfd,const char *,newpath)
254 #endif
255 _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
256 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
257 _syscall3(int,sys_symlinkat,const char *,oldpath,
258 int,newdirfd,const char *,newpath)
259 #endif
260 _syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
261 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
262 _syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
263 #endif
264 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
265 _syscall2(int,sys_tkill,int,tid,int,sig)
266 #endif
267 #ifdef __NR_exit_group
268 _syscall1(int,exit_group,int,error_code)
269 #endif
270 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
271 _syscall1(int,set_tid_address,int *,tidptr)
272 #endif
273 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
274 _syscall3(int,sys_unlinkat,int,dirfd,const char *,pathname,int,flags)
275 #endif
276 #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
277 _syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
278 const struct timespec *,tsp,int,flags)
279 #endif
280 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
281 _syscall0(int,sys_inotify_init)
282 #endif
283 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
284 _syscall3(int,sys_inotify_add_watch,int,fd,const char *,pathname,uint32_t,mask)
285 #endif
286 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
287 _syscall2(int,sys_inotify_rm_watch,int,fd,uint32_t,wd)
288 #endif
289 #if defined(USE_NPTL)
290 #if defined(TARGET_NR_futex) && defined(__NR_futex)
291 _syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
292 const struct timespec *,timeout,int *,uaddr2,int,val3)
293 #endif
294 #endif
296 extern int personality(int);
297 extern int flock(int, int);
298 extern int setfsuid(int);
299 extern int setfsgid(int);
300 extern int setgroups(int, gid_t *);
302 #define ERRNO_TABLE_SIZE 1200
304 /* target_to_host_errno_table[] is initialized from
305 * host_to_target_errno_table[] in syscall_init(). */
306 static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
310 * This list is the union of errno values overridden in asm-<arch>/errno.h
311 * minus the errnos that are not actually generic to all archs.
313 static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
314 [EIDRM] = TARGET_EIDRM,
315 [ECHRNG] = TARGET_ECHRNG,
316 [EL2NSYNC] = TARGET_EL2NSYNC,
317 [EL3HLT] = TARGET_EL3HLT,
318 [EL3RST] = TARGET_EL3RST,
319 [ELNRNG] = TARGET_ELNRNG,
320 [EUNATCH] = TARGET_EUNATCH,
321 [ENOCSI] = TARGET_ENOCSI,
322 [EL2HLT] = TARGET_EL2HLT,
323 [EDEADLK] = TARGET_EDEADLK,
324 [ENOLCK] = TARGET_ENOLCK,
325 [EBADE] = TARGET_EBADE,
326 [EBADR] = TARGET_EBADR,
327 [EXFULL] = TARGET_EXFULL,
328 [ENOANO] = TARGET_ENOANO,
329 [EBADRQC] = TARGET_EBADRQC,
330 [EBADSLT] = TARGET_EBADSLT,
331 [EBFONT] = TARGET_EBFONT,
332 [ENOSTR] = TARGET_ENOSTR,
333 [ENODATA] = TARGET_ENODATA,
334 [ETIME] = TARGET_ETIME,
335 [ENOSR] = TARGET_ENOSR,
336 [ENONET] = TARGET_ENONET,
337 [ENOPKG] = TARGET_ENOPKG,
338 [EREMOTE] = TARGET_EREMOTE,
339 [ENOLINK] = TARGET_ENOLINK,
340 [EADV] = TARGET_EADV,
341 [ESRMNT] = TARGET_ESRMNT,
342 [ECOMM] = TARGET_ECOMM,
343 [EPROTO] = TARGET_EPROTO,
344 [EDOTDOT] = TARGET_EDOTDOT,
345 [EMULTIHOP] = TARGET_EMULTIHOP,
346 [EBADMSG] = TARGET_EBADMSG,
347 [ENAMETOOLONG] = TARGET_ENAMETOOLONG,
348 [EOVERFLOW] = TARGET_EOVERFLOW,
349 [ENOTUNIQ] = TARGET_ENOTUNIQ,
350 [EBADFD] = TARGET_EBADFD,
351 [EREMCHG] = TARGET_EREMCHG,
352 [ELIBACC] = TARGET_ELIBACC,
353 [ELIBBAD] = TARGET_ELIBBAD,
354 [ELIBSCN] = TARGET_ELIBSCN,
355 [ELIBMAX] = TARGET_ELIBMAX,
356 [ELIBEXEC] = TARGET_ELIBEXEC,
357 [EILSEQ] = TARGET_EILSEQ,
358 [ENOSYS] = TARGET_ENOSYS,
359 [ELOOP] = TARGET_ELOOP,
360 [ERESTART] = TARGET_ERESTART,
361 [ESTRPIPE] = TARGET_ESTRPIPE,
362 [ENOTEMPTY] = TARGET_ENOTEMPTY,
363 [EUSERS] = TARGET_EUSERS,
364 [ENOTSOCK] = TARGET_ENOTSOCK,
365 [EDESTADDRREQ] = TARGET_EDESTADDRREQ,
366 [EMSGSIZE] = TARGET_EMSGSIZE,
367 [EPROTOTYPE] = TARGET_EPROTOTYPE,
368 [ENOPROTOOPT] = TARGET_ENOPROTOOPT,
369 [EPROTONOSUPPORT] = TARGET_EPROTONOSUPPORT,
370 [ESOCKTNOSUPPORT] = TARGET_ESOCKTNOSUPPORT,
371 [EOPNOTSUPP] = TARGET_EOPNOTSUPP,
372 [EPFNOSUPPORT] = TARGET_EPFNOSUPPORT,
373 [EAFNOSUPPORT] = TARGET_EAFNOSUPPORT,
374 [EADDRINUSE] = TARGET_EADDRINUSE,
375 [EADDRNOTAVAIL] = TARGET_EADDRNOTAVAIL,
376 [ENETDOWN] = TARGET_ENETDOWN,
377 [ENETUNREACH] = TARGET_ENETUNREACH,
378 [ENETRESET] = TARGET_ENETRESET,
379 [ECONNABORTED] = TARGET_ECONNABORTED,
380 [ECONNRESET] = TARGET_ECONNRESET,
381 [ENOBUFS] = TARGET_ENOBUFS,
382 [EISCONN] = TARGET_EISCONN,
383 [ENOTCONN] = TARGET_ENOTCONN,
384 [EUCLEAN] = TARGET_EUCLEAN,
385 [ENOTNAM] = TARGET_ENOTNAM,
386 [ENAVAIL] = TARGET_ENAVAIL,
387 [EISNAM] = TARGET_EISNAM,
388 [EREMOTEIO] = TARGET_EREMOTEIO,
389 [ESHUTDOWN] = TARGET_ESHUTDOWN,
390 [ETOOMANYREFS] = TARGET_ETOOMANYREFS,
391 [ETIMEDOUT] = TARGET_ETIMEDOUT,
392 [ECONNREFUSED] = TARGET_ECONNREFUSED,
393 [EHOSTDOWN] = TARGET_EHOSTDOWN,
394 [EHOSTUNREACH] = TARGET_EHOSTUNREACH,
395 [EALREADY] = TARGET_EALREADY,
396 [EINPROGRESS] = TARGET_EINPROGRESS,
397 [ESTALE] = TARGET_ESTALE,
398 [ECANCELED] = TARGET_ECANCELED,
399 [ENOMEDIUM] = TARGET_ENOMEDIUM,
400 [EMEDIUMTYPE] = TARGET_EMEDIUMTYPE,
401 #ifdef ENOKEY
402 [ENOKEY] = TARGET_ENOKEY,
403 #endif
404 #ifdef EKEYEXPIRED
405 [EKEYEXPIRED] = TARGET_EKEYEXPIRED,
406 #endif
407 #ifdef EKEYREVOKED
408 [EKEYREVOKED] = TARGET_EKEYREVOKED,
409 #endif
410 #ifdef EKEYREJECTED
411 [EKEYREJECTED] = TARGET_EKEYREJECTED,
412 #endif
413 #ifdef EOWNERDEAD
414 [EOWNERDEAD] = TARGET_EOWNERDEAD,
415 #endif
416 #ifdef ENOTRECOVERABLE
417 [ENOTRECOVERABLE] = TARGET_ENOTRECOVERABLE,
418 #endif
421 static inline int host_to_target_errno(int err)
423 if(host_to_target_errno_table[err])
424 return host_to_target_errno_table[err];
425 return err;
428 static inline int target_to_host_errno(int err)
430 if (target_to_host_errno_table[err])
431 return target_to_host_errno_table[err];
432 return err;
435 static inline abi_long get_errno(abi_long ret)
437 if (ret == -1)
438 return -host_to_target_errno(errno);
439 else
440 return ret;
443 static inline int is_error(abi_long ret)
445 return (abi_ulong)ret >= (abi_ulong)(-4096);
448 char *target_strerror(int err)
450 return strerror(target_to_host_errno(err));
453 static abi_ulong target_brk;
454 static abi_ulong target_original_brk;
456 void target_set_brk(abi_ulong new_brk)
458 target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
461 /* do_brk() must return target values and target errnos. */
462 abi_long do_brk(abi_ulong new_brk)
464 abi_ulong brk_page;
465 abi_long mapped_addr;
466 int new_alloc_size;
468 if (!new_brk)
469 return target_brk;
470 if (new_brk < target_original_brk)
471 return target_brk;
473 brk_page = HOST_PAGE_ALIGN(target_brk);
475 /* If the new brk is less than this, set it and we're done... */
476 if (new_brk < brk_page) {
477 target_brk = new_brk;
478 return target_brk;
481 /* We need to allocate more memory after the brk... */
482 new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
483 mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
484 PROT_READ|PROT_WRITE,
485 MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
487 if (!is_error(mapped_addr))
488 target_brk = new_brk;
490 return target_brk;
493 static inline abi_long copy_from_user_fdset(fd_set *fds,
494 abi_ulong target_fds_addr,
495 int n)
497 int i, nw, j, k;
498 abi_ulong b, *target_fds;
500 nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
501 if (!(target_fds = lock_user(VERIFY_READ,
502 target_fds_addr,
503 sizeof(abi_ulong) * nw,
504 1)))
505 return -TARGET_EFAULT;
507 FD_ZERO(fds);
508 k = 0;
509 for (i = 0; i < nw; i++) {
510 /* grab the abi_ulong */
511 __get_user(b, &target_fds[i]);
512 for (j = 0; j < TARGET_ABI_BITS; j++) {
513 /* check the bit inside the abi_ulong */
514 if ((b >> j) & 1)
515 FD_SET(k, fds);
516 k++;
520 unlock_user(target_fds, target_fds_addr, 0);
522 return 0;
525 static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
526 const fd_set *fds,
527 int n)
529 int i, nw, j, k;
530 abi_long v;
531 abi_ulong *target_fds;
533 nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
534 if (!(target_fds = lock_user(VERIFY_WRITE,
535 target_fds_addr,
536 sizeof(abi_ulong) * nw,
537 0)))
538 return -TARGET_EFAULT;
540 k = 0;
541 for (i = 0; i < nw; i++) {
542 v = 0;
543 for (j = 0; j < TARGET_ABI_BITS; j++) {
544 v |= ((FD_ISSET(k, fds) != 0) << j);
545 k++;
547 __put_user(v, &target_fds[i]);
550 unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
552 return 0;
555 #if defined(__alpha__)
556 #define HOST_HZ 1024
557 #else
558 #define HOST_HZ 100
559 #endif
561 static inline abi_long host_to_target_clock_t(long ticks)
563 #if HOST_HZ == TARGET_HZ
564 return ticks;
565 #else
566 return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
567 #endif
570 static inline abi_long host_to_target_rusage(abi_ulong target_addr,
571 const struct rusage *rusage)
573 struct target_rusage *target_rusage;
575 if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
576 return -TARGET_EFAULT;
577 target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
578 target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
579 target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
580 target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec);
581 target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss);
582 target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss);
583 target_rusage->ru_idrss = tswapl(rusage->ru_idrss);
584 target_rusage->ru_isrss = tswapl(rusage->ru_isrss);
585 target_rusage->ru_minflt = tswapl(rusage->ru_minflt);
586 target_rusage->ru_majflt = tswapl(rusage->ru_majflt);
587 target_rusage->ru_nswap = tswapl(rusage->ru_nswap);
588 target_rusage->ru_inblock = tswapl(rusage->ru_inblock);
589 target_rusage->ru_oublock = tswapl(rusage->ru_oublock);
590 target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd);
591 target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv);
592 target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);
593 target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
594 target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
595 unlock_user_struct(target_rusage, target_addr, 1);
597 return 0;
600 static inline abi_long copy_from_user_timeval(struct timeval *tv,
601 abi_ulong target_tv_addr)
603 struct target_timeval *target_tv;
605 if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
606 return -TARGET_EFAULT;
608 __get_user(tv->tv_sec, &target_tv->tv_sec);
609 __get_user(tv->tv_usec, &target_tv->tv_usec);
611 unlock_user_struct(target_tv, target_tv_addr, 0);
613 return 0;
616 static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
617 const struct timeval *tv)
619 struct target_timeval *target_tv;
621 if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
622 return -TARGET_EFAULT;
624 __put_user(tv->tv_sec, &target_tv->tv_sec);
625 __put_user(tv->tv_usec, &target_tv->tv_usec);
627 unlock_user_struct(target_tv, target_tv_addr, 1);
629 return 0;
633 /* do_select() must return target values and target errnos. */
634 static abi_long do_select(int n,
635 abi_ulong rfd_addr, abi_ulong wfd_addr,
636 abi_ulong efd_addr, abi_ulong target_tv_addr)
638 fd_set rfds, wfds, efds;
639 fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
640 struct timeval tv, *tv_ptr;
641 abi_long ret;
643 if (rfd_addr) {
644 if (copy_from_user_fdset(&rfds, rfd_addr, n))
645 return -TARGET_EFAULT;
646 rfds_ptr = &rfds;
647 } else {
648 rfds_ptr = NULL;
650 if (wfd_addr) {
651 if (copy_from_user_fdset(&wfds, wfd_addr, n))
652 return -TARGET_EFAULT;
653 wfds_ptr = &wfds;
654 } else {
655 wfds_ptr = NULL;
657 if (efd_addr) {
658 if (copy_from_user_fdset(&efds, efd_addr, n))
659 return -TARGET_EFAULT;
660 efds_ptr = &efds;
661 } else {
662 efds_ptr = NULL;
665 if (target_tv_addr) {
666 if (copy_from_user_timeval(&tv, target_tv_addr))
667 return -TARGET_EFAULT;
668 tv_ptr = &tv;
669 } else {
670 tv_ptr = NULL;
673 ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
675 if (!is_error(ret)) {
676 if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
677 return -TARGET_EFAULT;
678 if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
679 return -TARGET_EFAULT;
680 if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
681 return -TARGET_EFAULT;
683 if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
684 return -TARGET_EFAULT;
687 return ret;
690 static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
691 abi_ulong target_addr,
692 socklen_t len)
694 struct target_sockaddr *target_saddr;
696 target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
697 if (!target_saddr)
698 return -TARGET_EFAULT;
699 memcpy(addr, target_saddr, len);
700 addr->sa_family = tswap16(target_saddr->sa_family);
701 unlock_user(target_saddr, target_addr, 0);
703 return 0;
706 static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
707 struct sockaddr *addr,
708 socklen_t len)
710 struct target_sockaddr *target_saddr;
712 target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
713 if (!target_saddr)
714 return -TARGET_EFAULT;
715 memcpy(target_saddr, addr, len);
716 target_saddr->sa_family = tswap16(addr->sa_family);
717 unlock_user(target_saddr, target_addr, len);
719 return 0;
722 /* ??? Should this also swap msgh->name? */
723 static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
724 struct target_msghdr *target_msgh)
726 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
727 abi_long msg_controllen;
728 abi_ulong target_cmsg_addr;
729 struct target_cmsghdr *target_cmsg;
730 socklen_t space = 0;
732 msg_controllen = tswapl(target_msgh->msg_controllen);
733 if (msg_controllen < sizeof (struct target_cmsghdr))
734 goto the_end;
735 target_cmsg_addr = tswapl(target_msgh->msg_control);
736 target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
737 if (!target_cmsg)
738 return -TARGET_EFAULT;
740 while (cmsg && target_cmsg) {
741 void *data = CMSG_DATA(cmsg);
742 void *target_data = TARGET_CMSG_DATA(target_cmsg);
744 int len = tswapl(target_cmsg->cmsg_len)
745 - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
747 space += CMSG_SPACE(len);
748 if (space > msgh->msg_controllen) {
749 space -= CMSG_SPACE(len);
750 gemu_log("Host cmsg overflow\n");
751 break;
754 cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
755 cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
756 cmsg->cmsg_len = CMSG_LEN(len);
758 if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
759 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
760 memcpy(data, target_data, len);
761 } else {
762 int *fd = (int *)data;
763 int *target_fd = (int *)target_data;
764 int i, numfds = len / sizeof(int);
766 for (i = 0; i < numfds; i++)
767 fd[i] = tswap32(target_fd[i]);
770 cmsg = CMSG_NXTHDR(msgh, cmsg);
771 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
773 unlock_user(target_cmsg, target_cmsg_addr, 0);
774 the_end:
775 msgh->msg_controllen = space;
776 return 0;
779 /* ??? Should this also swap msgh->name? */
780 static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
781 struct msghdr *msgh)
783 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
784 abi_long msg_controllen;
785 abi_ulong target_cmsg_addr;
786 struct target_cmsghdr *target_cmsg;
787 socklen_t space = 0;
789 msg_controllen = tswapl(target_msgh->msg_controllen);
790 if (msg_controllen < sizeof (struct target_cmsghdr))
791 goto the_end;
792 target_cmsg_addr = tswapl(target_msgh->msg_control);
793 target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
794 if (!target_cmsg)
795 return -TARGET_EFAULT;
797 while (cmsg && target_cmsg) {
798 void *data = CMSG_DATA(cmsg);
799 void *target_data = TARGET_CMSG_DATA(target_cmsg);
801 int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
803 space += TARGET_CMSG_SPACE(len);
804 if (space > msg_controllen) {
805 space -= TARGET_CMSG_SPACE(len);
806 gemu_log("Target cmsg overflow\n");
807 break;
810 target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
811 target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
812 target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
814 if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
815 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
816 memcpy(target_data, data, len);
817 } else {
818 int *fd = (int *)data;
819 int *target_fd = (int *)target_data;
820 int i, numfds = len / sizeof(int);
822 for (i = 0; i < numfds; i++)
823 target_fd[i] = tswap32(fd[i]);
826 cmsg = CMSG_NXTHDR(msgh, cmsg);
827 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
829 unlock_user(target_cmsg, target_cmsg_addr, space);
830 the_end:
831 target_msgh->msg_controllen = tswapl(space);
832 return 0;
835 /* do_setsockopt() Must return target values and target errnos. */
836 static abi_long do_setsockopt(int sockfd, int level, int optname,
837 abi_ulong optval_addr, socklen_t optlen)
839 abi_long ret;
840 int val;
842 switch(level) {
843 case SOL_TCP:
844 /* TCP options all take an 'int' value. */
845 if (optlen < sizeof(uint32_t))
846 return -TARGET_EINVAL;
848 if (get_user_u32(val, optval_addr))
849 return -TARGET_EFAULT;
850 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
851 break;
852 case SOL_IP:
853 switch(optname) {
854 case IP_TOS:
855 case IP_TTL:
856 case IP_HDRINCL:
857 case IP_ROUTER_ALERT:
858 case IP_RECVOPTS:
859 case IP_RETOPTS:
860 case IP_PKTINFO:
861 case IP_MTU_DISCOVER:
862 case IP_RECVERR:
863 case IP_RECVTOS:
864 #ifdef IP_FREEBIND
865 case IP_FREEBIND:
866 #endif
867 case IP_MULTICAST_TTL:
868 case IP_MULTICAST_LOOP:
869 val = 0;
870 if (optlen >= sizeof(uint32_t)) {
871 if (get_user_u32(val, optval_addr))
872 return -TARGET_EFAULT;
873 } else if (optlen >= 1) {
874 if (get_user_u8(val, optval_addr))
875 return -TARGET_EFAULT;
877 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
878 break;
879 default:
880 goto unimplemented;
882 break;
883 case TARGET_SOL_SOCKET:
884 switch (optname) {
885 /* Options with 'int' argument. */
886 case TARGET_SO_DEBUG:
887 optname = SO_DEBUG;
888 break;
889 case TARGET_SO_REUSEADDR:
890 optname = SO_REUSEADDR;
891 break;
892 case TARGET_SO_TYPE:
893 optname = SO_TYPE;
894 break;
895 case TARGET_SO_ERROR:
896 optname = SO_ERROR;
897 break;
898 case TARGET_SO_DONTROUTE:
899 optname = SO_DONTROUTE;
900 break;
901 case TARGET_SO_BROADCAST:
902 optname = SO_BROADCAST;
903 break;
904 case TARGET_SO_SNDBUF:
905 optname = SO_SNDBUF;
906 break;
907 case TARGET_SO_RCVBUF:
908 optname = SO_RCVBUF;
909 break;
910 case TARGET_SO_KEEPALIVE:
911 optname = SO_KEEPALIVE;
912 break;
913 case TARGET_SO_OOBINLINE:
914 optname = SO_OOBINLINE;
915 break;
916 case TARGET_SO_NO_CHECK:
917 optname = SO_NO_CHECK;
918 break;
919 case TARGET_SO_PRIORITY:
920 optname = SO_PRIORITY;
921 break;
922 #ifdef SO_BSDCOMPAT
923 case TARGET_SO_BSDCOMPAT:
924 optname = SO_BSDCOMPAT;
925 break;
926 #endif
927 case TARGET_SO_PASSCRED:
928 optname = SO_PASSCRED;
929 break;
930 case TARGET_SO_TIMESTAMP:
931 optname = SO_TIMESTAMP;
932 break;
933 case TARGET_SO_RCVLOWAT:
934 optname = SO_RCVLOWAT;
935 break;
936 case TARGET_SO_RCVTIMEO:
937 optname = SO_RCVTIMEO;
938 break;
939 case TARGET_SO_SNDTIMEO:
940 optname = SO_SNDTIMEO;
941 break;
942 break;
943 default:
944 goto unimplemented;
946 if (optlen < sizeof(uint32_t))
947 return -TARGET_EINVAL;
949 if (get_user_u32(val, optval_addr))
950 return -TARGET_EFAULT;
951 ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
952 break;
953 default:
954 unimplemented:
955 gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
956 ret = -TARGET_ENOPROTOOPT;
958 return ret;
961 /* do_getsockopt() Must return target values and target errnos. */
962 static abi_long do_getsockopt(int sockfd, int level, int optname,
963 abi_ulong optval_addr, abi_ulong optlen)
965 abi_long ret;
966 int len, val;
967 socklen_t lv;
969 switch(level) {
970 case TARGET_SOL_SOCKET:
971 level = SOL_SOCKET;
972 switch (optname) {
973 case TARGET_SO_LINGER:
974 case TARGET_SO_RCVTIMEO:
975 case TARGET_SO_SNDTIMEO:
976 case TARGET_SO_PEERCRED:
977 case TARGET_SO_PEERNAME:
978 /* These don't just return a single integer */
979 goto unimplemented;
980 default:
981 goto int_case;
983 break;
984 case SOL_TCP:
985 /* TCP options all take an 'int' value. */
986 int_case:
987 if (get_user_u32(len, optlen))
988 return -TARGET_EFAULT;
989 if (len < 0)
990 return -TARGET_EINVAL;
991 lv = sizeof(int);
992 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
993 if (ret < 0)
994 return ret;
995 val = tswap32(val);
996 if (len > lv)
997 len = lv;
998 if (len == 4) {
999 if (put_user_u32(val, optval_addr))
1000 return -TARGET_EFAULT;
1001 } else {
1002 if (put_user_u8(val, optval_addr))
1003 return -TARGET_EFAULT;
1005 if (put_user_u32(len, optlen))
1006 return -TARGET_EFAULT;
1007 break;
1008 case SOL_IP:
1009 switch(optname) {
1010 case IP_TOS:
1011 case IP_TTL:
1012 case IP_HDRINCL:
1013 case IP_ROUTER_ALERT:
1014 case IP_RECVOPTS:
1015 case IP_RETOPTS:
1016 case IP_PKTINFO:
1017 case IP_MTU_DISCOVER:
1018 case IP_RECVERR:
1019 case IP_RECVTOS:
1020 #ifdef IP_FREEBIND
1021 case IP_FREEBIND:
1022 #endif
1023 case IP_MULTICAST_TTL:
1024 case IP_MULTICAST_LOOP:
1025 if (get_user_u32(len, optlen))
1026 return -TARGET_EFAULT;
1027 if (len < 0)
1028 return -TARGET_EINVAL;
1029 lv = sizeof(int);
1030 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1031 if (ret < 0)
1032 return ret;
1033 if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
1034 len = 1;
1035 if (put_user_u32(len, optlen)
1036 || put_user_u8(val, optval_addr))
1037 return -TARGET_EFAULT;
1038 } else {
1039 if (len > sizeof(int))
1040 len = sizeof(int);
1041 if (put_user_u32(len, optlen)
1042 || put_user_u32(val, optval_addr))
1043 return -TARGET_EFAULT;
1045 break;
1046 default:
1047 ret = -TARGET_ENOPROTOOPT;
1048 break;
1050 break;
1051 default:
1052 unimplemented:
1053 gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1054 level, optname);
1055 ret = -TARGET_EOPNOTSUPP;
1056 break;
1058 return ret;
1061 /* FIXME
1062 * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1063 * other lock functions have a return code of 0 for failure.
1065 static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1066 int count, int copy)
1068 struct target_iovec *target_vec;
1069 abi_ulong base;
1070 int i;
1072 target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1073 if (!target_vec)
1074 return -TARGET_EFAULT;
1075 for(i = 0;i < count; i++) {
1076 base = tswapl(target_vec[i].iov_base);
1077 vec[i].iov_len = tswapl(target_vec[i].iov_len);
1078 if (vec[i].iov_len != 0) {
1079 vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
1080 /* Don't check lock_user return value. We must call writev even
1081 if a element has invalid base address. */
1082 } else {
1083 /* zero length pointer is ignored */
1084 vec[i].iov_base = NULL;
1087 unlock_user (target_vec, target_addr, 0);
1088 return 0;
1091 static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1092 int count, int copy)
1094 struct target_iovec *target_vec;
1095 abi_ulong base;
1096 int i;
1098 target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1099 if (!target_vec)
1100 return -TARGET_EFAULT;
1101 for(i = 0;i < count; i++) {
1102 if (target_vec[i].iov_base) {
1103 base = tswapl(target_vec[i].iov_base);
1104 unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1107 unlock_user (target_vec, target_addr, 0);
1109 return 0;
1112 /* do_socket() Must return target values and target errnos. */
1113 static abi_long do_socket(int domain, int type, int protocol)
1115 #if defined(TARGET_MIPS)
1116 switch(type) {
1117 case TARGET_SOCK_DGRAM:
1118 type = SOCK_DGRAM;
1119 break;
1120 case TARGET_SOCK_STREAM:
1121 type = SOCK_STREAM;
1122 break;
1123 case TARGET_SOCK_RAW:
1124 type = SOCK_RAW;
1125 break;
1126 case TARGET_SOCK_RDM:
1127 type = SOCK_RDM;
1128 break;
1129 case TARGET_SOCK_SEQPACKET:
1130 type = SOCK_SEQPACKET;
1131 break;
1132 case TARGET_SOCK_PACKET:
1133 type = SOCK_PACKET;
1134 break;
1136 #endif
1137 if (domain == PF_NETLINK)
1138 return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1139 return get_errno(socket(domain, type, protocol));
1142 /* do_bind() Must return target values and target errnos. */
1143 static abi_long do_bind(int sockfd, abi_ulong target_addr,
1144 socklen_t addrlen)
1146 void *addr = alloca(addrlen);
1148 target_to_host_sockaddr(addr, target_addr, addrlen);
1149 return get_errno(bind(sockfd, addr, addrlen));
1152 /* do_connect() Must return target values and target errnos. */
1153 static abi_long do_connect(int sockfd, abi_ulong target_addr,
1154 socklen_t addrlen)
1156 void *addr = alloca(addrlen);
1158 target_to_host_sockaddr(addr, target_addr, addrlen);
1159 return get_errno(connect(sockfd, addr, addrlen));
1162 /* do_sendrecvmsg() Must return target values and target errnos. */
1163 static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1164 int flags, int send)
1166 abi_long ret, len;
1167 struct target_msghdr *msgp;
1168 struct msghdr msg;
1169 int count;
1170 struct iovec *vec;
1171 abi_ulong target_vec;
1173 /* FIXME */
1174 if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1175 msgp,
1176 target_msg,
1177 send ? 1 : 0))
1178 return -TARGET_EFAULT;
1179 if (msgp->msg_name) {
1180 msg.msg_namelen = tswap32(msgp->msg_namelen);
1181 msg.msg_name = alloca(msg.msg_namelen);
1182 target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
1183 msg.msg_namelen);
1184 } else {
1185 msg.msg_name = NULL;
1186 msg.msg_namelen = 0;
1188 msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
1189 msg.msg_control = alloca(msg.msg_controllen);
1190 msg.msg_flags = tswap32(msgp->msg_flags);
1192 count = tswapl(msgp->msg_iovlen);
1193 vec = alloca(count * sizeof(struct iovec));
1194 target_vec = tswapl(msgp->msg_iov);
1195 lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1196 msg.msg_iovlen = count;
1197 msg.msg_iov = vec;
1199 if (send) {
1200 ret = target_to_host_cmsg(&msg, msgp);
1201 if (ret == 0)
1202 ret = get_errno(sendmsg(fd, &msg, flags));
1203 } else {
1204 ret = get_errno(recvmsg(fd, &msg, flags));
1205 if (!is_error(ret)) {
1206 len = ret;
1207 ret = host_to_target_cmsg(msgp, &msg);
1208 if (!is_error(ret))
1209 ret = len;
1212 unlock_iovec(vec, target_vec, count, !send);
1213 unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1214 return ret;
1217 /* do_accept() Must return target values and target errnos. */
1218 static abi_long do_accept(int fd, abi_ulong target_addr,
1219 abi_ulong target_addrlen_addr)
1221 socklen_t addrlen;
1222 void *addr;
1223 abi_long ret;
1225 if (get_user_u32(addrlen, target_addrlen_addr))
1226 return -TARGET_EFAULT;
1228 addr = alloca(addrlen);
1230 ret = get_errno(accept(fd, addr, &addrlen));
1231 if (!is_error(ret)) {
1232 host_to_target_sockaddr(target_addr, addr, addrlen);
1233 if (put_user_u32(addrlen, target_addrlen_addr))
1234 ret = -TARGET_EFAULT;
1236 return ret;
1239 /* do_getpeername() Must return target values and target errnos. */
1240 static abi_long do_getpeername(int fd, abi_ulong target_addr,
1241 abi_ulong target_addrlen_addr)
1243 socklen_t addrlen;
1244 void *addr;
1245 abi_long ret;
1247 if (get_user_u32(addrlen, target_addrlen_addr))
1248 return -TARGET_EFAULT;
1250 addr = alloca(addrlen);
1252 ret = get_errno(getpeername(fd, addr, &addrlen));
1253 if (!is_error(ret)) {
1254 host_to_target_sockaddr(target_addr, addr, addrlen);
1255 if (put_user_u32(addrlen, target_addrlen_addr))
1256 ret = -TARGET_EFAULT;
1258 return ret;
1261 /* do_getsockname() Must return target values and target errnos. */
1262 static abi_long do_getsockname(int fd, abi_ulong target_addr,
1263 abi_ulong target_addrlen_addr)
1265 socklen_t addrlen;
1266 void *addr;
1267 abi_long ret;
1269 if (get_user_u32(addrlen, target_addrlen_addr))
1270 return -TARGET_EFAULT;
1272 addr = alloca(addrlen);
1274 ret = get_errno(getsockname(fd, addr, &addrlen));
1275 if (!is_error(ret)) {
1276 host_to_target_sockaddr(target_addr, addr, addrlen);
1277 if (put_user_u32(addrlen, target_addrlen_addr))
1278 ret = -TARGET_EFAULT;
1280 return ret;
1283 /* do_socketpair() Must return target values and target errnos. */
1284 static abi_long do_socketpair(int domain, int type, int protocol,
1285 abi_ulong target_tab_addr)
1287 int tab[2];
1288 abi_long ret;
1290 ret = get_errno(socketpair(domain, type, protocol, tab));
1291 if (!is_error(ret)) {
1292 if (put_user_s32(tab[0], target_tab_addr)
1293 || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1294 ret = -TARGET_EFAULT;
1296 return ret;
1299 /* do_sendto() Must return target values and target errnos. */
1300 static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
1301 abi_ulong target_addr, socklen_t addrlen)
1303 void *addr;
1304 void *host_msg;
1305 abi_long ret;
1307 host_msg = lock_user(VERIFY_READ, msg, len, 1);
1308 if (!host_msg)
1309 return -TARGET_EFAULT;
1310 if (target_addr) {
1311 addr = alloca(addrlen);
1312 target_to_host_sockaddr(addr, target_addr, addrlen);
1313 ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
1314 } else {
1315 ret = get_errno(send(fd, host_msg, len, flags));
1317 unlock_user(host_msg, msg, 0);
1318 return ret;
1321 /* do_recvfrom() Must return target values and target errnos. */
1322 static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
1323 abi_ulong target_addr,
1324 abi_ulong target_addrlen)
1326 socklen_t addrlen;
1327 void *addr;
1328 void *host_msg;
1329 abi_long ret;
1331 host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
1332 if (!host_msg)
1333 return -TARGET_EFAULT;
1334 if (target_addr) {
1335 if (get_user_u32(addrlen, target_addrlen)) {
1336 ret = -TARGET_EFAULT;
1337 goto fail;
1339 addr = alloca(addrlen);
1340 ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
1341 } else {
1342 addr = NULL; /* To keep compiler quiet. */
1343 ret = get_errno(recv(fd, host_msg, len, flags));
1345 if (!is_error(ret)) {
1346 if (target_addr) {
1347 host_to_target_sockaddr(target_addr, addr, addrlen);
1348 if (put_user_u32(addrlen, target_addrlen)) {
1349 ret = -TARGET_EFAULT;
1350 goto fail;
1353 unlock_user(host_msg, msg, len);
1354 } else {
1355 fail:
1356 unlock_user(host_msg, msg, 0);
1358 return ret;
1361 #ifdef TARGET_NR_socketcall
1362 /* do_socketcall() Must return target values and target errnos. */
1363 static abi_long do_socketcall(int num, abi_ulong vptr)
1365 abi_long ret;
1366 const int n = sizeof(abi_ulong);
1368 switch(num) {
1369 case SOCKOP_socket:
1371 int domain, type, protocol;
1373 if (get_user_s32(domain, vptr)
1374 || get_user_s32(type, vptr + n)
1375 || get_user_s32(protocol, vptr + 2 * n))
1376 return -TARGET_EFAULT;
1378 ret = do_socket(domain, type, protocol);
1380 break;
1381 case SOCKOP_bind:
1383 int sockfd;
1384 abi_ulong target_addr;
1385 socklen_t addrlen;
1387 if (get_user_s32(sockfd, vptr)
1388 || get_user_ual(target_addr, vptr + n)
1389 || get_user_u32(addrlen, vptr + 2 * n))
1390 return -TARGET_EFAULT;
1392 ret = do_bind(sockfd, target_addr, addrlen);
1394 break;
1395 case SOCKOP_connect:
1397 int sockfd;
1398 abi_ulong target_addr;
1399 socklen_t addrlen;
1401 if (get_user_s32(sockfd, vptr)
1402 || get_user_ual(target_addr, vptr + n)
1403 || get_user_u32(addrlen, vptr + 2 * n))
1404 return -TARGET_EFAULT;
1406 ret = do_connect(sockfd, target_addr, addrlen);
1408 break;
1409 case SOCKOP_listen:
1411 int sockfd, backlog;
1413 if (get_user_s32(sockfd, vptr)
1414 || get_user_s32(backlog, vptr + n))
1415 return -TARGET_EFAULT;
1417 ret = get_errno(listen(sockfd, backlog));
1419 break;
1420 case SOCKOP_accept:
1422 int sockfd;
1423 abi_ulong target_addr, target_addrlen;
1425 if (get_user_s32(sockfd, vptr)
1426 || get_user_ual(target_addr, vptr + n)
1427 || get_user_u32(target_addrlen, vptr + 2 * n))
1428 return -TARGET_EFAULT;
1430 ret = do_accept(sockfd, target_addr, target_addrlen);
1432 break;
1433 case SOCKOP_getsockname:
1435 int sockfd;
1436 abi_ulong target_addr, target_addrlen;
1438 if (get_user_s32(sockfd, vptr)
1439 || get_user_ual(target_addr, vptr + n)
1440 || get_user_u32(target_addrlen, vptr + 2 * n))
1441 return -TARGET_EFAULT;
1443 ret = do_getsockname(sockfd, target_addr, target_addrlen);
1445 break;
1446 case SOCKOP_getpeername:
1448 int sockfd;
1449 abi_ulong target_addr, target_addrlen;
1451 if (get_user_s32(sockfd, vptr)
1452 || get_user_ual(target_addr, vptr + n)
1453 || get_user_u32(target_addrlen, vptr + 2 * n))
1454 return -TARGET_EFAULT;
1456 ret = do_getpeername(sockfd, target_addr, target_addrlen);
1458 break;
1459 case SOCKOP_socketpair:
1461 int domain, type, protocol;
1462 abi_ulong tab;
1464 if (get_user_s32(domain, vptr)
1465 || get_user_s32(type, vptr + n)
1466 || get_user_s32(protocol, vptr + 2 * n)
1467 || get_user_ual(tab, vptr + 3 * n))
1468 return -TARGET_EFAULT;
1470 ret = do_socketpair(domain, type, protocol, tab);
1472 break;
1473 case SOCKOP_send:
1475 int sockfd;
1476 abi_ulong msg;
1477 size_t len;
1478 int flags;
1480 if (get_user_s32(sockfd, vptr)
1481 || get_user_ual(msg, vptr + n)
1482 || get_user_ual(len, vptr + 2 * n)
1483 || get_user_s32(flags, vptr + 3 * n))
1484 return -TARGET_EFAULT;
1486 ret = do_sendto(sockfd, msg, len, flags, 0, 0);
1488 break;
1489 case SOCKOP_recv:
1491 int sockfd;
1492 abi_ulong msg;
1493 size_t len;
1494 int flags;
1496 if (get_user_s32(sockfd, vptr)
1497 || get_user_ual(msg, vptr + n)
1498 || get_user_ual(len, vptr + 2 * n)
1499 || get_user_s32(flags, vptr + 3 * n))
1500 return -TARGET_EFAULT;
1502 ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
1504 break;
1505 case SOCKOP_sendto:
1507 int sockfd;
1508 abi_ulong msg;
1509 size_t len;
1510 int flags;
1511 abi_ulong addr;
1512 socklen_t addrlen;
1514 if (get_user_s32(sockfd, vptr)
1515 || get_user_ual(msg, vptr + n)
1516 || get_user_ual(len, vptr + 2 * n)
1517 || get_user_s32(flags, vptr + 3 * n)
1518 || get_user_ual(addr, vptr + 4 * n)
1519 || get_user_u32(addrlen, vptr + 5 * n))
1520 return -TARGET_EFAULT;
1522 ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
1524 break;
1525 case SOCKOP_recvfrom:
1527 int sockfd;
1528 abi_ulong msg;
1529 size_t len;
1530 int flags;
1531 abi_ulong addr;
1532 socklen_t addrlen;
1534 if (get_user_s32(sockfd, vptr)
1535 || get_user_ual(msg, vptr + n)
1536 || get_user_ual(len, vptr + 2 * n)
1537 || get_user_s32(flags, vptr + 3 * n)
1538 || get_user_ual(addr, vptr + 4 * n)
1539 || get_user_u32(addrlen, vptr + 5 * n))
1540 return -TARGET_EFAULT;
1542 ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
1544 break;
1545 case SOCKOP_shutdown:
1547 int sockfd, how;
1549 if (get_user_s32(sockfd, vptr)
1550 || get_user_s32(how, vptr + n))
1551 return -TARGET_EFAULT;
1553 ret = get_errno(shutdown(sockfd, how));
1555 break;
1556 case SOCKOP_sendmsg:
1557 case SOCKOP_recvmsg:
1559 int fd;
1560 abi_ulong target_msg;
1561 int flags;
1563 if (get_user_s32(fd, vptr)
1564 || get_user_ual(target_msg, vptr + n)
1565 || get_user_s32(flags, vptr + 2 * n))
1566 return -TARGET_EFAULT;
1568 ret = do_sendrecvmsg(fd, target_msg, flags,
1569 (num == SOCKOP_sendmsg));
1571 break;
1572 case SOCKOP_setsockopt:
1574 int sockfd;
1575 int level;
1576 int optname;
1577 abi_ulong optval;
1578 socklen_t optlen;
1580 if (get_user_s32(sockfd, vptr)
1581 || get_user_s32(level, vptr + n)
1582 || get_user_s32(optname, vptr + 2 * n)
1583 || get_user_ual(optval, vptr + 3 * n)
1584 || get_user_u32(optlen, vptr + 4 * n))
1585 return -TARGET_EFAULT;
1587 ret = do_setsockopt(sockfd, level, optname, optval, optlen);
1589 break;
1590 case SOCKOP_getsockopt:
1592 int sockfd;
1593 int level;
1594 int optname;
1595 abi_ulong optval;
1596 socklen_t optlen;
1598 if (get_user_s32(sockfd, vptr)
1599 || get_user_s32(level, vptr + n)
1600 || get_user_s32(optname, vptr + 2 * n)
1601 || get_user_ual(optval, vptr + 3 * n)
1602 || get_user_u32(optlen, vptr + 4 * n))
1603 return -TARGET_EFAULT;
1605 ret = do_getsockopt(sockfd, level, optname, optval, optlen);
1607 break;
1608 default:
1609 gemu_log("Unsupported socketcall: %d\n", num);
1610 ret = -TARGET_ENOSYS;
1611 break;
1613 return ret;
1615 #endif
1617 #ifdef TARGET_NR_ipc
1618 #define N_SHM_REGIONS 32
1620 static struct shm_region {
1621 abi_ulong start;
1622 abi_ulong size;
1623 } shm_regions[N_SHM_REGIONS];
1624 #endif
1626 struct target_ipc_perm
1628 abi_long __key;
1629 abi_ulong uid;
1630 abi_ulong gid;
1631 abi_ulong cuid;
1632 abi_ulong cgid;
1633 unsigned short int mode;
1634 unsigned short int __pad1;
1635 unsigned short int __seq;
1636 unsigned short int __pad2;
1637 abi_ulong __unused1;
1638 abi_ulong __unused2;
1641 struct target_semid_ds
1643 struct target_ipc_perm sem_perm;
1644 abi_ulong sem_otime;
1645 abi_ulong __unused1;
1646 abi_ulong sem_ctime;
1647 abi_ulong __unused2;
1648 abi_ulong sem_nsems;
1649 abi_ulong __unused3;
1650 abi_ulong __unused4;
1653 static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
1654 abi_ulong target_addr)
1656 struct target_ipc_perm *target_ip;
1657 struct target_semid_ds *target_sd;
1659 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
1660 return -TARGET_EFAULT;
1661 target_ip=&(target_sd->sem_perm);
1662 host_ip->__key = tswapl(target_ip->__key);
1663 host_ip->uid = tswapl(target_ip->uid);
1664 host_ip->gid = tswapl(target_ip->gid);
1665 host_ip->cuid = tswapl(target_ip->cuid);
1666 host_ip->cgid = tswapl(target_ip->cgid);
1667 host_ip->mode = tswapl(target_ip->mode);
1668 unlock_user_struct(target_sd, target_addr, 0);
1669 return 0;
1672 static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
1673 struct ipc_perm *host_ip)
1675 struct target_ipc_perm *target_ip;
1676 struct target_semid_ds *target_sd;
1678 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
1679 return -TARGET_EFAULT;
1680 target_ip = &(target_sd->sem_perm);
1681 target_ip->__key = tswapl(host_ip->__key);
1682 target_ip->uid = tswapl(host_ip->uid);
1683 target_ip->gid = tswapl(host_ip->gid);
1684 target_ip->cuid = tswapl(host_ip->cuid);
1685 target_ip->cgid = tswapl(host_ip->cgid);
1686 target_ip->mode = tswapl(host_ip->mode);
1687 unlock_user_struct(target_sd, target_addr, 1);
1688 return 0;
1691 static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
1692 abi_ulong target_addr)
1694 struct target_semid_ds *target_sd;
1696 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
1697 return -TARGET_EFAULT;
1698 target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr);
1699 host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
1700 host_sd->sem_otime = tswapl(target_sd->sem_otime);
1701 host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
1702 unlock_user_struct(target_sd, target_addr, 0);
1703 return 0;
1706 static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
1707 struct semid_ds *host_sd)
1709 struct target_semid_ds *target_sd;
1711 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
1712 return -TARGET_EFAULT;
1713 host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm));
1714 target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
1715 target_sd->sem_otime = tswapl(host_sd->sem_otime);
1716 target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
1717 unlock_user_struct(target_sd, target_addr, 1);
1718 return 0;
1721 union semun {
1722 int val;
1723 struct semid_ds *buf;
1724 unsigned short *array;
1727 union target_semun {
1728 int val;
1729 abi_long buf;
1730 unsigned short int *array;
1733 static inline abi_long target_to_host_semun(int cmd,
1734 union semun *host_su,
1735 abi_ulong target_addr,
1736 struct semid_ds *ds)
1738 union target_semun *target_su;
1740 switch( cmd ) {
1741 case IPC_STAT:
1742 case IPC_SET:
1743 if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1744 return -TARGET_EFAULT;
1745 target_to_host_semid_ds(ds,target_su->buf);
1746 host_su->buf = ds;
1747 unlock_user_struct(target_su, target_addr, 0);
1748 break;
1749 case GETVAL:
1750 case SETVAL:
1751 if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1752 return -TARGET_EFAULT;
1753 host_su->val = tswapl(target_su->val);
1754 unlock_user_struct(target_su, target_addr, 0);
1755 break;
1756 case GETALL:
1757 case SETALL:
1758 if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1759 return -TARGET_EFAULT;
1760 *host_su->array = tswap16(*target_su->array);
1761 unlock_user_struct(target_su, target_addr, 0);
1762 break;
1763 default:
1764 gemu_log("semun operation not fully supported: %d\n", (int)cmd);
1766 return 0;
1769 static inline abi_long host_to_target_semun(int cmd,
1770 abi_ulong target_addr,
1771 union semun *host_su,
1772 struct semid_ds *ds)
1774 union target_semun *target_su;
1776 switch( cmd ) {
1777 case IPC_STAT:
1778 case IPC_SET:
1779 if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1780 return -TARGET_EFAULT;
1781 host_to_target_semid_ds(target_su->buf,ds);
1782 unlock_user_struct(target_su, target_addr, 1);
1783 break;
1784 case GETVAL:
1785 case SETVAL:
1786 if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1787 return -TARGET_EFAULT;
1788 target_su->val = tswapl(host_su->val);
1789 unlock_user_struct(target_su, target_addr, 1);
1790 break;
1791 case GETALL:
1792 case SETALL:
1793 if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1794 return -TARGET_EFAULT;
1795 *target_su->array = tswap16(*host_su->array);
1796 unlock_user_struct(target_su, target_addr, 1);
1797 break;
1798 default:
1799 gemu_log("semun operation not fully supported: %d\n", (int)cmd);
1801 return 0;
1804 static inline abi_long do_semctl(int first, int second, int third,
1805 abi_long ptr)
1807 union semun arg;
1808 struct semid_ds dsarg;
1809 int cmd = third&0xff;
1810 abi_long ret = 0;
1812 switch( cmd ) {
1813 case GETVAL:
1814 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1815 ret = get_errno(semctl(first, second, cmd, arg));
1816 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1817 break;
1818 case SETVAL:
1819 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1820 ret = get_errno(semctl(first, second, cmd, arg));
1821 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1822 break;
1823 case GETALL:
1824 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1825 ret = get_errno(semctl(first, second, cmd, arg));
1826 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1827 break;
1828 case SETALL:
1829 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1830 ret = get_errno(semctl(first, second, cmd, arg));
1831 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1832 break;
1833 case IPC_STAT:
1834 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1835 ret = get_errno(semctl(first, second, cmd, arg));
1836 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1837 break;
1838 case IPC_SET:
1839 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1840 ret = get_errno(semctl(first, second, cmd, arg));
1841 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1842 break;
1843 default:
1844 ret = get_errno(semctl(first, second, cmd, arg));
1847 return ret;
1850 struct target_msqid_ds
1852 struct target_ipc_perm msg_perm;
1853 abi_ulong msg_stime;
1854 #if TARGET_ABI_BITS == 32
1855 abi_ulong __unused1;
1856 #endif
1857 abi_ulong msg_rtime;
1858 #if TARGET_ABI_BITS == 32
1859 abi_ulong __unused2;
1860 #endif
1861 abi_ulong msg_ctime;
1862 #if TARGET_ABI_BITS == 32
1863 abi_ulong __unused3;
1864 #endif
1865 abi_ulong __msg_cbytes;
1866 abi_ulong msg_qnum;
1867 abi_ulong msg_qbytes;
1868 abi_ulong msg_lspid;
1869 abi_ulong msg_lrpid;
1870 abi_ulong __unused4;
1871 abi_ulong __unused5;
1874 static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
1875 abi_ulong target_addr)
1877 struct target_msqid_ds *target_md;
1879 if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
1880 return -TARGET_EFAULT;
1881 if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
1882 return -TARGET_EFAULT;
1883 host_md->msg_stime = tswapl(target_md->msg_stime);
1884 host_md->msg_rtime = tswapl(target_md->msg_rtime);
1885 host_md->msg_ctime = tswapl(target_md->msg_ctime);
1886 host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
1887 host_md->msg_qnum = tswapl(target_md->msg_qnum);
1888 host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
1889 host_md->msg_lspid = tswapl(target_md->msg_lspid);
1890 host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
1891 unlock_user_struct(target_md, target_addr, 0);
1892 return 0;
1895 static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
1896 struct msqid_ds *host_md)
1898 struct target_msqid_ds *target_md;
1900 if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
1901 return -TARGET_EFAULT;
1902 if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
1903 return -TARGET_EFAULT;
1904 target_md->msg_stime = tswapl(host_md->msg_stime);
1905 target_md->msg_rtime = tswapl(host_md->msg_rtime);
1906 target_md->msg_ctime = tswapl(host_md->msg_ctime);
1907 target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
1908 target_md->msg_qnum = tswapl(host_md->msg_qnum);
1909 target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
1910 target_md->msg_lspid = tswapl(host_md->msg_lspid);
1911 target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
1912 unlock_user_struct(target_md, target_addr, 1);
1913 return 0;
1916 struct target_msginfo {
1917 int msgpool;
1918 int msgmap;
1919 int msgmax;
1920 int msgmnb;
1921 int msgmni;
1922 int msgssz;
1923 int msgtql;
1924 unsigned short int msgseg;
1927 static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
1928 struct msginfo *host_msginfo)
1930 struct target_msginfo *target_msginfo;
1931 if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
1932 return -TARGET_EFAULT;
1933 __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
1934 __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
1935 __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
1936 __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
1937 __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
1938 __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
1939 __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
1940 __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
1941 unlock_user_struct(target_msginfo, target_addr, 1);
1942 return 0;
1945 static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
1947 struct msqid_ds dsarg;
1948 struct msginfo msginfo;
1949 abi_long ret = -TARGET_EINVAL;
1951 cmd &= 0xff;
1953 switch (cmd) {
1954 case IPC_STAT:
1955 case IPC_SET:
1956 case MSG_STAT:
1957 if (target_to_host_msqid_ds(&dsarg,ptr))
1958 return -TARGET_EFAULT;
1959 ret = get_errno(msgctl(msgid, cmd, &dsarg));
1960 if (host_to_target_msqid_ds(ptr,&dsarg))
1961 return -TARGET_EFAULT;
1962 break;
1963 case IPC_RMID:
1964 ret = get_errno(msgctl(msgid, cmd, NULL));
1965 break;
1966 case IPC_INFO:
1967 case MSG_INFO:
1968 ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
1969 if (host_to_target_msginfo(ptr, &msginfo))
1970 return -TARGET_EFAULT;
1971 break;
1974 return ret;
1977 struct target_msgbuf {
1978 abi_long mtype;
1979 char mtext[1];
1982 static inline abi_long do_msgsnd(int msqid, abi_long msgp,
1983 unsigned int msgsz, int msgflg)
1985 struct target_msgbuf *target_mb;
1986 struct msgbuf *host_mb;
1987 abi_long ret = 0;
1989 if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
1990 return -TARGET_EFAULT;
1991 host_mb = malloc(msgsz+sizeof(long));
1992 host_mb->mtype = (abi_long) tswapl(target_mb->mtype);
1993 memcpy(host_mb->mtext, target_mb->mtext, msgsz);
1994 ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
1995 free(host_mb);
1996 unlock_user_struct(target_mb, msgp, 0);
1998 return ret;
2001 static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2002 unsigned int msgsz, abi_long msgtyp,
2003 int msgflg)
2005 struct target_msgbuf *target_mb;
2006 char *target_mtext;
2007 struct msgbuf *host_mb;
2008 abi_long ret = 0;
2010 if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2011 return -TARGET_EFAULT;
2013 host_mb = malloc(msgsz+sizeof(long));
2014 ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapl(msgtyp), msgflg));
2016 if (ret > 0) {
2017 abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2018 target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2019 if (!target_mtext) {
2020 ret = -TARGET_EFAULT;
2021 goto end;
2023 memcpy(target_mb->mtext, host_mb->mtext, ret);
2024 unlock_user(target_mtext, target_mtext_addr, ret);
2027 target_mb->mtype = tswapl(host_mb->mtype);
2028 free(host_mb);
2030 end:
2031 if (target_mb)
2032 unlock_user_struct(target_mb, msgp, 1);
2033 return ret;
2036 #ifdef TARGET_NR_ipc
2037 /* ??? This only works with linear mappings. */
2038 /* do_ipc() must return target values and target errnos. */
2039 static abi_long do_ipc(unsigned int call, int first,
2040 int second, int third,
2041 abi_long ptr, abi_long fifth)
2043 int version;
2044 abi_long ret = 0;
2045 struct shmid_ds shm_info;
2046 int i;
2048 version = call >> 16;
2049 call &= 0xffff;
2051 switch (call) {
2052 case IPCOP_semop:
2053 ret = get_errno(semop(first,(struct sembuf *)g2h(ptr), second));
2054 break;
2056 case IPCOP_semget:
2057 ret = get_errno(semget(first, second, third));
2058 break;
2060 case IPCOP_semctl:
2061 ret = do_semctl(first, second, third, ptr);
2062 break;
2064 case IPCOP_semtimedop:
2065 gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2066 ret = -TARGET_ENOSYS;
2067 break;
2069 case IPCOP_msgget:
2070 ret = get_errno(msgget(first, second));
2071 break;
2073 case IPCOP_msgsnd:
2074 ret = do_msgsnd(first, ptr, second, third);
2075 break;
2077 case IPCOP_msgctl:
2078 ret = do_msgctl(first, second, ptr);
2079 break;
2081 case IPCOP_msgrcv:
2082 switch (version) {
2083 case 0:
2085 struct target_ipc_kludge {
2086 abi_long msgp;
2087 abi_long msgtyp;
2088 } *tmp;
2090 if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
2091 ret = -TARGET_EFAULT;
2092 break;
2095 ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
2097 unlock_user_struct(tmp, ptr, 0);
2098 break;
2100 default:
2101 ret = do_msgrcv(first, ptr, second, fifth, third);
2103 break;
2105 case IPCOP_shmat:
2107 abi_ulong raddr;
2108 void *host_addr;
2109 /* SHM_* flags are the same on all linux platforms */
2110 host_addr = shmat(first, (void *)g2h(ptr), second);
2111 if (host_addr == (void *)-1) {
2112 ret = get_errno((long)host_addr);
2113 break;
2115 raddr = h2g((unsigned long)host_addr);
2116 /* find out the length of the shared memory segment */
2118 ret = get_errno(shmctl(first, IPC_STAT, &shm_info));
2119 if (is_error(ret)) {
2120 /* can't get length, bail out */
2121 shmdt(host_addr);
2122 break;
2124 page_set_flags(raddr, raddr + shm_info.shm_segsz,
2125 PAGE_VALID | PAGE_READ |
2126 ((second & SHM_RDONLY)? 0: PAGE_WRITE));
2127 for (i = 0; i < N_SHM_REGIONS; ++i) {
2128 if (shm_regions[i].start == 0) {
2129 shm_regions[i].start = raddr;
2130 shm_regions[i].size = shm_info.shm_segsz;
2131 break;
2134 if (put_user_ual(raddr, third))
2135 return -TARGET_EFAULT;
2136 ret = 0;
2138 break;
2139 case IPCOP_shmdt:
2140 for (i = 0; i < N_SHM_REGIONS; ++i) {
2141 if (shm_regions[i].start == ptr) {
2142 shm_regions[i].start = 0;
2143 page_set_flags(ptr, shm_regions[i].size, 0);
2144 break;
2147 ret = get_errno(shmdt((void *)g2h(ptr)));
2148 break;
2150 case IPCOP_shmget:
2151 /* IPC_* flag values are the same on all linux platforms */
2152 ret = get_errno(shmget(first, second, third));
2153 break;
2155 /* IPC_* and SHM_* command values are the same on all linux platforms */
2156 case IPCOP_shmctl:
2157 switch(second) {
2158 case IPC_RMID:
2159 case SHM_LOCK:
2160 case SHM_UNLOCK:
2161 ret = get_errno(shmctl(first, second, NULL));
2162 break;
2163 default:
2164 goto unimplemented;
2166 break;
2167 default:
2168 unimplemented:
2169 gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2170 ret = -TARGET_ENOSYS;
2171 break;
2173 return ret;
2175 #endif
2177 /* kernel structure types definitions */
2178 #define IFNAMSIZ 16
2180 #define STRUCT(name, list...) STRUCT_ ## name,
2181 #define STRUCT_SPECIAL(name) STRUCT_ ## name,
2182 enum {
2183 #include "syscall_types.h"
2185 #undef STRUCT
2186 #undef STRUCT_SPECIAL
2188 #define STRUCT(name, list...) static const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };
2189 #define STRUCT_SPECIAL(name)
2190 #include "syscall_types.h"
2191 #undef STRUCT
2192 #undef STRUCT_SPECIAL
2194 typedef struct IOCTLEntry {
2195 unsigned int target_cmd;
2196 unsigned int host_cmd;
2197 const char *name;
2198 int access;
2199 const argtype arg_type[5];
2200 } IOCTLEntry;
2202 #define IOC_R 0x0001
2203 #define IOC_W 0x0002
2204 #define IOC_RW (IOC_R | IOC_W)
2206 #define MAX_STRUCT_SIZE 4096
2208 static IOCTLEntry ioctl_entries[] = {
2209 #define IOCTL(cmd, access, types...) \
2210 { TARGET_ ## cmd, cmd, #cmd, access, { types } },
2211 #include "ioctls.h"
2212 { 0, 0, },
2215 /* ??? Implement proper locking for ioctls. */
2216 /* do_ioctl() Must return target values and target errnos. */
2217 static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
2219 const IOCTLEntry *ie;
2220 const argtype *arg_type;
2221 abi_long ret;
2222 uint8_t buf_temp[MAX_STRUCT_SIZE];
2223 int target_size;
2224 void *argptr;
2226 ie = ioctl_entries;
2227 for(;;) {
2228 if (ie->target_cmd == 0) {
2229 gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
2230 return -TARGET_ENOSYS;
2232 if (ie->target_cmd == cmd)
2233 break;
2234 ie++;
2236 arg_type = ie->arg_type;
2237 #if defined(DEBUG)
2238 gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
2239 #endif
2240 switch(arg_type[0]) {
2241 case TYPE_NULL:
2242 /* no argument */
2243 ret = get_errno(ioctl(fd, ie->host_cmd));
2244 break;
2245 case TYPE_PTRVOID:
2246 case TYPE_INT:
2247 /* int argment */
2248 ret = get_errno(ioctl(fd, ie->host_cmd, arg));
2249 break;
2250 case TYPE_PTR:
2251 arg_type++;
2252 target_size = thunk_type_size(arg_type, 0);
2253 switch(ie->access) {
2254 case IOC_R:
2255 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2256 if (!is_error(ret)) {
2257 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2258 if (!argptr)
2259 return -TARGET_EFAULT;
2260 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2261 unlock_user(argptr, arg, target_size);
2263 break;
2264 case IOC_W:
2265 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2266 if (!argptr)
2267 return -TARGET_EFAULT;
2268 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2269 unlock_user(argptr, arg, 0);
2270 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2271 break;
2272 default:
2273 case IOC_RW:
2274 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2275 if (!argptr)
2276 return -TARGET_EFAULT;
2277 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2278 unlock_user(argptr, arg, 0);
2279 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2280 if (!is_error(ret)) {
2281 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2282 if (!argptr)
2283 return -TARGET_EFAULT;
2284 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2285 unlock_user(argptr, arg, target_size);
2287 break;
2289 break;
2290 default:
2291 gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
2292 (long)cmd, arg_type[0]);
2293 ret = -TARGET_ENOSYS;
2294 break;
2296 return ret;
2299 static const bitmask_transtbl iflag_tbl[] = {
2300 { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
2301 { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
2302 { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
2303 { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
2304 { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
2305 { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
2306 { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
2307 { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
2308 { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
2309 { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
2310 { TARGET_IXON, TARGET_IXON, IXON, IXON },
2311 { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
2312 { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
2313 { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
2314 { 0, 0, 0, 0 }
2317 static const bitmask_transtbl oflag_tbl[] = {
2318 { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
2319 { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
2320 { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
2321 { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
2322 { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
2323 { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
2324 { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
2325 { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
2326 { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
2327 { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
2328 { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
2329 { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
2330 { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
2331 { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
2332 { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
2333 { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
2334 { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
2335 { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
2336 { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
2337 { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
2338 { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
2339 { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
2340 { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
2341 { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
2342 { 0, 0, 0, 0 }
2345 static const bitmask_transtbl cflag_tbl[] = {
2346 { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
2347 { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
2348 { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
2349 { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
2350 { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
2351 { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
2352 { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
2353 { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
2354 { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
2355 { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
2356 { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
2357 { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
2358 { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
2359 { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
2360 { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
2361 { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
2362 { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
2363 { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
2364 { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
2365 { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
2366 { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
2367 { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
2368 { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
2369 { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
2370 { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
2371 { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
2372 { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
2373 { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
2374 { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
2375 { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
2376 { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
2377 { 0, 0, 0, 0 }
2380 static const bitmask_transtbl lflag_tbl[] = {
2381 { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
2382 { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
2383 { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
2384 { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
2385 { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
2386 { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
2387 { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
2388 { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
2389 { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
2390 { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
2391 { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
2392 { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
2393 { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
2394 { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
2395 { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
2396 { 0, 0, 0, 0 }
2399 static void target_to_host_termios (void *dst, const void *src)
2401 struct host_termios *host = dst;
2402 const struct target_termios *target = src;
2404 host->c_iflag =
2405 target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
2406 host->c_oflag =
2407 target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
2408 host->c_cflag =
2409 target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
2410 host->c_lflag =
2411 target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
2412 host->c_line = target->c_line;
2414 host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
2415 host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
2416 host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
2417 host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
2418 host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
2419 host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
2420 host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
2421 host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
2422 host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
2423 host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
2424 host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
2425 host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
2426 host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
2427 host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
2428 host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
2429 host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
2430 host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
2433 static void host_to_target_termios (void *dst, const void *src)
2435 struct target_termios *target = dst;
2436 const struct host_termios *host = src;
2438 target->c_iflag =
2439 tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
2440 target->c_oflag =
2441 tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
2442 target->c_cflag =
2443 tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
2444 target->c_lflag =
2445 tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
2446 target->c_line = host->c_line;
2448 target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
2449 target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
2450 target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
2451 target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
2452 target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
2453 target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
2454 target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
2455 target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
2456 target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
2457 target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
2458 target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
2459 target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
2460 target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
2461 target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
2462 target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
2463 target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
2464 target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
2467 static const StructEntry struct_termios_def = {
2468 .convert = { host_to_target_termios, target_to_host_termios },
2469 .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
2470 .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
2473 static bitmask_transtbl mmap_flags_tbl[] = {
2474 { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
2475 { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
2476 { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
2477 { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
2478 { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
2479 { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
2480 { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
2481 { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
2482 { 0, 0, 0, 0 }
2485 static bitmask_transtbl fcntl_flags_tbl[] = {
2486 { TARGET_O_ACCMODE, TARGET_O_WRONLY, O_ACCMODE, O_WRONLY, },
2487 { TARGET_O_ACCMODE, TARGET_O_RDWR, O_ACCMODE, O_RDWR, },
2488 { TARGET_O_CREAT, TARGET_O_CREAT, O_CREAT, O_CREAT, },
2489 { TARGET_O_EXCL, TARGET_O_EXCL, O_EXCL, O_EXCL, },
2490 { TARGET_O_NOCTTY, TARGET_O_NOCTTY, O_NOCTTY, O_NOCTTY, },
2491 { TARGET_O_TRUNC, TARGET_O_TRUNC, O_TRUNC, O_TRUNC, },
2492 { TARGET_O_APPEND, TARGET_O_APPEND, O_APPEND, O_APPEND, },
2493 { TARGET_O_NONBLOCK, TARGET_O_NONBLOCK, O_NONBLOCK, O_NONBLOCK, },
2494 { TARGET_O_SYNC, TARGET_O_SYNC, O_SYNC, O_SYNC, },
2495 { TARGET_FASYNC, TARGET_FASYNC, FASYNC, FASYNC, },
2496 { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
2497 { TARGET_O_NOFOLLOW, TARGET_O_NOFOLLOW, O_NOFOLLOW, O_NOFOLLOW, },
2498 { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
2499 #if defined(O_DIRECT)
2500 { TARGET_O_DIRECT, TARGET_O_DIRECT, O_DIRECT, O_DIRECT, },
2501 #endif
2502 { 0, 0, 0, 0 }
2505 #if defined(TARGET_I386)
2507 /* NOTE: there is really one LDT for all the threads */
2508 static uint8_t *ldt_table;
2510 static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
2512 int size;
2513 void *p;
2515 if (!ldt_table)
2516 return 0;
2517 size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
2518 if (size > bytecount)
2519 size = bytecount;
2520 p = lock_user(VERIFY_WRITE, ptr, size, 0);
2521 if (!p)
2522 return -TARGET_EFAULT;
2523 /* ??? Should this by byteswapped? */
2524 memcpy(p, ldt_table, size);
2525 unlock_user(p, ptr, size);
2526 return size;
2529 /* XXX: add locking support */
2530 static abi_long write_ldt(CPUX86State *env,
2531 abi_ulong ptr, unsigned long bytecount, int oldmode)
2533 struct target_modify_ldt_ldt_s ldt_info;
2534 struct target_modify_ldt_ldt_s *target_ldt_info;
2535 int seg_32bit, contents, read_exec_only, limit_in_pages;
2536 int seg_not_present, useable, lm;
2537 uint32_t *lp, entry_1, entry_2;
2539 if (bytecount != sizeof(ldt_info))
2540 return -TARGET_EINVAL;
2541 if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
2542 return -TARGET_EFAULT;
2543 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2544 ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2545 ldt_info.limit = tswap32(target_ldt_info->limit);
2546 ldt_info.flags = tswap32(target_ldt_info->flags);
2547 unlock_user_struct(target_ldt_info, ptr, 0);
2549 if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
2550 return -TARGET_EINVAL;
2551 seg_32bit = ldt_info.flags & 1;
2552 contents = (ldt_info.flags >> 1) & 3;
2553 read_exec_only = (ldt_info.flags >> 3) & 1;
2554 limit_in_pages = (ldt_info.flags >> 4) & 1;
2555 seg_not_present = (ldt_info.flags >> 5) & 1;
2556 useable = (ldt_info.flags >> 6) & 1;
2557 #ifdef TARGET_ABI32
2558 lm = 0;
2559 #else
2560 lm = (ldt_info.flags >> 7) & 1;
2561 #endif
2562 if (contents == 3) {
2563 if (oldmode)
2564 return -TARGET_EINVAL;
2565 if (seg_not_present == 0)
2566 return -TARGET_EINVAL;
2568 /* allocate the LDT */
2569 if (!ldt_table) {
2570 env->ldt.base = target_mmap(0,
2571 TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
2572 PROT_READ|PROT_WRITE,
2573 MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
2574 if (env->ldt.base == -1)
2575 return -TARGET_ENOMEM;
2576 memset(g2h(env->ldt.base), 0,
2577 TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
2578 env->ldt.limit = 0xffff;
2579 ldt_table = g2h(env->ldt.base);
2582 /* NOTE: same code as Linux kernel */
2583 /* Allow LDTs to be cleared by the user. */
2584 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2585 if (oldmode ||
2586 (contents == 0 &&
2587 read_exec_only == 1 &&
2588 seg_32bit == 0 &&
2589 limit_in_pages == 0 &&
2590 seg_not_present == 1 &&
2591 useable == 0 )) {
2592 entry_1 = 0;
2593 entry_2 = 0;
2594 goto install;
2598 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2599 (ldt_info.limit & 0x0ffff);
2600 entry_2 = (ldt_info.base_addr & 0xff000000) |
2601 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2602 (ldt_info.limit & 0xf0000) |
2603 ((read_exec_only ^ 1) << 9) |
2604 (contents << 10) |
2605 ((seg_not_present ^ 1) << 15) |
2606 (seg_32bit << 22) |
2607 (limit_in_pages << 23) |
2608 (lm << 21) |
2609 0x7000;
2610 if (!oldmode)
2611 entry_2 |= (useable << 20);
2613 /* Install the new entry ... */
2614 install:
2615 lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
2616 lp[0] = tswap32(entry_1);
2617 lp[1] = tswap32(entry_2);
2618 return 0;
2621 /* specific and weird i386 syscalls */
2622 static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
2623 unsigned long bytecount)
2625 abi_long ret;
2627 switch (func) {
2628 case 0:
2629 ret = read_ldt(ptr, bytecount);
2630 break;
2631 case 1:
2632 ret = write_ldt(env, ptr, bytecount, 1);
2633 break;
2634 case 0x11:
2635 ret = write_ldt(env, ptr, bytecount, 0);
2636 break;
2637 default:
2638 ret = -TARGET_ENOSYS;
2639 break;
2641 return ret;
2644 #if defined(TARGET_I386) && defined(TARGET_ABI32)
2645 static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
2647 uint64_t *gdt_table = g2h(env->gdt.base);
2648 struct target_modify_ldt_ldt_s ldt_info;
2649 struct target_modify_ldt_ldt_s *target_ldt_info;
2650 int seg_32bit, contents, read_exec_only, limit_in_pages;
2651 int seg_not_present, useable, lm;
2652 uint32_t *lp, entry_1, entry_2;
2653 int i;
2655 lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
2656 if (!target_ldt_info)
2657 return -TARGET_EFAULT;
2658 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2659 ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2660 ldt_info.limit = tswap32(target_ldt_info->limit);
2661 ldt_info.flags = tswap32(target_ldt_info->flags);
2662 if (ldt_info.entry_number == -1) {
2663 for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
2664 if (gdt_table[i] == 0) {
2665 ldt_info.entry_number = i;
2666 target_ldt_info->entry_number = tswap32(i);
2667 break;
2671 unlock_user_struct(target_ldt_info, ptr, 1);
2673 if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN ||
2674 ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
2675 return -TARGET_EINVAL;
2676 seg_32bit = ldt_info.flags & 1;
2677 contents = (ldt_info.flags >> 1) & 3;
2678 read_exec_only = (ldt_info.flags >> 3) & 1;
2679 limit_in_pages = (ldt_info.flags >> 4) & 1;
2680 seg_not_present = (ldt_info.flags >> 5) & 1;
2681 useable = (ldt_info.flags >> 6) & 1;
2682 #ifdef TARGET_ABI32
2683 lm = 0;
2684 #else
2685 lm = (ldt_info.flags >> 7) & 1;
2686 #endif
2688 if (contents == 3) {
2689 if (seg_not_present == 0)
2690 return -TARGET_EINVAL;
2693 /* NOTE: same code as Linux kernel */
2694 /* Allow LDTs to be cleared by the user. */
2695 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2696 if ((contents == 0 &&
2697 read_exec_only == 1 &&
2698 seg_32bit == 0 &&
2699 limit_in_pages == 0 &&
2700 seg_not_present == 1 &&
2701 useable == 0 )) {
2702 entry_1 = 0;
2703 entry_2 = 0;
2704 goto install;
2708 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2709 (ldt_info.limit & 0x0ffff);
2710 entry_2 = (ldt_info.base_addr & 0xff000000) |
2711 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2712 (ldt_info.limit & 0xf0000) |
2713 ((read_exec_only ^ 1) << 9) |
2714 (contents << 10) |
2715 ((seg_not_present ^ 1) << 15) |
2716 (seg_32bit << 22) |
2717 (limit_in_pages << 23) |
2718 (useable << 20) |
2719 (lm << 21) |
2720 0x7000;
2722 /* Install the new entry ... */
2723 install:
2724 lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
2725 lp[0] = tswap32(entry_1);
2726 lp[1] = tswap32(entry_2);
2727 return 0;
2730 static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
2732 struct target_modify_ldt_ldt_s *target_ldt_info;
2733 uint64_t *gdt_table = g2h(env->gdt.base);
2734 uint32_t base_addr, limit, flags;
2735 int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
2736 int seg_not_present, useable, lm;
2737 uint32_t *lp, entry_1, entry_2;
2739 lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
2740 if (!target_ldt_info)
2741 return -TARGET_EFAULT;
2742 idx = tswap32(target_ldt_info->entry_number);
2743 if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
2744 idx > TARGET_GDT_ENTRY_TLS_MAX) {
2745 unlock_user_struct(target_ldt_info, ptr, 1);
2746 return -TARGET_EINVAL;
2748 lp = (uint32_t *)(gdt_table + idx);
2749 entry_1 = tswap32(lp[0]);
2750 entry_2 = tswap32(lp[1]);
2752 read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
2753 contents = (entry_2 >> 10) & 3;
2754 seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
2755 seg_32bit = (entry_2 >> 22) & 1;
2756 limit_in_pages = (entry_2 >> 23) & 1;
2757 useable = (entry_2 >> 20) & 1;
2758 #ifdef TARGET_ABI32
2759 lm = 0;
2760 #else
2761 lm = (entry_2 >> 21) & 1;
2762 #endif
2763 flags = (seg_32bit << 0) | (contents << 1) |
2764 (read_exec_only << 3) | (limit_in_pages << 4) |
2765 (seg_not_present << 5) | (useable << 6) | (lm << 7);
2766 limit = (entry_1 & 0xffff) | (entry_2 & 0xf0000);
2767 base_addr = (entry_1 >> 16) |
2768 (entry_2 & 0xff000000) |
2769 ((entry_2 & 0xff) << 16);
2770 target_ldt_info->base_addr = tswapl(base_addr);
2771 target_ldt_info->limit = tswap32(limit);
2772 target_ldt_info->flags = tswap32(flags);
2773 unlock_user_struct(target_ldt_info, ptr, 1);
2774 return 0;
2776 #endif /* TARGET_I386 && TARGET_ABI32 */
2778 #ifndef TARGET_ABI32
2779 static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
2781 abi_long ret;
2782 abi_ulong val;
2783 int idx;
2785 switch(code) {
2786 case TARGET_ARCH_SET_GS:
2787 case TARGET_ARCH_SET_FS:
2788 if (code == TARGET_ARCH_SET_GS)
2789 idx = R_GS;
2790 else
2791 idx = R_FS;
2792 cpu_x86_load_seg(env, idx, 0);
2793 env->segs[idx].base = addr;
2794 break;
2795 case TARGET_ARCH_GET_GS:
2796 case TARGET_ARCH_GET_FS:
2797 if (code == TARGET_ARCH_GET_GS)
2798 idx = R_GS;
2799 else
2800 idx = R_FS;
2801 val = env->segs[idx].base;
2802 if (put_user(val, addr, abi_ulong))
2803 return -TARGET_EFAULT;
2804 break;
2805 default:
2806 ret = -TARGET_EINVAL;
2807 break;
2809 return 0;
2811 #endif
2813 #endif /* defined(TARGET_I386) */
2815 #if defined(USE_NPTL)
2817 #define NEW_STACK_SIZE PTHREAD_STACK_MIN
2819 static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
2820 typedef struct {
2821 CPUState *env;
2822 pthread_mutex_t mutex;
2823 pthread_cond_t cond;
2824 pthread_t thread;
2825 uint32_t tid;
2826 abi_ulong child_tidptr;
2827 abi_ulong parent_tidptr;
2828 sigset_t sigmask;
2829 } new_thread_info;
2831 static void *clone_func(void *arg)
2833 new_thread_info *info = arg;
2834 CPUState *env;
2836 env = info->env;
2837 thread_env = env;
2838 info->tid = gettid();
2839 if (info->child_tidptr)
2840 put_user_u32(info->tid, info->child_tidptr);
2841 if (info->parent_tidptr)
2842 put_user_u32(info->tid, info->parent_tidptr);
2843 /* Enable signals. */
2844 sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
2845 /* Signal to the parent that we're ready. */
2846 pthread_mutex_lock(&info->mutex);
2847 pthread_cond_broadcast(&info->cond);
2848 pthread_mutex_unlock(&info->mutex);
2849 /* Wait until the parent has finshed initializing the tls state. */
2850 pthread_mutex_lock(&clone_lock);
2851 pthread_mutex_unlock(&clone_lock);
2852 cpu_loop(env);
2853 /* never exits */
2854 return NULL;
2856 #else
2857 /* this stack is the equivalent of the kernel stack associated with a
2858 thread/process */
2859 #define NEW_STACK_SIZE 8192
2861 static int clone_func(void *arg)
2863 CPUState *env = arg;
2864 cpu_loop(env);
2865 /* never exits */
2866 return 0;
2868 #endif
2870 /* do_fork() Must return host values and target errnos (unlike most
2871 do_*() functions). */
2872 static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
2873 abi_ulong parent_tidptr, target_ulong newtls,
2874 abi_ulong child_tidptr)
2876 int ret;
2877 TaskState *ts;
2878 uint8_t *new_stack;
2879 CPUState *new_env;
2880 #if defined(USE_NPTL)
2881 unsigned int nptl_flags;
2882 sigset_t sigmask;
2883 #endif
2885 /* Emulate vfork() with fork() */
2886 if (flags & CLONE_VFORK)
2887 flags &= ~(CLONE_VFORK | CLONE_VM);
2889 if (flags & CLONE_VM) {
2890 #if defined(USE_NPTL)
2891 new_thread_info info;
2892 pthread_attr_t attr;
2893 #endif
2894 ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
2895 init_task_state(ts);
2896 new_stack = ts->stack;
2897 /* we create a new CPU instance. */
2898 new_env = cpu_copy(env);
2899 /* Init regs that differ from the parent. */
2900 cpu_clone_regs(new_env, newsp);
2901 new_env->opaque = ts;
2902 #if defined(USE_NPTL)
2903 nptl_flags = flags;
2904 flags &= ~CLONE_NPTL_FLAGS2;
2906 /* TODO: Implement CLONE_CHILD_CLEARTID. */
2907 if (nptl_flags & CLONE_SETTLS)
2908 cpu_set_tls (new_env, newtls);
2910 /* Grab a mutex so that thread setup appears atomic. */
2911 pthread_mutex_lock(&clone_lock);
2913 memset(&info, 0, sizeof(info));
2914 pthread_mutex_init(&info.mutex, NULL);
2915 pthread_mutex_lock(&info.mutex);
2916 pthread_cond_init(&info.cond, NULL);
2917 info.env = new_env;
2918 if (nptl_flags & CLONE_CHILD_SETTID)
2919 info.child_tidptr = child_tidptr;
2920 if (nptl_flags & CLONE_PARENT_SETTID)
2921 info.parent_tidptr = parent_tidptr;
2923 ret = pthread_attr_init(&attr);
2924 ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE);
2925 /* It is not safe to deliver signals until the child has finished
2926 initializing, so temporarily block all signals. */
2927 sigfillset(&sigmask);
2928 sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
2930 ret = pthread_create(&info.thread, &attr, clone_func, &info);
2932 sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
2933 pthread_attr_destroy(&attr);
2934 if (ret == 0) {
2935 /* Wait for the child to initialize. */
2936 pthread_cond_wait(&info.cond, &info.mutex);
2937 ret = info.tid;
2938 if (flags & CLONE_PARENT_SETTID)
2939 put_user_u32(ret, parent_tidptr);
2940 } else {
2941 ret = -1;
2943 pthread_mutex_unlock(&info.mutex);
2944 pthread_cond_destroy(&info.cond);
2945 pthread_mutex_destroy(&info.mutex);
2946 pthread_mutex_unlock(&clone_lock);
2947 #else
2948 if (flags & CLONE_NPTL_FLAGS2)
2949 return -EINVAL;
2950 /* This is probably going to die very quickly, but do it anyway. */
2951 #ifdef __ia64__
2952 ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
2953 #else
2954 ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
2955 #endif
2956 #endif
2957 } else {
2958 /* if no CLONE_VM, we consider it is a fork */
2959 if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
2960 return -EINVAL;
2961 fork_start();
2962 ret = fork();
2963 if (ret == 0) {
2964 /* Child Process. */
2965 cpu_clone_regs(env, newsp);
2966 fork_end(1);
2967 #if defined(USE_NPTL)
2968 /* There is a race condition here. The parent process could
2969 theoretically read the TID in the child process before the child
2970 tid is set. This would require using either ptrace
2971 (not implemented) or having *_tidptr to point at a shared memory
2972 mapping. We can't repeat the spinlock hack used above because
2973 the child process gets its own copy of the lock. */
2974 if (flags & CLONE_CHILD_SETTID)
2975 put_user_u32(gettid(), child_tidptr);
2976 if (flags & CLONE_PARENT_SETTID)
2977 put_user_u32(gettid(), parent_tidptr);
2978 ts = (TaskState *)env->opaque;
2979 if (flags & CLONE_SETTLS)
2980 cpu_set_tls (env, newtls);
2981 /* TODO: Implement CLONE_CHILD_CLEARTID. */
2982 #endif
2983 } else {
2984 fork_end(0);
2987 return ret;
2990 static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
2992 struct flock fl;
2993 struct target_flock *target_fl;
2994 struct flock64 fl64;
2995 struct target_flock64 *target_fl64;
2996 abi_long ret;
2998 switch(cmd) {
2999 case TARGET_F_GETLK:
3000 if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3001 return -TARGET_EFAULT;
3002 fl.l_type = tswap16(target_fl->l_type);
3003 fl.l_whence = tswap16(target_fl->l_whence);
3004 fl.l_start = tswapl(target_fl->l_start);
3005 fl.l_len = tswapl(target_fl->l_len);
3006 fl.l_pid = tswapl(target_fl->l_pid);
3007 unlock_user_struct(target_fl, arg, 0);
3008 ret = get_errno(fcntl(fd, cmd, &fl));
3009 if (ret == 0) {
3010 if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
3011 return -TARGET_EFAULT;
3012 target_fl->l_type = tswap16(fl.l_type);
3013 target_fl->l_whence = tswap16(fl.l_whence);
3014 target_fl->l_start = tswapl(fl.l_start);
3015 target_fl->l_len = tswapl(fl.l_len);
3016 target_fl->l_pid = tswapl(fl.l_pid);
3017 unlock_user_struct(target_fl, arg, 1);
3019 break;
3021 case TARGET_F_SETLK:
3022 case TARGET_F_SETLKW:
3023 if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3024 return -TARGET_EFAULT;
3025 fl.l_type = tswap16(target_fl->l_type);
3026 fl.l_whence = tswap16(target_fl->l_whence);
3027 fl.l_start = tswapl(target_fl->l_start);
3028 fl.l_len = tswapl(target_fl->l_len);
3029 fl.l_pid = tswapl(target_fl->l_pid);
3030 unlock_user_struct(target_fl, arg, 0);
3031 ret = get_errno(fcntl(fd, cmd, &fl));
3032 break;
3034 case TARGET_F_GETLK64:
3035 if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3036 return -TARGET_EFAULT;
3037 fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3038 fl64.l_whence = tswap16(target_fl64->l_whence);
3039 fl64.l_start = tswapl(target_fl64->l_start);
3040 fl64.l_len = tswapl(target_fl64->l_len);
3041 fl64.l_pid = tswap16(target_fl64->l_pid);
3042 unlock_user_struct(target_fl64, arg, 0);
3043 ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
3044 if (ret == 0) {
3045 if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
3046 return -TARGET_EFAULT;
3047 target_fl64->l_type = tswap16(fl64.l_type) >> 1;
3048 target_fl64->l_whence = tswap16(fl64.l_whence);
3049 target_fl64->l_start = tswapl(fl64.l_start);
3050 target_fl64->l_len = tswapl(fl64.l_len);
3051 target_fl64->l_pid = tswapl(fl64.l_pid);
3052 unlock_user_struct(target_fl64, arg, 1);
3054 break;
3055 case TARGET_F_SETLK64:
3056 case TARGET_F_SETLKW64:
3057 if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3058 return -TARGET_EFAULT;
3059 fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3060 fl64.l_whence = tswap16(target_fl64->l_whence);
3061 fl64.l_start = tswapl(target_fl64->l_start);
3062 fl64.l_len = tswapl(target_fl64->l_len);
3063 fl64.l_pid = tswap16(target_fl64->l_pid);
3064 unlock_user_struct(target_fl64, arg, 0);
3065 ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
3066 break;
3068 case F_GETFL:
3069 ret = get_errno(fcntl(fd, cmd, arg));
3070 if (ret >= 0) {
3071 ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
3073 break;
3075 case F_SETFL:
3076 ret = get_errno(fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
3077 break;
3079 default:
3080 ret = get_errno(fcntl(fd, cmd, arg));
3081 break;
3083 return ret;
3086 #ifdef USE_UID16
3088 static inline int high2lowuid(int uid)
3090 if (uid > 65535)
3091 return 65534;
3092 else
3093 return uid;
3096 static inline int high2lowgid(int gid)
3098 if (gid > 65535)
3099 return 65534;
3100 else
3101 return gid;
3104 static inline int low2highuid(int uid)
3106 if ((int16_t)uid == -1)
3107 return -1;
3108 else
3109 return uid;
3112 static inline int low2highgid(int gid)
3114 if ((int16_t)gid == -1)
3115 return -1;
3116 else
3117 return gid;
3120 #endif /* USE_UID16 */
3122 void syscall_init(void)
3124 IOCTLEntry *ie;
3125 const argtype *arg_type;
3126 int size;
3127 int i;
3129 #define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3130 #define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3131 #include "syscall_types.h"
3132 #undef STRUCT
3133 #undef STRUCT_SPECIAL
3135 /* we patch the ioctl size if necessary. We rely on the fact that
3136 no ioctl has all the bits at '1' in the size field */
3137 ie = ioctl_entries;
3138 while (ie->target_cmd != 0) {
3139 if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
3140 TARGET_IOC_SIZEMASK) {
3141 arg_type = ie->arg_type;
3142 if (arg_type[0] != TYPE_PTR) {
3143 fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
3144 ie->target_cmd);
3145 exit(1);
3147 arg_type++;
3148 size = thunk_type_size(arg_type, 0);
3149 ie->target_cmd = (ie->target_cmd &
3150 ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
3151 (size << TARGET_IOC_SIZESHIFT);
3154 /* Build target_to_host_errno_table[] table from
3155 * host_to_target_errno_table[]. */
3156 for (i=0; i < ERRNO_TABLE_SIZE; i++)
3157 target_to_host_errno_table[host_to_target_errno_table[i]] = i;
3159 /* automatic consistency check if same arch */
3160 #if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
3161 (defined(__x86_64__) && defined(TARGET_X86_64))
3162 if (unlikely(ie->target_cmd != ie->host_cmd)) {
3163 fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
3164 ie->name, ie->target_cmd, ie->host_cmd);
3166 #endif
3167 ie++;
3171 #if TARGET_ABI_BITS == 32
3172 static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
3174 #ifdef TARGET_WORDS_BIGENDIAN
3175 return ((uint64_t)word0 << 32) | word1;
3176 #else
3177 return ((uint64_t)word1 << 32) | word0;
3178 #endif
3180 #else /* TARGET_ABI_BITS == 32 */
3181 static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
3183 return word0;
3185 #endif /* TARGET_ABI_BITS != 32 */
3187 #ifdef TARGET_NR_truncate64
3188 static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
3189 abi_long arg2,
3190 abi_long arg3,
3191 abi_long arg4)
3193 #ifdef TARGET_ARM
3194 if (((CPUARMState *)cpu_env)->eabi)
3196 arg2 = arg3;
3197 arg3 = arg4;
3199 #endif
3200 return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
3202 #endif
3204 #ifdef TARGET_NR_ftruncate64
3205 static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
3206 abi_long arg2,
3207 abi_long arg3,
3208 abi_long arg4)
3210 #ifdef TARGET_ARM
3211 if (((CPUARMState *)cpu_env)->eabi)
3213 arg2 = arg3;
3214 arg3 = arg4;
3216 #endif
3217 return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
3219 #endif
3221 static inline abi_long target_to_host_timespec(struct timespec *host_ts,
3222 abi_ulong target_addr)
3224 struct target_timespec *target_ts;
3226 if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
3227 return -TARGET_EFAULT;
3228 host_ts->tv_sec = tswapl(target_ts->tv_sec);
3229 host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
3230 unlock_user_struct(target_ts, target_addr, 0);
3231 return 0;
3234 static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3235 struct timespec *host_ts)
3237 struct target_timespec *target_ts;
3239 if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
3240 return -TARGET_EFAULT;
3241 target_ts->tv_sec = tswapl(host_ts->tv_sec);
3242 target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
3243 unlock_user_struct(target_ts, target_addr, 1);
3244 return 0;
3247 #ifdef TARGET_NR_stat64
3248 static inline abi_long host_to_target_stat64(void *cpu_env,
3249 abi_ulong target_addr,
3250 struct stat *host_st)
3252 #ifdef TARGET_ARM
3253 if (((CPUARMState *)cpu_env)->eabi) {
3254 struct target_eabi_stat64 *target_st;
3256 if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3257 return -TARGET_EFAULT;
3258 memset(target_st, 0, sizeof(struct target_eabi_stat64));
3259 __put_user(host_st->st_dev, &target_st->st_dev);
3260 __put_user(host_st->st_ino, &target_st->st_ino);
3261 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3262 __put_user(host_st->st_ino, &target_st->__st_ino);
3263 #endif
3264 __put_user(host_st->st_mode, &target_st->st_mode);
3265 __put_user(host_st->st_nlink, &target_st->st_nlink);
3266 __put_user(host_st->st_uid, &target_st->st_uid);
3267 __put_user(host_st->st_gid, &target_st->st_gid);
3268 __put_user(host_st->st_rdev, &target_st->st_rdev);
3269 __put_user(host_st->st_size, &target_st->st_size);
3270 __put_user(host_st->st_blksize, &target_st->st_blksize);
3271 __put_user(host_st->st_blocks, &target_st->st_blocks);
3272 __put_user(host_st->st_atime, &target_st->target_st_atime);
3273 __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3274 __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3275 unlock_user_struct(target_st, target_addr, 1);
3276 } else
3277 #endif
3279 struct target_stat64 *target_st;
3281 if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3282 return -TARGET_EFAULT;
3283 memset(target_st, 0, sizeof(struct target_stat64));
3284 __put_user(host_st->st_dev, &target_st->st_dev);
3285 __put_user(host_st->st_ino, &target_st->st_ino);
3286 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3287 __put_user(host_st->st_ino, &target_st->__st_ino);
3288 #endif
3289 __put_user(host_st->st_mode, &target_st->st_mode);
3290 __put_user(host_st->st_nlink, &target_st->st_nlink);
3291 __put_user(host_st->st_uid, &target_st->st_uid);
3292 __put_user(host_st->st_gid, &target_st->st_gid);
3293 __put_user(host_st->st_rdev, &target_st->st_rdev);
3294 /* XXX: better use of kernel struct */
3295 __put_user(host_st->st_size, &target_st->st_size);
3296 __put_user(host_st->st_blksize, &target_st->st_blksize);
3297 __put_user(host_st->st_blocks, &target_st->st_blocks);
3298 __put_user(host_st->st_atime, &target_st->target_st_atime);
3299 __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3300 __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3301 unlock_user_struct(target_st, target_addr, 1);
3304 return 0;
3306 #endif
3308 #if defined(USE_NPTL)
3309 /* ??? Using host futex calls even when target atomic operations
3310 are not really atomic probably breaks things. However implementing
3311 futexes locally would make futexes shared between multiple processes
3312 tricky. However they're probably useless because guest atomic
3313 operations won't work either. */
3314 static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
3315 target_ulong uaddr2, int val3)
3317 struct timespec ts, *pts;
3319 /* ??? We assume FUTEX_* constants are the same on both host
3320 and target. */
3321 switch (op) {
3322 case FUTEX_WAIT:
3323 if (timeout) {
3324 pts = &ts;
3325 target_to_host_timespec(pts, timeout);
3326 } else {
3327 pts = NULL;
3329 return get_errno(sys_futex(g2h(uaddr), FUTEX_WAIT, tswap32(val),
3330 pts, NULL, 0));
3331 case FUTEX_WAKE:
3332 return get_errno(sys_futex(g2h(uaddr), FUTEX_WAKE, val, NULL, NULL, 0));
3333 case FUTEX_FD:
3334 return get_errno(sys_futex(g2h(uaddr), FUTEX_FD, val, NULL, NULL, 0));
3335 case FUTEX_REQUEUE:
3336 return get_errno(sys_futex(g2h(uaddr), FUTEX_REQUEUE, val,
3337 NULL, g2h(uaddr2), 0));
3338 case FUTEX_CMP_REQUEUE:
3339 return get_errno(sys_futex(g2h(uaddr), FUTEX_CMP_REQUEUE, val,
3340 NULL, g2h(uaddr2), tswap32(val3)));
3341 default:
3342 return -TARGET_ENOSYS;
3345 #endif
3347 int get_osversion(void)
3349 static int osversion;
3350 struct new_utsname buf;
3351 const char *s;
3352 int i, n, tmp;
3353 if (osversion)
3354 return osversion;
3355 if (qemu_uname_release && *qemu_uname_release) {
3356 s = qemu_uname_release;
3357 } else {
3358 if (sys_uname(&buf))
3359 return 0;
3360 s = buf.release;
3362 tmp = 0;
3363 for (i = 0; i < 3; i++) {
3364 n = 0;
3365 while (*s >= '0' && *s <= '9') {
3366 n *= 10;
3367 n += *s - '0';
3368 s++;
3370 tmp = (tmp << 8) + n;
3371 if (*s == '.')
3372 s++;
3374 osversion = tmp;
3375 return osversion;
3378 /* do_syscall() should always have a single exit point at the end so
3379 that actions, such as logging of syscall results, can be performed.
3380 All errnos that do_syscall() returns must be -TARGET_<errcode>. */
3381 abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3382 abi_long arg2, abi_long arg3, abi_long arg4,
3383 abi_long arg5, abi_long arg6)
3385 abi_long ret;
3386 struct stat st;
3387 struct statfs stfs;
3388 void *p;
3390 #ifdef DEBUG
3391 gemu_log("syscall %d", num);
3392 #endif
3393 if(do_strace)
3394 print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
3396 switch(num) {
3397 case TARGET_NR_exit:
3398 #ifdef HAVE_GPROF
3399 _mcleanup();
3400 #endif
3401 gdb_exit(cpu_env, arg1);
3402 /* XXX: should free thread stack and CPU env */
3403 sys_exit(arg1);
3404 ret = 0; /* avoid warning */
3405 break;
3406 case TARGET_NR_read:
3407 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
3408 goto efault;
3409 ret = get_errno(read(arg1, p, arg3));
3410 unlock_user(p, arg2, ret);
3411 break;
3412 case TARGET_NR_write:
3413 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
3414 goto efault;
3415 ret = get_errno(write(arg1, p, arg3));
3416 unlock_user(p, arg2, 0);
3417 break;
3418 case TARGET_NR_open:
3419 if (!(p = lock_user_string(arg1)))
3420 goto efault;
3421 ret = get_errno(open(path(p),
3422 target_to_host_bitmask(arg2, fcntl_flags_tbl),
3423 arg3));
3424 unlock_user(p, arg1, 0);
3425 break;
3426 #if defined(TARGET_NR_openat) && defined(__NR_openat)
3427 case TARGET_NR_openat:
3428 if (!(p = lock_user_string(arg2)))
3429 goto efault;
3430 ret = get_errno(sys_openat(arg1,
3431 path(p),
3432 target_to_host_bitmask(arg3, fcntl_flags_tbl),
3433 arg4));
3434 unlock_user(p, arg2, 0);
3435 break;
3436 #endif
3437 case TARGET_NR_close:
3438 ret = get_errno(close(arg1));
3439 break;
3440 case TARGET_NR_brk:
3441 ret = do_brk(arg1);
3442 break;
3443 case TARGET_NR_fork:
3444 ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
3445 break;
3446 #ifdef TARGET_NR_waitpid
3447 case TARGET_NR_waitpid:
3449 int status;
3450 ret = get_errno(waitpid(arg1, &status, arg3));
3451 if (!is_error(ret) && arg2
3452 && put_user_s32(status, arg2))
3453 goto efault;
3455 break;
3456 #endif
3457 #ifdef TARGET_NR_waitid
3458 case TARGET_NR_waitid:
3460 siginfo_t info;
3461 info.si_pid = 0;
3462 ret = get_errno(waitid(arg1, arg2, &info, arg4));
3463 if (!is_error(ret) && arg3 && info.si_pid != 0) {
3464 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
3465 goto efault;
3466 host_to_target_siginfo(p, &info);
3467 unlock_user(p, arg3, sizeof(target_siginfo_t));
3470 break;
3471 #endif
3472 #ifdef TARGET_NR_creat /* not on alpha */
3473 case TARGET_NR_creat:
3474 if (!(p = lock_user_string(arg1)))
3475 goto efault;
3476 ret = get_errno(creat(p, arg2));
3477 unlock_user(p, arg1, 0);
3478 break;
3479 #endif
3480 case TARGET_NR_link:
3482 void * p2;
3483 p = lock_user_string(arg1);
3484 p2 = lock_user_string(arg2);
3485 if (!p || !p2)
3486 ret = -TARGET_EFAULT;
3487 else
3488 ret = get_errno(link(p, p2));
3489 unlock_user(p2, arg2, 0);
3490 unlock_user(p, arg1, 0);
3492 break;
3493 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
3494 case TARGET_NR_linkat:
3496 void * p2 = NULL;
3497 if (!arg2 || !arg4)
3498 goto efault;
3499 p = lock_user_string(arg2);
3500 p2 = lock_user_string(arg4);
3501 if (!p || !p2)
3502 ret = -TARGET_EFAULT;
3503 else
3504 ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
3505 unlock_user(p, arg2, 0);
3506 unlock_user(p2, arg4, 0);
3508 break;
3509 #endif
3510 case TARGET_NR_unlink:
3511 if (!(p = lock_user_string(arg1)))
3512 goto efault;
3513 ret = get_errno(unlink(p));
3514 unlock_user(p, arg1, 0);
3515 break;
3516 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
3517 case TARGET_NR_unlinkat:
3518 if (!(p = lock_user_string(arg2)))
3519 goto efault;
3520 ret = get_errno(sys_unlinkat(arg1, p, arg3));
3521 unlock_user(p, arg2, 0);
3522 break;
3523 #endif
3524 case TARGET_NR_execve:
3526 char **argp, **envp;
3527 int argc, envc;
3528 abi_ulong gp;
3529 abi_ulong guest_argp;
3530 abi_ulong guest_envp;
3531 abi_ulong addr;
3532 char **q;
3534 argc = 0;
3535 guest_argp = arg2;
3536 for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
3537 if (get_user_ual(addr, gp))
3538 goto efault;
3539 if (!addr)
3540 break;
3541 argc++;
3543 envc = 0;
3544 guest_envp = arg3;
3545 for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
3546 if (get_user_ual(addr, gp))
3547 goto efault;
3548 if (!addr)
3549 break;
3550 envc++;
3553 argp = alloca((argc + 1) * sizeof(void *));
3554 envp = alloca((envc + 1) * sizeof(void *));
3556 for (gp = guest_argp, q = argp; gp;
3557 gp += sizeof(abi_ulong), q++) {
3558 if (get_user_ual(addr, gp))
3559 goto execve_efault;
3560 if (!addr)
3561 break;
3562 if (!(*q = lock_user_string(addr)))
3563 goto execve_efault;
3565 *q = NULL;
3567 for (gp = guest_envp, q = envp; gp;
3568 gp += sizeof(abi_ulong), q++) {
3569 if (get_user_ual(addr, gp))
3570 goto execve_efault;
3571 if (!addr)
3572 break;
3573 if (!(*q = lock_user_string(addr)))
3574 goto execve_efault;
3576 *q = NULL;
3578 if (!(p = lock_user_string(arg1)))
3579 goto execve_efault;
3580 ret = get_errno(execve(p, argp, envp));
3581 unlock_user(p, arg1, 0);
3583 goto execve_end;
3585 execve_efault:
3586 ret = -TARGET_EFAULT;
3588 execve_end:
3589 for (gp = guest_argp, q = argp; *q;
3590 gp += sizeof(abi_ulong), q++) {
3591 if (get_user_ual(addr, gp)
3592 || !addr)
3593 break;
3594 unlock_user(*q, addr, 0);
3596 for (gp = guest_envp, q = envp; *q;
3597 gp += sizeof(abi_ulong), q++) {
3598 if (get_user_ual(addr, gp)
3599 || !addr)
3600 break;
3601 unlock_user(*q, addr, 0);
3604 break;
3605 case TARGET_NR_chdir:
3606 if (!(p = lock_user_string(arg1)))
3607 goto efault;
3608 ret = get_errno(chdir(p));
3609 unlock_user(p, arg1, 0);
3610 break;
3611 #ifdef TARGET_NR_time
3612 case TARGET_NR_time:
3614 time_t host_time;
3615 ret = get_errno(time(&host_time));
3616 if (!is_error(ret)
3617 && arg1
3618 && put_user_sal(host_time, arg1))
3619 goto efault;
3621 break;
3622 #endif
3623 case TARGET_NR_mknod:
3624 if (!(p = lock_user_string(arg1)))
3625 goto efault;
3626 ret = get_errno(mknod(p, arg2, arg3));
3627 unlock_user(p, arg1, 0);
3628 break;
3629 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
3630 case TARGET_NR_mknodat:
3631 if (!(p = lock_user_string(arg2)))
3632 goto efault;
3633 ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
3634 unlock_user(p, arg2, 0);
3635 break;
3636 #endif
3637 case TARGET_NR_chmod:
3638 if (!(p = lock_user_string(arg1)))
3639 goto efault;
3640 ret = get_errno(chmod(p, arg2));
3641 unlock_user(p, arg1, 0);
3642 break;
3643 #ifdef TARGET_NR_break
3644 case TARGET_NR_break:
3645 goto unimplemented;
3646 #endif
3647 #ifdef TARGET_NR_oldstat
3648 case TARGET_NR_oldstat:
3649 goto unimplemented;
3650 #endif
3651 case TARGET_NR_lseek:
3652 ret = get_errno(lseek(arg1, arg2, arg3));
3653 break;
3654 #ifdef TARGET_NR_getxpid
3655 case TARGET_NR_getxpid:
3656 #else
3657 case TARGET_NR_getpid:
3658 #endif
3659 ret = get_errno(getpid());
3660 break;
3661 case TARGET_NR_mount:
3663 /* need to look at the data field */
3664 void *p2, *p3;
3665 p = lock_user_string(arg1);
3666 p2 = lock_user_string(arg2);
3667 p3 = lock_user_string(arg3);
3668 if (!p || !p2 || !p3)
3669 ret = -TARGET_EFAULT;
3670 else
3671 /* FIXME - arg5 should be locked, but it isn't clear how to
3672 * do that since it's not guaranteed to be a NULL-terminated
3673 * string.
3675 ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
3676 unlock_user(p, arg1, 0);
3677 unlock_user(p2, arg2, 0);
3678 unlock_user(p3, arg3, 0);
3679 break;
3681 #ifdef TARGET_NR_umount
3682 case TARGET_NR_umount:
3683 if (!(p = lock_user_string(arg1)))
3684 goto efault;
3685 ret = get_errno(umount(p));
3686 unlock_user(p, arg1, 0);
3687 break;
3688 #endif
3689 #ifdef TARGET_NR_stime /* not on alpha */
3690 case TARGET_NR_stime:
3692 time_t host_time;
3693 if (get_user_sal(host_time, arg1))
3694 goto efault;
3695 ret = get_errno(stime(&host_time));
3697 break;
3698 #endif
3699 case TARGET_NR_ptrace:
3700 goto unimplemented;
3701 #ifdef TARGET_NR_alarm /* not on alpha */
3702 case TARGET_NR_alarm:
3703 ret = alarm(arg1);
3704 break;
3705 #endif
3706 #ifdef TARGET_NR_oldfstat
3707 case TARGET_NR_oldfstat:
3708 goto unimplemented;
3709 #endif
3710 #ifdef TARGET_NR_pause /* not on alpha */
3711 case TARGET_NR_pause:
3712 ret = get_errno(pause());
3713 break;
3714 #endif
3715 #ifdef TARGET_NR_utime
3716 case TARGET_NR_utime:
3718 struct utimbuf tbuf, *host_tbuf;
3719 struct target_utimbuf *target_tbuf;
3720 if (arg2) {
3721 if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
3722 goto efault;
3723 tbuf.actime = tswapl(target_tbuf->actime);
3724 tbuf.modtime = tswapl(target_tbuf->modtime);
3725 unlock_user_struct(target_tbuf, arg2, 0);
3726 host_tbuf = &tbuf;
3727 } else {
3728 host_tbuf = NULL;
3730 if (!(p = lock_user_string(arg1)))
3731 goto efault;
3732 ret = get_errno(utime(p, host_tbuf));
3733 unlock_user(p, arg1, 0);
3735 break;
3736 #endif
3737 case TARGET_NR_utimes:
3739 struct timeval *tvp, tv[2];
3740 if (arg2) {
3741 if (copy_from_user_timeval(&tv[0], arg2)
3742 || copy_from_user_timeval(&tv[1],
3743 arg2 + sizeof(struct target_timeval)))
3744 goto efault;
3745 tvp = tv;
3746 } else {
3747 tvp = NULL;
3749 if (!(p = lock_user_string(arg1)))
3750 goto efault;
3751 ret = get_errno(utimes(p, tvp));
3752 unlock_user(p, arg1, 0);
3754 break;
3755 #if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
3756 case TARGET_NR_futimesat:
3758 struct timeval *tvp, tv[2];
3759 if (arg3) {
3760 if (copy_from_user_timeval(&tv[0], arg3)
3761 || copy_from_user_timeval(&tv[1],
3762 arg3 + sizeof(struct target_timeval)))
3763 goto efault;
3764 tvp = tv;
3765 } else {
3766 tvp = NULL;
3768 if (!(p = lock_user_string(arg2)))
3769 goto efault;
3770 ret = get_errno(sys_futimesat(arg1, path(p), tvp));
3771 unlock_user(p, arg2, 0);
3773 break;
3774 #endif
3775 #ifdef TARGET_NR_stty
3776 case TARGET_NR_stty:
3777 goto unimplemented;
3778 #endif
3779 #ifdef TARGET_NR_gtty
3780 case TARGET_NR_gtty:
3781 goto unimplemented;
3782 #endif
3783 case TARGET_NR_access:
3784 if (!(p = lock_user_string(arg1)))
3785 goto efault;
3786 ret = get_errno(access(p, arg2));
3787 unlock_user(p, arg1, 0);
3788 break;
3789 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
3790 case TARGET_NR_faccessat:
3791 if (!(p = lock_user_string(arg2)))
3792 goto efault;
3793 ret = get_errno(sys_faccessat(arg1, p, arg3, arg4));
3794 unlock_user(p, arg2, 0);
3795 break;
3796 #endif
3797 #ifdef TARGET_NR_nice /* not on alpha */
3798 case TARGET_NR_nice:
3799 ret = get_errno(nice(arg1));
3800 break;
3801 #endif
3802 #ifdef TARGET_NR_ftime
3803 case TARGET_NR_ftime:
3804 goto unimplemented;
3805 #endif
3806 case TARGET_NR_sync:
3807 sync();
3808 ret = 0;
3809 break;
3810 case TARGET_NR_kill:
3811 ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
3812 break;
3813 case TARGET_NR_rename:
3815 void *p2;
3816 p = lock_user_string(arg1);
3817 p2 = lock_user_string(arg2);
3818 if (!p || !p2)
3819 ret = -TARGET_EFAULT;
3820 else
3821 ret = get_errno(rename(p, p2));
3822 unlock_user(p2, arg2, 0);
3823 unlock_user(p, arg1, 0);
3825 break;
3826 #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
3827 case TARGET_NR_renameat:
3829 void *p2;
3830 p = lock_user_string(arg2);
3831 p2 = lock_user_string(arg4);
3832 if (!p || !p2)
3833 ret = -TARGET_EFAULT;
3834 else
3835 ret = get_errno(sys_renameat(arg1, p, arg3, p2));
3836 unlock_user(p2, arg4, 0);
3837 unlock_user(p, arg2, 0);
3839 break;
3840 #endif
3841 case TARGET_NR_mkdir:
3842 if (!(p = lock_user_string(arg1)))
3843 goto efault;
3844 ret = get_errno(mkdir(p, arg2));
3845 unlock_user(p, arg1, 0);
3846 break;
3847 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
3848 case TARGET_NR_mkdirat:
3849 if (!(p = lock_user_string(arg2)))
3850 goto efault;
3851 ret = get_errno(sys_mkdirat(arg1, p, arg3));
3852 unlock_user(p, arg2, 0);
3853 break;
3854 #endif
3855 case TARGET_NR_rmdir:
3856 if (!(p = lock_user_string(arg1)))
3857 goto efault;
3858 ret = get_errno(rmdir(p));
3859 unlock_user(p, arg1, 0);
3860 break;
3861 case TARGET_NR_dup:
3862 ret = get_errno(dup(arg1));
3863 break;
3864 case TARGET_NR_pipe:
3866 int host_pipe[2];
3867 ret = get_errno(pipe(host_pipe));
3868 if (!is_error(ret)) {
3869 #if defined(TARGET_MIPS)
3870 CPUMIPSState *env = (CPUMIPSState*)cpu_env;
3871 env->active_tc.gpr[3] = host_pipe[1];
3872 ret = host_pipe[0];
3873 #elif defined(TARGET_SH4)
3874 ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
3875 ret = host_pipe[0];
3876 #else
3877 if (put_user_s32(host_pipe[0], arg1)
3878 || put_user_s32(host_pipe[1], arg1 + sizeof(host_pipe[0])))
3879 goto efault;
3880 #endif
3883 break;
3884 case TARGET_NR_times:
3886 struct target_tms *tmsp;
3887 struct tms tms;
3888 ret = get_errno(times(&tms));
3889 if (arg1) {
3890 tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
3891 if (!tmsp)
3892 goto efault;
3893 tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
3894 tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
3895 tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
3896 tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime));
3898 if (!is_error(ret))
3899 ret = host_to_target_clock_t(ret);
3901 break;
3902 #ifdef TARGET_NR_prof
3903 case TARGET_NR_prof:
3904 goto unimplemented;
3905 #endif
3906 #ifdef TARGET_NR_signal
3907 case TARGET_NR_signal:
3908 goto unimplemented;
3909 #endif
3910 case TARGET_NR_acct:
3911 if (!(p = lock_user_string(arg1)))
3912 goto efault;
3913 ret = get_errno(acct(path(p)));
3914 unlock_user(p, arg1, 0);
3915 break;
3916 #ifdef TARGET_NR_umount2 /* not on alpha */
3917 case TARGET_NR_umount2:
3918 if (!(p = lock_user_string(arg1)))
3919 goto efault;
3920 ret = get_errno(umount2(p, arg2));
3921 unlock_user(p, arg1, 0);
3922 break;
3923 #endif
3924 #ifdef TARGET_NR_lock
3925 case TARGET_NR_lock:
3926 goto unimplemented;
3927 #endif
3928 case TARGET_NR_ioctl:
3929 ret = do_ioctl(arg1, arg2, arg3);
3930 break;
3931 case TARGET_NR_fcntl:
3932 ret = do_fcntl(arg1, arg2, arg3);
3933 break;
3934 #ifdef TARGET_NR_mpx
3935 case TARGET_NR_mpx:
3936 goto unimplemented;
3937 #endif
3938 case TARGET_NR_setpgid:
3939 ret = get_errno(setpgid(arg1, arg2));
3940 break;
3941 #ifdef TARGET_NR_ulimit
3942 case TARGET_NR_ulimit:
3943 goto unimplemented;
3944 #endif
3945 #ifdef TARGET_NR_oldolduname
3946 case TARGET_NR_oldolduname:
3947 goto unimplemented;
3948 #endif
3949 case TARGET_NR_umask:
3950 ret = get_errno(umask(arg1));
3951 break;
3952 case TARGET_NR_chroot:
3953 if (!(p = lock_user_string(arg1)))
3954 goto efault;
3955 ret = get_errno(chroot(p));
3956 unlock_user(p, arg1, 0);
3957 break;
3958 case TARGET_NR_ustat:
3959 goto unimplemented;
3960 case TARGET_NR_dup2:
3961 ret = get_errno(dup2(arg1, arg2));
3962 break;
3963 #ifdef TARGET_NR_getppid /* not on alpha */
3964 case TARGET_NR_getppid:
3965 ret = get_errno(getppid());
3966 break;
3967 #endif
3968 case TARGET_NR_getpgrp:
3969 ret = get_errno(getpgrp());
3970 break;
3971 case TARGET_NR_setsid:
3972 ret = get_errno(setsid());
3973 break;
3974 #ifdef TARGET_NR_sigaction
3975 case TARGET_NR_sigaction:
3977 #if !defined(TARGET_MIPS)
3978 struct target_old_sigaction *old_act;
3979 struct target_sigaction act, oact, *pact;
3980 if (arg2) {
3981 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
3982 goto efault;
3983 act._sa_handler = old_act->_sa_handler;
3984 target_siginitset(&act.sa_mask, old_act->sa_mask);
3985 act.sa_flags = old_act->sa_flags;
3986 act.sa_restorer = old_act->sa_restorer;
3987 unlock_user_struct(old_act, arg2, 0);
3988 pact = &act;
3989 } else {
3990 pact = NULL;
3992 ret = get_errno(do_sigaction(arg1, pact, &oact));
3993 if (!is_error(ret) && arg3) {
3994 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
3995 goto efault;
3996 old_act->_sa_handler = oact._sa_handler;
3997 old_act->sa_mask = oact.sa_mask.sig[0];
3998 old_act->sa_flags = oact.sa_flags;
3999 old_act->sa_restorer = oact.sa_restorer;
4000 unlock_user_struct(old_act, arg3, 1);
4002 #else
4003 struct target_sigaction act, oact, *pact, *old_act;
4005 if (arg2) {
4006 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4007 goto efault;
4008 act._sa_handler = old_act->_sa_handler;
4009 target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
4010 act.sa_flags = old_act->sa_flags;
4011 unlock_user_struct(old_act, arg2, 0);
4012 pact = &act;
4013 } else {
4014 pact = NULL;
4017 ret = get_errno(do_sigaction(arg1, pact, &oact));
4019 if (!is_error(ret) && arg3) {
4020 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4021 goto efault;
4022 old_act->_sa_handler = oact._sa_handler;
4023 old_act->sa_flags = oact.sa_flags;
4024 old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
4025 old_act->sa_mask.sig[1] = 0;
4026 old_act->sa_mask.sig[2] = 0;
4027 old_act->sa_mask.sig[3] = 0;
4028 unlock_user_struct(old_act, arg3, 1);
4030 #endif
4032 break;
4033 #endif
4034 case TARGET_NR_rt_sigaction:
4036 struct target_sigaction *act;
4037 struct target_sigaction *oact;
4039 if (arg2) {
4040 if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
4041 goto efault;
4042 } else
4043 act = NULL;
4044 if (arg3) {
4045 if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
4046 ret = -TARGET_EFAULT;
4047 goto rt_sigaction_fail;
4049 } else
4050 oact = NULL;
4051 ret = get_errno(do_sigaction(arg1, act, oact));
4052 rt_sigaction_fail:
4053 if (act)
4054 unlock_user_struct(act, arg2, 0);
4055 if (oact)
4056 unlock_user_struct(oact, arg3, 1);
4058 break;
4059 #ifdef TARGET_NR_sgetmask /* not on alpha */
4060 case TARGET_NR_sgetmask:
4062 sigset_t cur_set;
4063 abi_ulong target_set;
4064 sigprocmask(0, NULL, &cur_set);
4065 host_to_target_old_sigset(&target_set, &cur_set);
4066 ret = target_set;
4068 break;
4069 #endif
4070 #ifdef TARGET_NR_ssetmask /* not on alpha */
4071 case TARGET_NR_ssetmask:
4073 sigset_t set, oset, cur_set;
4074 abi_ulong target_set = arg1;
4075 sigprocmask(0, NULL, &cur_set);
4076 target_to_host_old_sigset(&set, &target_set);
4077 sigorset(&set, &set, &cur_set);
4078 sigprocmask(SIG_SETMASK, &set, &oset);
4079 host_to_target_old_sigset(&target_set, &oset);
4080 ret = target_set;
4082 break;
4083 #endif
4084 #ifdef TARGET_NR_sigprocmask
4085 case TARGET_NR_sigprocmask:
4087 int how = arg1;
4088 sigset_t set, oldset, *set_ptr;
4090 if (arg2) {
4091 switch(how) {
4092 case TARGET_SIG_BLOCK:
4093 how = SIG_BLOCK;
4094 break;
4095 case TARGET_SIG_UNBLOCK:
4096 how = SIG_UNBLOCK;
4097 break;
4098 case TARGET_SIG_SETMASK:
4099 how = SIG_SETMASK;
4100 break;
4101 default:
4102 ret = -TARGET_EINVAL;
4103 goto fail;
4105 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4106 goto efault;
4107 target_to_host_old_sigset(&set, p);
4108 unlock_user(p, arg2, 0);
4109 set_ptr = &set;
4110 } else {
4111 how = 0;
4112 set_ptr = NULL;
4114 ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
4115 if (!is_error(ret) && arg3) {
4116 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4117 goto efault;
4118 host_to_target_old_sigset(p, &oldset);
4119 unlock_user(p, arg3, sizeof(target_sigset_t));
4122 break;
4123 #endif
4124 case TARGET_NR_rt_sigprocmask:
4126 int how = arg1;
4127 sigset_t set, oldset, *set_ptr;
4129 if (arg2) {
4130 switch(how) {
4131 case TARGET_SIG_BLOCK:
4132 how = SIG_BLOCK;
4133 break;
4134 case TARGET_SIG_UNBLOCK:
4135 how = SIG_UNBLOCK;
4136 break;
4137 case TARGET_SIG_SETMASK:
4138 how = SIG_SETMASK;
4139 break;
4140 default:
4141 ret = -TARGET_EINVAL;
4142 goto fail;
4144 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4145 goto efault;
4146 target_to_host_sigset(&set, p);
4147 unlock_user(p, arg2, 0);
4148 set_ptr = &set;
4149 } else {
4150 how = 0;
4151 set_ptr = NULL;
4153 ret = get_errno(sigprocmask(how, set_ptr, &oldset));
4154 if (!is_error(ret) && arg3) {
4155 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4156 goto efault;
4157 host_to_target_sigset(p, &oldset);
4158 unlock_user(p, arg3, sizeof(target_sigset_t));
4161 break;
4162 #ifdef TARGET_NR_sigpending
4163 case TARGET_NR_sigpending:
4165 sigset_t set;
4166 ret = get_errno(sigpending(&set));
4167 if (!is_error(ret)) {
4168 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4169 goto efault;
4170 host_to_target_old_sigset(p, &set);
4171 unlock_user(p, arg1, sizeof(target_sigset_t));
4174 break;
4175 #endif
4176 case TARGET_NR_rt_sigpending:
4178 sigset_t set;
4179 ret = get_errno(sigpending(&set));
4180 if (!is_error(ret)) {
4181 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4182 goto efault;
4183 host_to_target_sigset(p, &set);
4184 unlock_user(p, arg1, sizeof(target_sigset_t));
4187 break;
4188 #ifdef TARGET_NR_sigsuspend
4189 case TARGET_NR_sigsuspend:
4191 sigset_t set;
4192 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4193 goto efault;
4194 target_to_host_old_sigset(&set, p);
4195 unlock_user(p, arg1, 0);
4196 ret = get_errno(sigsuspend(&set));
4198 break;
4199 #endif
4200 case TARGET_NR_rt_sigsuspend:
4202 sigset_t set;
4203 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4204 goto efault;
4205 target_to_host_sigset(&set, p);
4206 unlock_user(p, arg1, 0);
4207 ret = get_errno(sigsuspend(&set));
4209 break;
4210 case TARGET_NR_rt_sigtimedwait:
4212 sigset_t set;
4213 struct timespec uts, *puts;
4214 siginfo_t uinfo;
4216 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4217 goto efault;
4218 target_to_host_sigset(&set, p);
4219 unlock_user(p, arg1, 0);
4220 if (arg3) {
4221 puts = &uts;
4222 target_to_host_timespec(puts, arg3);
4223 } else {
4224 puts = NULL;
4226 ret = get_errno(sigtimedwait(&set, &uinfo, puts));
4227 if (!is_error(ret) && arg2) {
4228 if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
4229 goto efault;
4230 host_to_target_siginfo(p, &uinfo);
4231 unlock_user(p, arg2, sizeof(target_siginfo_t));
4234 break;
4235 case TARGET_NR_rt_sigqueueinfo:
4237 siginfo_t uinfo;
4238 if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
4239 goto efault;
4240 target_to_host_siginfo(&uinfo, p);
4241 unlock_user(p, arg1, 0);
4242 ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
4244 break;
4245 #ifdef TARGET_NR_sigreturn
4246 case TARGET_NR_sigreturn:
4247 /* NOTE: ret is eax, so not transcoding must be done */
4248 ret = do_sigreturn(cpu_env);
4249 break;
4250 #endif
4251 case TARGET_NR_rt_sigreturn:
4252 /* NOTE: ret is eax, so not transcoding must be done */
4253 ret = do_rt_sigreturn(cpu_env);
4254 break;
4255 case TARGET_NR_sethostname:
4256 if (!(p = lock_user_string(arg1)))
4257 goto efault;
4258 ret = get_errno(sethostname(p, arg2));
4259 unlock_user(p, arg1, 0);
4260 break;
4261 case TARGET_NR_setrlimit:
4263 /* XXX: convert resource ? */
4264 int resource = arg1;
4265 struct target_rlimit *target_rlim;
4266 struct rlimit rlim;
4267 if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
4268 goto efault;
4269 rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4270 rlim.rlim_max = tswapl(target_rlim->rlim_max);
4271 unlock_user_struct(target_rlim, arg2, 0);
4272 ret = get_errno(setrlimit(resource, &rlim));
4274 break;
4275 case TARGET_NR_getrlimit:
4277 /* XXX: convert resource ? */
4278 int resource = arg1;
4279 struct target_rlimit *target_rlim;
4280 struct rlimit rlim;
4282 ret = get_errno(getrlimit(resource, &rlim));
4283 if (!is_error(ret)) {
4284 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
4285 goto efault;
4286 rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4287 rlim.rlim_max = tswapl(target_rlim->rlim_max);
4288 unlock_user_struct(target_rlim, arg2, 1);
4291 break;
4292 case TARGET_NR_getrusage:
4294 struct rusage rusage;
4295 ret = get_errno(getrusage(arg1, &rusage));
4296 if (!is_error(ret)) {
4297 host_to_target_rusage(arg2, &rusage);
4300 break;
4301 case TARGET_NR_gettimeofday:
4303 struct timeval tv;
4304 ret = get_errno(gettimeofday(&tv, NULL));
4305 if (!is_error(ret)) {
4306 if (copy_to_user_timeval(arg1, &tv))
4307 goto efault;
4310 break;
4311 case TARGET_NR_settimeofday:
4313 struct timeval tv;
4314 if (copy_from_user_timeval(&tv, arg1))
4315 goto efault;
4316 ret = get_errno(settimeofday(&tv, NULL));
4318 break;
4319 #ifdef TARGET_NR_select
4320 case TARGET_NR_select:
4322 struct target_sel_arg_struct *sel;
4323 abi_ulong inp, outp, exp, tvp;
4324 long nsel;
4326 if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
4327 goto efault;
4328 nsel = tswapl(sel->n);
4329 inp = tswapl(sel->inp);
4330 outp = tswapl(sel->outp);
4331 exp = tswapl(sel->exp);
4332 tvp = tswapl(sel->tvp);
4333 unlock_user_struct(sel, arg1, 0);
4334 ret = do_select(nsel, inp, outp, exp, tvp);
4336 break;
4337 #endif
4338 case TARGET_NR_symlink:
4340 void *p2;
4341 p = lock_user_string(arg1);
4342 p2 = lock_user_string(arg2);
4343 if (!p || !p2)
4344 ret = -TARGET_EFAULT;
4345 else
4346 ret = get_errno(symlink(p, p2));
4347 unlock_user(p2, arg2, 0);
4348 unlock_user(p, arg1, 0);
4350 break;
4351 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
4352 case TARGET_NR_symlinkat:
4354 void *p2;
4355 p = lock_user_string(arg1);
4356 p2 = lock_user_string(arg3);
4357 if (!p || !p2)
4358 ret = -TARGET_EFAULT;
4359 else
4360 ret = get_errno(sys_symlinkat(p, arg2, p2));
4361 unlock_user(p2, arg3, 0);
4362 unlock_user(p, arg1, 0);
4364 break;
4365 #endif
4366 #ifdef TARGET_NR_oldlstat
4367 case TARGET_NR_oldlstat:
4368 goto unimplemented;
4369 #endif
4370 case TARGET_NR_readlink:
4372 void *p2;
4373 p = lock_user_string(arg1);
4374 p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
4375 if (!p || !p2)
4376 ret = -TARGET_EFAULT;
4377 else
4378 ret = get_errno(readlink(path(p), p2, arg3));
4379 unlock_user(p2, arg2, ret);
4380 unlock_user(p, arg1, 0);
4382 break;
4383 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
4384 case TARGET_NR_readlinkat:
4386 void *p2;
4387 p = lock_user_string(arg2);
4388 p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
4389 if (!p || !p2)
4390 ret = -TARGET_EFAULT;
4391 else
4392 ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
4393 unlock_user(p2, arg3, ret);
4394 unlock_user(p, arg2, 0);
4396 break;
4397 #endif
4398 #ifdef TARGET_NR_uselib
4399 case TARGET_NR_uselib:
4400 goto unimplemented;
4401 #endif
4402 #ifdef TARGET_NR_swapon
4403 case TARGET_NR_swapon:
4404 if (!(p = lock_user_string(arg1)))
4405 goto efault;
4406 ret = get_errno(swapon(p, arg2));
4407 unlock_user(p, arg1, 0);
4408 break;
4409 #endif
4410 case TARGET_NR_reboot:
4411 goto unimplemented;
4412 #ifdef TARGET_NR_readdir
4413 case TARGET_NR_readdir:
4414 goto unimplemented;
4415 #endif
4416 #ifdef TARGET_NR_mmap
4417 case TARGET_NR_mmap:
4418 #if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS)
4420 abi_ulong *v;
4421 abi_ulong v1, v2, v3, v4, v5, v6;
4422 if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
4423 goto efault;
4424 v1 = tswapl(v[0]);
4425 v2 = tswapl(v[1]);
4426 v3 = tswapl(v[2]);
4427 v4 = tswapl(v[3]);
4428 v5 = tswapl(v[4]);
4429 v6 = tswapl(v[5]);
4430 unlock_user(v, arg1, 0);
4431 ret = get_errno(target_mmap(v1, v2, v3,
4432 target_to_host_bitmask(v4, mmap_flags_tbl),
4433 v5, v6));
4435 #else
4436 ret = get_errno(target_mmap(arg1, arg2, arg3,
4437 target_to_host_bitmask(arg4, mmap_flags_tbl),
4438 arg5,
4439 arg6));
4440 #endif
4441 break;
4442 #endif
4443 #ifdef TARGET_NR_mmap2
4444 case TARGET_NR_mmap2:
4445 #ifndef MMAP_SHIFT
4446 #define MMAP_SHIFT 12
4447 #endif
4448 ret = get_errno(target_mmap(arg1, arg2, arg3,
4449 target_to_host_bitmask(arg4, mmap_flags_tbl),
4450 arg5,
4451 arg6 << MMAP_SHIFT));
4452 break;
4453 #endif
4454 case TARGET_NR_munmap:
4455 ret = get_errno(target_munmap(arg1, arg2));
4456 break;
4457 case TARGET_NR_mprotect:
4458 ret = get_errno(target_mprotect(arg1, arg2, arg3));
4459 break;
4460 #ifdef TARGET_NR_mremap
4461 case TARGET_NR_mremap:
4462 ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
4463 break;
4464 #endif
4465 /* ??? msync/mlock/munlock are broken for softmmu. */
4466 #ifdef TARGET_NR_msync
4467 case TARGET_NR_msync:
4468 ret = get_errno(msync(g2h(arg1), arg2, arg3));
4469 break;
4470 #endif
4471 #ifdef TARGET_NR_mlock
4472 case TARGET_NR_mlock:
4473 ret = get_errno(mlock(g2h(arg1), arg2));
4474 break;
4475 #endif
4476 #ifdef TARGET_NR_munlock
4477 case TARGET_NR_munlock:
4478 ret = get_errno(munlock(g2h(arg1), arg2));
4479 break;
4480 #endif
4481 #ifdef TARGET_NR_mlockall
4482 case TARGET_NR_mlockall:
4483 ret = get_errno(mlockall(arg1));
4484 break;
4485 #endif
4486 #ifdef TARGET_NR_munlockall
4487 case TARGET_NR_munlockall:
4488 ret = get_errno(munlockall());
4489 break;
4490 #endif
4491 case TARGET_NR_truncate:
4492 if (!(p = lock_user_string(arg1)))
4493 goto efault;
4494 ret = get_errno(truncate(p, arg2));
4495 unlock_user(p, arg1, 0);
4496 break;
4497 case TARGET_NR_ftruncate:
4498 ret = get_errno(ftruncate(arg1, arg2));
4499 break;
4500 case TARGET_NR_fchmod:
4501 ret = get_errno(fchmod(arg1, arg2));
4502 break;
4503 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
4504 case TARGET_NR_fchmodat:
4505 if (!(p = lock_user_string(arg2)))
4506 goto efault;
4507 ret = get_errno(sys_fchmodat(arg1, p, arg3, arg4));
4508 unlock_user(p, arg2, 0);
4509 break;
4510 #endif
4511 case TARGET_NR_getpriority:
4512 /* libc does special remapping of the return value of
4513 * sys_getpriority() so it's just easiest to call
4514 * sys_getpriority() directly rather than through libc. */
4515 ret = sys_getpriority(arg1, arg2);
4516 break;
4517 case TARGET_NR_setpriority:
4518 ret = get_errno(setpriority(arg1, arg2, arg3));
4519 break;
4520 #ifdef TARGET_NR_profil
4521 case TARGET_NR_profil:
4522 goto unimplemented;
4523 #endif
4524 case TARGET_NR_statfs:
4525 if (!(p = lock_user_string(arg1)))
4526 goto efault;
4527 ret = get_errno(statfs(path(p), &stfs));
4528 unlock_user(p, arg1, 0);
4529 convert_statfs:
4530 if (!is_error(ret)) {
4531 struct target_statfs *target_stfs;
4533 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
4534 goto efault;
4535 __put_user(stfs.f_type, &target_stfs->f_type);
4536 __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4537 __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4538 __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4539 __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4540 __put_user(stfs.f_files, &target_stfs->f_files);
4541 __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4542 __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4543 __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4544 __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4545 unlock_user_struct(target_stfs, arg2, 1);
4547 break;
4548 case TARGET_NR_fstatfs:
4549 ret = get_errno(fstatfs(arg1, &stfs));
4550 goto convert_statfs;
4551 #ifdef TARGET_NR_statfs64
4552 case TARGET_NR_statfs64:
4553 if (!(p = lock_user_string(arg1)))
4554 goto efault;
4555 ret = get_errno(statfs(path(p), &stfs));
4556 unlock_user(p, arg1, 0);
4557 convert_statfs64:
4558 if (!is_error(ret)) {
4559 struct target_statfs64 *target_stfs;
4561 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
4562 goto efault;
4563 __put_user(stfs.f_type, &target_stfs->f_type);
4564 __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4565 __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4566 __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4567 __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4568 __put_user(stfs.f_files, &target_stfs->f_files);
4569 __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4570 __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4571 __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4572 __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4573 unlock_user_struct(target_stfs, arg3, 1);
4575 break;
4576 case TARGET_NR_fstatfs64:
4577 ret = get_errno(fstatfs(arg1, &stfs));
4578 goto convert_statfs64;
4579 #endif
4580 #ifdef TARGET_NR_ioperm
4581 case TARGET_NR_ioperm:
4582 goto unimplemented;
4583 #endif
4584 #ifdef TARGET_NR_socketcall
4585 case TARGET_NR_socketcall:
4586 ret = do_socketcall(arg1, arg2);
4587 break;
4588 #endif
4589 #ifdef TARGET_NR_accept
4590 case TARGET_NR_accept:
4591 ret = do_accept(arg1, arg2, arg3);
4592 break;
4593 #endif
4594 #ifdef TARGET_NR_bind
4595 case TARGET_NR_bind:
4596 ret = do_bind(arg1, arg2, arg3);
4597 break;
4598 #endif
4599 #ifdef TARGET_NR_connect
4600 case TARGET_NR_connect:
4601 ret = do_connect(arg1, arg2, arg3);
4602 break;
4603 #endif
4604 #ifdef TARGET_NR_getpeername
4605 case TARGET_NR_getpeername:
4606 ret = do_getpeername(arg1, arg2, arg3);
4607 break;
4608 #endif
4609 #ifdef TARGET_NR_getsockname
4610 case TARGET_NR_getsockname:
4611 ret = do_getsockname(arg1, arg2, arg3);
4612 break;
4613 #endif
4614 #ifdef TARGET_NR_getsockopt
4615 case TARGET_NR_getsockopt:
4616 ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
4617 break;
4618 #endif
4619 #ifdef TARGET_NR_listen
4620 case TARGET_NR_listen:
4621 ret = get_errno(listen(arg1, arg2));
4622 break;
4623 #endif
4624 #ifdef TARGET_NR_recv
4625 case TARGET_NR_recv:
4626 ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
4627 break;
4628 #endif
4629 #ifdef TARGET_NR_recvfrom
4630 case TARGET_NR_recvfrom:
4631 ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
4632 break;
4633 #endif
4634 #ifdef TARGET_NR_recvmsg
4635 case TARGET_NR_recvmsg:
4636 ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
4637 break;
4638 #endif
4639 #ifdef TARGET_NR_send
4640 case TARGET_NR_send:
4641 ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
4642 break;
4643 #endif
4644 #ifdef TARGET_NR_sendmsg
4645 case TARGET_NR_sendmsg:
4646 ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
4647 break;
4648 #endif
4649 #ifdef TARGET_NR_sendto
4650 case TARGET_NR_sendto:
4651 ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
4652 break;
4653 #endif
4654 #ifdef TARGET_NR_shutdown
4655 case TARGET_NR_shutdown:
4656 ret = get_errno(shutdown(arg1, arg2));
4657 break;
4658 #endif
4659 #ifdef TARGET_NR_socket
4660 case TARGET_NR_socket:
4661 ret = do_socket(arg1, arg2, arg3);
4662 break;
4663 #endif
4664 #ifdef TARGET_NR_socketpair
4665 case TARGET_NR_socketpair:
4666 ret = do_socketpair(arg1, arg2, arg3, arg4);
4667 break;
4668 #endif
4669 #ifdef TARGET_NR_setsockopt
4670 case TARGET_NR_setsockopt:
4671 ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
4672 break;
4673 #endif
4675 case TARGET_NR_syslog:
4676 if (!(p = lock_user_string(arg2)))
4677 goto efault;
4678 ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
4679 unlock_user(p, arg2, 0);
4680 break;
4682 case TARGET_NR_setitimer:
4684 struct itimerval value, ovalue, *pvalue;
4686 if (arg2) {
4687 pvalue = &value;
4688 if (copy_from_user_timeval(&pvalue->it_interval, arg2)
4689 || copy_from_user_timeval(&pvalue->it_value,
4690 arg2 + sizeof(struct target_timeval)))
4691 goto efault;
4692 } else {
4693 pvalue = NULL;
4695 ret = get_errno(setitimer(arg1, pvalue, &ovalue));
4696 if (!is_error(ret) && arg3) {
4697 if (copy_to_user_timeval(arg3,
4698 &ovalue.it_interval)
4699 || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
4700 &ovalue.it_value))
4701 goto efault;
4704 break;
4705 case TARGET_NR_getitimer:
4707 struct itimerval value;
4709 ret = get_errno(getitimer(arg1, &value));
4710 if (!is_error(ret) && arg2) {
4711 if (copy_to_user_timeval(arg2,
4712 &value.it_interval)
4713 || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
4714 &value.it_value))
4715 goto efault;
4718 break;
4719 case TARGET_NR_stat:
4720 if (!(p = lock_user_string(arg1)))
4721 goto efault;
4722 ret = get_errno(stat(path(p), &st));
4723 unlock_user(p, arg1, 0);
4724 goto do_stat;
4725 case TARGET_NR_lstat:
4726 if (!(p = lock_user_string(arg1)))
4727 goto efault;
4728 ret = get_errno(lstat(path(p), &st));
4729 unlock_user(p, arg1, 0);
4730 goto do_stat;
4731 case TARGET_NR_fstat:
4733 ret = get_errno(fstat(arg1, &st));
4734 do_stat:
4735 if (!is_error(ret)) {
4736 struct target_stat *target_st;
4738 if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
4739 goto efault;
4740 __put_user(st.st_dev, &target_st->st_dev);
4741 __put_user(st.st_ino, &target_st->st_ino);
4742 __put_user(st.st_mode, &target_st->st_mode);
4743 __put_user(st.st_uid, &target_st->st_uid);
4744 __put_user(st.st_gid, &target_st->st_gid);
4745 __put_user(st.st_nlink, &target_st->st_nlink);
4746 __put_user(st.st_rdev, &target_st->st_rdev);
4747 __put_user(st.st_size, &target_st->st_size);
4748 __put_user(st.st_blksize, &target_st->st_blksize);
4749 __put_user(st.st_blocks, &target_st->st_blocks);
4750 __put_user(st.st_atime, &target_st->target_st_atime);
4751 __put_user(st.st_mtime, &target_st->target_st_mtime);
4752 __put_user(st.st_ctime, &target_st->target_st_ctime);
4753 unlock_user_struct(target_st, arg2, 1);
4756 break;
4757 #ifdef TARGET_NR_olduname
4758 case TARGET_NR_olduname:
4759 goto unimplemented;
4760 #endif
4761 #ifdef TARGET_NR_iopl
4762 case TARGET_NR_iopl:
4763 goto unimplemented;
4764 #endif
4765 case TARGET_NR_vhangup:
4766 ret = get_errno(vhangup());
4767 break;
4768 #ifdef TARGET_NR_idle
4769 case TARGET_NR_idle:
4770 goto unimplemented;
4771 #endif
4772 #ifdef TARGET_NR_syscall
4773 case TARGET_NR_syscall:
4774 ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
4775 break;
4776 #endif
4777 case TARGET_NR_wait4:
4779 int status;
4780 abi_long status_ptr = arg2;
4781 struct rusage rusage, *rusage_ptr;
4782 abi_ulong target_rusage = arg4;
4783 if (target_rusage)
4784 rusage_ptr = &rusage;
4785 else
4786 rusage_ptr = NULL;
4787 ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
4788 if (!is_error(ret)) {
4789 if (status_ptr) {
4790 if (put_user_s32(status, status_ptr))
4791 goto efault;
4793 if (target_rusage)
4794 host_to_target_rusage(target_rusage, &rusage);
4797 break;
4798 #ifdef TARGET_NR_swapoff
4799 case TARGET_NR_swapoff:
4800 if (!(p = lock_user_string(arg1)))
4801 goto efault;
4802 ret = get_errno(swapoff(p));
4803 unlock_user(p, arg1, 0);
4804 break;
4805 #endif
4806 case TARGET_NR_sysinfo:
4808 struct target_sysinfo *target_value;
4809 struct sysinfo value;
4810 ret = get_errno(sysinfo(&value));
4811 if (!is_error(ret) && arg1)
4813 if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
4814 goto efault;
4815 __put_user(value.uptime, &target_value->uptime);
4816 __put_user(value.loads[0], &target_value->loads[0]);
4817 __put_user(value.loads[1], &target_value->loads[1]);
4818 __put_user(value.loads[2], &target_value->loads[2]);
4819 __put_user(value.totalram, &target_value->totalram);
4820 __put_user(value.freeram, &target_value->freeram);
4821 __put_user(value.sharedram, &target_value->sharedram);
4822 __put_user(value.bufferram, &target_value->bufferram);
4823 __put_user(value.totalswap, &target_value->totalswap);
4824 __put_user(value.freeswap, &target_value->freeswap);
4825 __put_user(value.procs, &target_value->procs);
4826 __put_user(value.totalhigh, &target_value->totalhigh);
4827 __put_user(value.freehigh, &target_value->freehigh);
4828 __put_user(value.mem_unit, &target_value->mem_unit);
4829 unlock_user_struct(target_value, arg1, 1);
4832 break;
4833 #ifdef TARGET_NR_ipc
4834 case TARGET_NR_ipc:
4835 ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
4836 break;
4837 #endif
4839 #ifdef TARGET_NR_msgctl
4840 case TARGET_NR_msgctl:
4841 ret = do_msgctl(arg1, arg2, arg3);
4842 break;
4843 #endif
4844 #ifdef TARGET_NR_msgget
4845 case TARGET_NR_msgget:
4846 ret = get_errno(msgget(arg1, arg2));
4847 break;
4848 #endif
4849 #ifdef TARGET_NR_msgrcv
4850 case TARGET_NR_msgrcv:
4851 ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
4852 break;
4853 #endif
4854 #ifdef TARGET_NR_msgsnd
4855 case TARGET_NR_msgsnd:
4856 ret = do_msgsnd(arg1, arg2, arg3, arg4);
4857 break;
4858 #endif
4859 case TARGET_NR_fsync:
4860 ret = get_errno(fsync(arg1));
4861 break;
4862 case TARGET_NR_clone:
4863 #if defined(TARGET_SH4)
4864 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
4865 #else
4866 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
4867 #endif
4868 break;
4869 #ifdef __NR_exit_group
4870 /* new thread calls */
4871 case TARGET_NR_exit_group:
4872 #ifdef HAVE_GPROF
4873 _mcleanup();
4874 #endif
4875 gdb_exit(cpu_env, arg1);
4876 ret = get_errno(exit_group(arg1));
4877 break;
4878 #endif
4879 case TARGET_NR_setdomainname:
4880 if (!(p = lock_user_string(arg1)))
4881 goto efault;
4882 ret = get_errno(setdomainname(p, arg2));
4883 unlock_user(p, arg1, 0);
4884 break;
4885 case TARGET_NR_uname:
4886 /* no need to transcode because we use the linux syscall */
4888 struct new_utsname * buf;
4890 if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
4891 goto efault;
4892 ret = get_errno(sys_uname(buf));
4893 if (!is_error(ret)) {
4894 /* Overrite the native machine name with whatever is being
4895 emulated. */
4896 strcpy (buf->machine, UNAME_MACHINE);
4897 /* Allow the user to override the reported release. */
4898 if (qemu_uname_release && *qemu_uname_release)
4899 strcpy (buf->release, qemu_uname_release);
4901 unlock_user_struct(buf, arg1, 1);
4903 break;
4904 #ifdef TARGET_I386
4905 case TARGET_NR_modify_ldt:
4906 ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
4907 break;
4908 #if !defined(TARGET_X86_64)
4909 case TARGET_NR_vm86old:
4910 goto unimplemented;
4911 case TARGET_NR_vm86:
4912 ret = do_vm86(cpu_env, arg1, arg2);
4913 break;
4914 #endif
4915 #endif
4916 case TARGET_NR_adjtimex:
4917 goto unimplemented;
4918 #ifdef TARGET_NR_create_module
4919 case TARGET_NR_create_module:
4920 #endif
4921 case TARGET_NR_init_module:
4922 case TARGET_NR_delete_module:
4923 #ifdef TARGET_NR_get_kernel_syms
4924 case TARGET_NR_get_kernel_syms:
4925 #endif
4926 goto unimplemented;
4927 case TARGET_NR_quotactl:
4928 goto unimplemented;
4929 case TARGET_NR_getpgid:
4930 ret = get_errno(getpgid(arg1));
4931 break;
4932 case TARGET_NR_fchdir:
4933 ret = get_errno(fchdir(arg1));
4934 break;
4935 #ifdef TARGET_NR_bdflush /* not on x86_64 */
4936 case TARGET_NR_bdflush:
4937 goto unimplemented;
4938 #endif
4939 #ifdef TARGET_NR_sysfs
4940 case TARGET_NR_sysfs:
4941 goto unimplemented;
4942 #endif
4943 case TARGET_NR_personality:
4944 ret = get_errno(personality(arg1));
4945 break;
4946 #ifdef TARGET_NR_afs_syscall
4947 case TARGET_NR_afs_syscall:
4948 goto unimplemented;
4949 #endif
4950 #ifdef TARGET_NR__llseek /* Not on alpha */
4951 case TARGET_NR__llseek:
4953 #if defined (__x86_64__)
4954 ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
4955 if (put_user_s64(ret, arg4))
4956 goto efault;
4957 #else
4958 int64_t res;
4959 ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
4960 if (put_user_s64(res, arg4))
4961 goto efault;
4962 #endif
4964 break;
4965 #endif
4966 case TARGET_NR_getdents:
4967 #if TARGET_ABI_BITS != 32
4968 goto unimplemented;
4969 #elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
4971 struct target_dirent *target_dirp;
4972 struct linux_dirent *dirp;
4973 abi_long count = arg3;
4975 dirp = malloc(count);
4976 if (!dirp) {
4977 ret = -TARGET_ENOMEM;
4978 goto fail;
4981 ret = get_errno(sys_getdents(arg1, dirp, count));
4982 if (!is_error(ret)) {
4983 struct linux_dirent *de;
4984 struct target_dirent *tde;
4985 int len = ret;
4986 int reclen, treclen;
4987 int count1, tnamelen;
4989 count1 = 0;
4990 de = dirp;
4991 if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4992 goto efault;
4993 tde = target_dirp;
4994 while (len > 0) {
4995 reclen = de->d_reclen;
4996 treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
4997 tde->d_reclen = tswap16(treclen);
4998 tde->d_ino = tswapl(de->d_ino);
4999 tde->d_off = tswapl(de->d_off);
5000 tnamelen = treclen - (2 * sizeof(abi_long) + 2);
5001 if (tnamelen > 256)
5002 tnamelen = 256;
5003 /* XXX: may not be correct */
5004 pstrcpy(tde->d_name, tnamelen, de->d_name);
5005 de = (struct linux_dirent *)((char *)de + reclen);
5006 len -= reclen;
5007 tde = (struct target_dirent *)((char *)tde + treclen);
5008 count1 += treclen;
5010 ret = count1;
5011 unlock_user(target_dirp, arg2, ret);
5013 free(dirp);
5015 #else
5017 struct linux_dirent *dirp;
5018 abi_long count = arg3;
5020 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5021 goto efault;
5022 ret = get_errno(sys_getdents(arg1, dirp, count));
5023 if (!is_error(ret)) {
5024 struct linux_dirent *de;
5025 int len = ret;
5026 int reclen;
5027 de = dirp;
5028 while (len > 0) {
5029 reclen = de->d_reclen;
5030 if (reclen > len)
5031 break;
5032 de->d_reclen = tswap16(reclen);
5033 tswapls(&de->d_ino);
5034 tswapls(&de->d_off);
5035 de = (struct linux_dirent *)((char *)de + reclen);
5036 len -= reclen;
5039 unlock_user(dirp, arg2, ret);
5041 #endif
5042 break;
5043 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
5044 case TARGET_NR_getdents64:
5046 struct linux_dirent64 *dirp;
5047 abi_long count = arg3;
5048 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5049 goto efault;
5050 ret = get_errno(sys_getdents64(arg1, dirp, count));
5051 if (!is_error(ret)) {
5052 struct linux_dirent64 *de;
5053 int len = ret;
5054 int reclen;
5055 de = dirp;
5056 while (len > 0) {
5057 reclen = de->d_reclen;
5058 if (reclen > len)
5059 break;
5060 de->d_reclen = tswap16(reclen);
5061 tswap64s((uint64_t *)&de->d_ino);
5062 tswap64s((uint64_t *)&de->d_off);
5063 de = (struct linux_dirent64 *)((char *)de + reclen);
5064 len -= reclen;
5067 unlock_user(dirp, arg2, ret);
5069 break;
5070 #endif /* TARGET_NR_getdents64 */
5071 #ifdef TARGET_NR__newselect
5072 case TARGET_NR__newselect:
5073 ret = do_select(arg1, arg2, arg3, arg4, arg5);
5074 break;
5075 #endif
5076 #ifdef TARGET_NR_poll
5077 case TARGET_NR_poll:
5079 struct target_pollfd *target_pfd;
5080 unsigned int nfds = arg2;
5081 int timeout = arg3;
5082 struct pollfd *pfd;
5083 unsigned int i;
5085 target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
5086 if (!target_pfd)
5087 goto efault;
5088 pfd = alloca(sizeof(struct pollfd) * nfds);
5089 for(i = 0; i < nfds; i++) {
5090 pfd[i].fd = tswap32(target_pfd[i].fd);
5091 pfd[i].events = tswap16(target_pfd[i].events);
5093 ret = get_errno(poll(pfd, nfds, timeout));
5094 if (!is_error(ret)) {
5095 for(i = 0; i < nfds; i++) {
5096 target_pfd[i].revents = tswap16(pfd[i].revents);
5098 ret += nfds * (sizeof(struct target_pollfd)
5099 - sizeof(struct pollfd));
5101 unlock_user(target_pfd, arg1, ret);
5103 break;
5104 #endif
5105 case TARGET_NR_flock:
5106 /* NOTE: the flock constant seems to be the same for every
5107 Linux platform */
5108 ret = get_errno(flock(arg1, arg2));
5109 break;
5110 case TARGET_NR_readv:
5112 int count = arg3;
5113 struct iovec *vec;
5115 vec = alloca(count * sizeof(struct iovec));
5116 if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
5117 goto efault;
5118 ret = get_errno(readv(arg1, vec, count));
5119 unlock_iovec(vec, arg2, count, 1);
5121 break;
5122 case TARGET_NR_writev:
5124 int count = arg3;
5125 struct iovec *vec;
5127 vec = alloca(count * sizeof(struct iovec));
5128 if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
5129 goto efault;
5130 ret = get_errno(writev(arg1, vec, count));
5131 unlock_iovec(vec, arg2, count, 0);
5133 break;
5134 case TARGET_NR_getsid:
5135 ret = get_errno(getsid(arg1));
5136 break;
5137 #if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
5138 case TARGET_NR_fdatasync:
5139 ret = get_errno(fdatasync(arg1));
5140 break;
5141 #endif
5142 case TARGET_NR__sysctl:
5143 /* We don't implement this, but ENOTDIR is always a safe
5144 return value. */
5145 ret = -TARGET_ENOTDIR;
5146 break;
5147 case TARGET_NR_sched_setparam:
5149 struct sched_param *target_schp;
5150 struct sched_param schp;
5152 if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
5153 goto efault;
5154 schp.sched_priority = tswap32(target_schp->sched_priority);
5155 unlock_user_struct(target_schp, arg2, 0);
5156 ret = get_errno(sched_setparam(arg1, &schp));
5158 break;
5159 case TARGET_NR_sched_getparam:
5161 struct sched_param *target_schp;
5162 struct sched_param schp;
5163 ret = get_errno(sched_getparam(arg1, &schp));
5164 if (!is_error(ret)) {
5165 if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
5166 goto efault;
5167 target_schp->sched_priority = tswap32(schp.sched_priority);
5168 unlock_user_struct(target_schp, arg2, 1);
5171 break;
5172 case TARGET_NR_sched_setscheduler:
5174 struct sched_param *target_schp;
5175 struct sched_param schp;
5176 if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
5177 goto efault;
5178 schp.sched_priority = tswap32(target_schp->sched_priority);
5179 unlock_user_struct(target_schp, arg3, 0);
5180 ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
5182 break;
5183 case TARGET_NR_sched_getscheduler:
5184 ret = get_errno(sched_getscheduler(arg1));
5185 break;
5186 case TARGET_NR_sched_yield:
5187 ret = get_errno(sched_yield());
5188 break;
5189 case TARGET_NR_sched_get_priority_max:
5190 ret = get_errno(sched_get_priority_max(arg1));
5191 break;
5192 case TARGET_NR_sched_get_priority_min:
5193 ret = get_errno(sched_get_priority_min(arg1));
5194 break;
5195 case TARGET_NR_sched_rr_get_interval:
5197 struct timespec ts;
5198 ret = get_errno(sched_rr_get_interval(arg1, &ts));
5199 if (!is_error(ret)) {
5200 host_to_target_timespec(arg2, &ts);
5203 break;
5204 case TARGET_NR_nanosleep:
5206 struct timespec req, rem;
5207 target_to_host_timespec(&req, arg1);
5208 ret = get_errno(nanosleep(&req, &rem));
5209 if (is_error(ret) && arg2) {
5210 host_to_target_timespec(arg2, &rem);
5213 break;
5214 #ifdef TARGET_NR_query_module
5215 case TARGET_NR_query_module:
5216 goto unimplemented;
5217 #endif
5218 #ifdef TARGET_NR_nfsservctl
5219 case TARGET_NR_nfsservctl:
5220 goto unimplemented;
5221 #endif
5222 case TARGET_NR_prctl:
5223 switch (arg1)
5225 case PR_GET_PDEATHSIG:
5227 int deathsig;
5228 ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
5229 if (!is_error(ret) && arg2
5230 && put_user_ual(deathsig, arg2))
5231 goto efault;
5233 break;
5234 default:
5235 ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
5236 break;
5238 break;
5239 #ifdef TARGET_NR_arch_prctl
5240 case TARGET_NR_arch_prctl:
5241 #if defined(TARGET_I386) && !defined(TARGET_ABI32)
5242 ret = do_arch_prctl(cpu_env, arg1, arg2);
5243 break;
5244 #else
5245 goto unimplemented;
5246 #endif
5247 #endif
5248 #ifdef TARGET_NR_pread
5249 case TARGET_NR_pread:
5250 #ifdef TARGET_ARM
5251 if (((CPUARMState *)cpu_env)->eabi)
5252 arg4 = arg5;
5253 #endif
5254 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5255 goto efault;
5256 ret = get_errno(pread(arg1, p, arg3, arg4));
5257 unlock_user(p, arg2, ret);
5258 break;
5259 case TARGET_NR_pwrite:
5260 #ifdef TARGET_ARM
5261 if (((CPUARMState *)cpu_env)->eabi)
5262 arg4 = arg5;
5263 #endif
5264 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5265 goto efault;
5266 ret = get_errno(pwrite(arg1, p, arg3, arg4));
5267 unlock_user(p, arg2, 0);
5268 break;
5269 #endif
5270 #ifdef TARGET_NR_pread64
5271 case TARGET_NR_pread64:
5272 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5273 goto efault;
5274 ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
5275 unlock_user(p, arg2, ret);
5276 break;
5277 case TARGET_NR_pwrite64:
5278 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5279 goto efault;
5280 ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
5281 unlock_user(p, arg2, 0);
5282 break;
5283 #endif
5284 case TARGET_NR_getcwd:
5285 if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
5286 goto efault;
5287 ret = get_errno(sys_getcwd1(p, arg2));
5288 unlock_user(p, arg1, ret);
5289 break;
5290 case TARGET_NR_capget:
5291 goto unimplemented;
5292 case TARGET_NR_capset:
5293 goto unimplemented;
5294 case TARGET_NR_sigaltstack:
5295 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
5296 defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA)
5297 ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env));
5298 break;
5299 #else
5300 goto unimplemented;
5301 #endif
5302 case TARGET_NR_sendfile:
5303 goto unimplemented;
5304 #ifdef TARGET_NR_getpmsg
5305 case TARGET_NR_getpmsg:
5306 goto unimplemented;
5307 #endif
5308 #ifdef TARGET_NR_putpmsg
5309 case TARGET_NR_putpmsg:
5310 goto unimplemented;
5311 #endif
5312 #ifdef TARGET_NR_vfork
5313 case TARGET_NR_vfork:
5314 ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
5315 0, 0, 0, 0));
5316 break;
5317 #endif
5318 #ifdef TARGET_NR_ugetrlimit
5319 case TARGET_NR_ugetrlimit:
5321 struct rlimit rlim;
5322 ret = get_errno(getrlimit(arg1, &rlim));
5323 if (!is_error(ret)) {
5324 struct target_rlimit *target_rlim;
5325 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
5326 goto efault;
5327 target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
5328 target_rlim->rlim_max = tswapl(rlim.rlim_max);
5329 unlock_user_struct(target_rlim, arg2, 1);
5331 break;
5333 #endif
5334 #ifdef TARGET_NR_truncate64
5335 case TARGET_NR_truncate64:
5336 if (!(p = lock_user_string(arg1)))
5337 goto efault;
5338 ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
5339 unlock_user(p, arg1, 0);
5340 break;
5341 #endif
5342 #ifdef TARGET_NR_ftruncate64
5343 case TARGET_NR_ftruncate64:
5344 ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
5345 break;
5346 #endif
5347 #ifdef TARGET_NR_stat64
5348 case TARGET_NR_stat64:
5349 if (!(p = lock_user_string(arg1)))
5350 goto efault;
5351 ret = get_errno(stat(path(p), &st));
5352 unlock_user(p, arg1, 0);
5353 if (!is_error(ret))
5354 ret = host_to_target_stat64(cpu_env, arg2, &st);
5355 break;
5356 #endif
5357 #ifdef TARGET_NR_lstat64
5358 case TARGET_NR_lstat64:
5359 if (!(p = lock_user_string(arg1)))
5360 goto efault;
5361 ret = get_errno(lstat(path(p), &st));
5362 unlock_user(p, arg1, 0);
5363 if (!is_error(ret))
5364 ret = host_to_target_stat64(cpu_env, arg2, &st);
5365 break;
5366 #endif
5367 #ifdef TARGET_NR_fstat64
5368 case TARGET_NR_fstat64:
5369 ret = get_errno(fstat(arg1, &st));
5370 if (!is_error(ret))
5371 ret = host_to_target_stat64(cpu_env, arg2, &st);
5372 break;
5373 #endif
5374 #if defined(TARGET_NR_fstatat64) && defined(__NR_fstatat64)
5375 case TARGET_NR_fstatat64:
5376 if (!(p = lock_user_string(arg2)))
5377 goto efault;
5378 ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
5379 if (!is_error(ret))
5380 ret = host_to_target_stat64(cpu_env, arg3, &st);
5381 break;
5382 #endif
5383 #ifdef USE_UID16
5384 case TARGET_NR_lchown:
5385 if (!(p = lock_user_string(arg1)))
5386 goto efault;
5387 ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
5388 unlock_user(p, arg1, 0);
5389 break;
5390 case TARGET_NR_getuid:
5391 ret = get_errno(high2lowuid(getuid()));
5392 break;
5393 case TARGET_NR_getgid:
5394 ret = get_errno(high2lowgid(getgid()));
5395 break;
5396 case TARGET_NR_geteuid:
5397 ret = get_errno(high2lowuid(geteuid()));
5398 break;
5399 case TARGET_NR_getegid:
5400 ret = get_errno(high2lowgid(getegid()));
5401 break;
5402 case TARGET_NR_setreuid:
5403 ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
5404 break;
5405 case TARGET_NR_setregid:
5406 ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
5407 break;
5408 case TARGET_NR_getgroups:
5410 int gidsetsize = arg1;
5411 uint16_t *target_grouplist;
5412 gid_t *grouplist;
5413 int i;
5415 grouplist = alloca(gidsetsize * sizeof(gid_t));
5416 ret = get_errno(getgroups(gidsetsize, grouplist));
5417 if (gidsetsize == 0)
5418 break;
5419 if (!is_error(ret)) {
5420 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
5421 if (!target_grouplist)
5422 goto efault;
5423 for(i = 0;i < ret; i++)
5424 target_grouplist[i] = tswap16(grouplist[i]);
5425 unlock_user(target_grouplist, arg2, gidsetsize * 2);
5428 break;
5429 case TARGET_NR_setgroups:
5431 int gidsetsize = arg1;
5432 uint16_t *target_grouplist;
5433 gid_t *grouplist;
5434 int i;
5436 grouplist = alloca(gidsetsize * sizeof(gid_t));
5437 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
5438 if (!target_grouplist) {
5439 ret = -TARGET_EFAULT;
5440 goto fail;
5442 for(i = 0;i < gidsetsize; i++)
5443 grouplist[i] = tswap16(target_grouplist[i]);
5444 unlock_user(target_grouplist, arg2, 0);
5445 ret = get_errno(setgroups(gidsetsize, grouplist));
5447 break;
5448 case TARGET_NR_fchown:
5449 ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
5450 break;
5451 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
5452 case TARGET_NR_fchownat:
5453 if (!(p = lock_user_string(arg2)))
5454 goto efault;
5455 ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
5456 unlock_user(p, arg2, 0);
5457 break;
5458 #endif
5459 #ifdef TARGET_NR_setresuid
5460 case TARGET_NR_setresuid:
5461 ret = get_errno(setresuid(low2highuid(arg1),
5462 low2highuid(arg2),
5463 low2highuid(arg3)));
5464 break;
5465 #endif
5466 #ifdef TARGET_NR_getresuid
5467 case TARGET_NR_getresuid:
5469 uid_t ruid, euid, suid;
5470 ret = get_errno(getresuid(&ruid, &euid, &suid));
5471 if (!is_error(ret)) {
5472 if (put_user_u16(high2lowuid(ruid), arg1)
5473 || put_user_u16(high2lowuid(euid), arg2)
5474 || put_user_u16(high2lowuid(suid), arg3))
5475 goto efault;
5478 break;
5479 #endif
5480 #ifdef TARGET_NR_getresgid
5481 case TARGET_NR_setresgid:
5482 ret = get_errno(setresgid(low2highgid(arg1),
5483 low2highgid(arg2),
5484 low2highgid(arg3)));
5485 break;
5486 #endif
5487 #ifdef TARGET_NR_getresgid
5488 case TARGET_NR_getresgid:
5490 gid_t rgid, egid, sgid;
5491 ret = get_errno(getresgid(&rgid, &egid, &sgid));
5492 if (!is_error(ret)) {
5493 if (put_user_u16(high2lowgid(rgid), arg1)
5494 || put_user_u16(high2lowgid(egid), arg2)
5495 || put_user_u16(high2lowgid(sgid), arg3))
5496 goto efault;
5499 break;
5500 #endif
5501 case TARGET_NR_chown:
5502 if (!(p = lock_user_string(arg1)))
5503 goto efault;
5504 ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
5505 unlock_user(p, arg1, 0);
5506 break;
5507 case TARGET_NR_setuid:
5508 ret = get_errno(setuid(low2highuid(arg1)));
5509 break;
5510 case TARGET_NR_setgid:
5511 ret = get_errno(setgid(low2highgid(arg1)));
5512 break;
5513 case TARGET_NR_setfsuid:
5514 ret = get_errno(setfsuid(arg1));
5515 break;
5516 case TARGET_NR_setfsgid:
5517 ret = get_errno(setfsgid(arg1));
5518 break;
5519 #endif /* USE_UID16 */
5521 #ifdef TARGET_NR_lchown32
5522 case TARGET_NR_lchown32:
5523 if (!(p = lock_user_string(arg1)))
5524 goto efault;
5525 ret = get_errno(lchown(p, arg2, arg3));
5526 unlock_user(p, arg1, 0);
5527 break;
5528 #endif
5529 #ifdef TARGET_NR_getuid32
5530 case TARGET_NR_getuid32:
5531 ret = get_errno(getuid());
5532 break;
5533 #endif
5535 #if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
5536 /* Alpha specific */
5537 case TARGET_NR_getxuid:
5539 uid_t euid;
5540 euid=geteuid();
5541 ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
5543 ret = get_errno(getuid());
5544 break;
5545 #endif
5546 #if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
5547 /* Alpha specific */
5548 case TARGET_NR_getxgid:
5550 uid_t egid;
5551 egid=getegid();
5552 ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
5554 ret = get_errno(getgid());
5555 break;
5556 #endif
5558 #ifdef TARGET_NR_getgid32
5559 case TARGET_NR_getgid32:
5560 ret = get_errno(getgid());
5561 break;
5562 #endif
5563 #ifdef TARGET_NR_geteuid32
5564 case TARGET_NR_geteuid32:
5565 ret = get_errno(geteuid());
5566 break;
5567 #endif
5568 #ifdef TARGET_NR_getegid32
5569 case TARGET_NR_getegid32:
5570 ret = get_errno(getegid());
5571 break;
5572 #endif
5573 #ifdef TARGET_NR_setreuid32
5574 case TARGET_NR_setreuid32:
5575 ret = get_errno(setreuid(arg1, arg2));
5576 break;
5577 #endif
5578 #ifdef TARGET_NR_setregid32
5579 case TARGET_NR_setregid32:
5580 ret = get_errno(setregid(arg1, arg2));
5581 break;
5582 #endif
5583 #ifdef TARGET_NR_getgroups32
5584 case TARGET_NR_getgroups32:
5586 int gidsetsize = arg1;
5587 uint32_t *target_grouplist;
5588 gid_t *grouplist;
5589 int i;
5591 grouplist = alloca(gidsetsize * sizeof(gid_t));
5592 ret = get_errno(getgroups(gidsetsize, grouplist));
5593 if (gidsetsize == 0)
5594 break;
5595 if (!is_error(ret)) {
5596 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
5597 if (!target_grouplist) {
5598 ret = -TARGET_EFAULT;
5599 goto fail;
5601 for(i = 0;i < ret; i++)
5602 target_grouplist[i] = tswap32(grouplist[i]);
5603 unlock_user(target_grouplist, arg2, gidsetsize * 4);
5606 break;
5607 #endif
5608 #ifdef TARGET_NR_setgroups32
5609 case TARGET_NR_setgroups32:
5611 int gidsetsize = arg1;
5612 uint32_t *target_grouplist;
5613 gid_t *grouplist;
5614 int i;
5616 grouplist = alloca(gidsetsize * sizeof(gid_t));
5617 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
5618 if (!target_grouplist) {
5619 ret = -TARGET_EFAULT;
5620 goto fail;
5622 for(i = 0;i < gidsetsize; i++)
5623 grouplist[i] = tswap32(target_grouplist[i]);
5624 unlock_user(target_grouplist, arg2, 0);
5625 ret = get_errno(setgroups(gidsetsize, grouplist));
5627 break;
5628 #endif
5629 #ifdef TARGET_NR_fchown32
5630 case TARGET_NR_fchown32:
5631 ret = get_errno(fchown(arg1, arg2, arg3));
5632 break;
5633 #endif
5634 #ifdef TARGET_NR_setresuid32
5635 case TARGET_NR_setresuid32:
5636 ret = get_errno(setresuid(arg1, arg2, arg3));
5637 break;
5638 #endif
5639 #ifdef TARGET_NR_getresuid32
5640 case TARGET_NR_getresuid32:
5642 uid_t ruid, euid, suid;
5643 ret = get_errno(getresuid(&ruid, &euid, &suid));
5644 if (!is_error(ret)) {
5645 if (put_user_u32(ruid, arg1)
5646 || put_user_u32(euid, arg2)
5647 || put_user_u32(suid, arg3))
5648 goto efault;
5651 break;
5652 #endif
5653 #ifdef TARGET_NR_setresgid32
5654 case TARGET_NR_setresgid32:
5655 ret = get_errno(setresgid(arg1, arg2, arg3));
5656 break;
5657 #endif
5658 #ifdef TARGET_NR_getresgid32
5659 case TARGET_NR_getresgid32:
5661 gid_t rgid, egid, sgid;
5662 ret = get_errno(getresgid(&rgid, &egid, &sgid));
5663 if (!is_error(ret)) {
5664 if (put_user_u32(rgid, arg1)
5665 || put_user_u32(egid, arg2)
5666 || put_user_u32(sgid, arg3))
5667 goto efault;
5670 break;
5671 #endif
5672 #ifdef TARGET_NR_chown32
5673 case TARGET_NR_chown32:
5674 if (!(p = lock_user_string(arg1)))
5675 goto efault;
5676 ret = get_errno(chown(p, arg2, arg3));
5677 unlock_user(p, arg1, 0);
5678 break;
5679 #endif
5680 #ifdef TARGET_NR_setuid32
5681 case TARGET_NR_setuid32:
5682 ret = get_errno(setuid(arg1));
5683 break;
5684 #endif
5685 #ifdef TARGET_NR_setgid32
5686 case TARGET_NR_setgid32:
5687 ret = get_errno(setgid(arg1));
5688 break;
5689 #endif
5690 #ifdef TARGET_NR_setfsuid32
5691 case TARGET_NR_setfsuid32:
5692 ret = get_errno(setfsuid(arg1));
5693 break;
5694 #endif
5695 #ifdef TARGET_NR_setfsgid32
5696 case TARGET_NR_setfsgid32:
5697 ret = get_errno(setfsgid(arg1));
5698 break;
5699 #endif
5701 case TARGET_NR_pivot_root:
5702 goto unimplemented;
5703 #ifdef TARGET_NR_mincore
5704 case TARGET_NR_mincore:
5706 void *a;
5707 ret = -TARGET_EFAULT;
5708 if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
5709 goto efault;
5710 if (!(p = lock_user_string(arg3)))
5711 goto mincore_fail;
5712 ret = get_errno(mincore(a, arg2, p));
5713 unlock_user(p, arg3, ret);
5714 mincore_fail:
5715 unlock_user(a, arg1, 0);
5717 break;
5718 #endif
5719 #ifdef TARGET_NR_arm_fadvise64_64
5720 case TARGET_NR_arm_fadvise64_64:
5723 * arm_fadvise64_64 looks like fadvise64_64 but
5724 * with different argument order
5726 abi_long temp;
5727 temp = arg3;
5728 arg3 = arg4;
5729 arg4 = temp;
5731 #endif
5732 #if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64)
5733 #ifdef TARGET_NR_fadvise64_64
5734 case TARGET_NR_fadvise64_64:
5735 #endif
5736 /* This is a hint, so ignoring and returning success is ok. */
5737 ret = get_errno(0);
5738 break;
5739 #endif
5740 #ifdef TARGET_NR_madvise
5741 case TARGET_NR_madvise:
5742 /* A straight passthrough may not be safe because qemu sometimes
5743 turns private flie-backed mappings into anonymous mappings.
5744 This will break MADV_DONTNEED.
5745 This is a hint, so ignoring and returning success is ok. */
5746 ret = get_errno(0);
5747 break;
5748 #endif
5749 #if TARGET_ABI_BITS == 32
5750 case TARGET_NR_fcntl64:
5752 int cmd;
5753 struct flock64 fl;
5754 struct target_flock64 *target_fl;
5755 #ifdef TARGET_ARM
5756 struct target_eabi_flock64 *target_efl;
5757 #endif
5759 switch(arg2){
5760 case TARGET_F_GETLK64:
5761 cmd = F_GETLK64;
5762 break;
5763 case TARGET_F_SETLK64:
5764 cmd = F_SETLK64;
5765 break;
5766 case TARGET_F_SETLKW64:
5767 cmd = F_SETLK64;
5768 break;
5769 default:
5770 cmd = arg2;
5771 break;
5774 switch(arg2) {
5775 case TARGET_F_GETLK64:
5776 #ifdef TARGET_ARM
5777 if (((CPUARMState *)cpu_env)->eabi) {
5778 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1))
5779 goto efault;
5780 fl.l_type = tswap16(target_efl->l_type);
5781 fl.l_whence = tswap16(target_efl->l_whence);
5782 fl.l_start = tswap64(target_efl->l_start);
5783 fl.l_len = tswap64(target_efl->l_len);
5784 fl.l_pid = tswapl(target_efl->l_pid);
5785 unlock_user_struct(target_efl, arg3, 0);
5786 } else
5787 #endif
5789 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1))
5790 goto efault;
5791 fl.l_type = tswap16(target_fl->l_type);
5792 fl.l_whence = tswap16(target_fl->l_whence);
5793 fl.l_start = tswap64(target_fl->l_start);
5794 fl.l_len = tswap64(target_fl->l_len);
5795 fl.l_pid = tswapl(target_fl->l_pid);
5796 unlock_user_struct(target_fl, arg3, 0);
5798 ret = get_errno(fcntl(arg1, cmd, &fl));
5799 if (ret == 0) {
5800 #ifdef TARGET_ARM
5801 if (((CPUARMState *)cpu_env)->eabi) {
5802 if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0))
5803 goto efault;
5804 target_efl->l_type = tswap16(fl.l_type);
5805 target_efl->l_whence = tswap16(fl.l_whence);
5806 target_efl->l_start = tswap64(fl.l_start);
5807 target_efl->l_len = tswap64(fl.l_len);
5808 target_efl->l_pid = tswapl(fl.l_pid);
5809 unlock_user_struct(target_efl, arg3, 1);
5810 } else
5811 #endif
5813 if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0))
5814 goto efault;
5815 target_fl->l_type = tswap16(fl.l_type);
5816 target_fl->l_whence = tswap16(fl.l_whence);
5817 target_fl->l_start = tswap64(fl.l_start);
5818 target_fl->l_len = tswap64(fl.l_len);
5819 target_fl->l_pid = tswapl(fl.l_pid);
5820 unlock_user_struct(target_fl, arg3, 1);
5823 break;
5825 case TARGET_F_SETLK64:
5826 case TARGET_F_SETLKW64:
5827 #ifdef TARGET_ARM
5828 if (((CPUARMState *)cpu_env)->eabi) {
5829 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1))
5830 goto efault;
5831 fl.l_type = tswap16(target_efl->l_type);
5832 fl.l_whence = tswap16(target_efl->l_whence);
5833 fl.l_start = tswap64(target_efl->l_start);
5834 fl.l_len = tswap64(target_efl->l_len);
5835 fl.l_pid = tswapl(target_efl->l_pid);
5836 unlock_user_struct(target_efl, arg3, 0);
5837 } else
5838 #endif
5840 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1))
5841 goto efault;
5842 fl.l_type = tswap16(target_fl->l_type);
5843 fl.l_whence = tswap16(target_fl->l_whence);
5844 fl.l_start = tswap64(target_fl->l_start);
5845 fl.l_len = tswap64(target_fl->l_len);
5846 fl.l_pid = tswapl(target_fl->l_pid);
5847 unlock_user_struct(target_fl, arg3, 0);
5849 ret = get_errno(fcntl(arg1, cmd, &fl));
5850 break;
5851 default:
5852 ret = do_fcntl(arg1, cmd, arg3);
5853 break;
5855 break;
5857 #endif
5858 #ifdef TARGET_NR_cacheflush
5859 case TARGET_NR_cacheflush:
5860 /* self-modifying code is handled automatically, so nothing needed */
5861 ret = 0;
5862 break;
5863 #endif
5864 #ifdef TARGET_NR_security
5865 case TARGET_NR_security:
5866 goto unimplemented;
5867 #endif
5868 #ifdef TARGET_NR_getpagesize
5869 case TARGET_NR_getpagesize:
5870 ret = TARGET_PAGE_SIZE;
5871 break;
5872 #endif
5873 case TARGET_NR_gettid:
5874 ret = get_errno(gettid());
5875 break;
5876 #ifdef TARGET_NR_readahead
5877 case TARGET_NR_readahead:
5878 #if TARGET_ABI_BITS == 32
5879 #ifdef TARGET_ARM
5880 if (((CPUARMState *)cpu_env)->eabi)
5882 arg2 = arg3;
5883 arg3 = arg4;
5884 arg4 = arg5;
5886 #endif
5887 ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
5888 #else
5889 ret = get_errno(readahead(arg1, arg2, arg3));
5890 #endif
5891 break;
5892 #endif
5893 #ifdef TARGET_NR_setxattr
5894 case TARGET_NR_setxattr:
5895 case TARGET_NR_lsetxattr:
5896 case TARGET_NR_fsetxattr:
5897 case TARGET_NR_getxattr:
5898 case TARGET_NR_lgetxattr:
5899 case TARGET_NR_fgetxattr:
5900 case TARGET_NR_listxattr:
5901 case TARGET_NR_llistxattr:
5902 case TARGET_NR_flistxattr:
5903 case TARGET_NR_removexattr:
5904 case TARGET_NR_lremovexattr:
5905 case TARGET_NR_fremovexattr:
5906 goto unimplemented_nowarn;
5907 #endif
5908 #ifdef TARGET_NR_set_thread_area
5909 case TARGET_NR_set_thread_area:
5910 #if defined(TARGET_MIPS)
5911 ((CPUMIPSState *) cpu_env)->tls_value = arg1;
5912 ret = 0;
5913 break;
5914 #elif defined(TARGET_I386) && defined(TARGET_ABI32)
5915 ret = do_set_thread_area(cpu_env, arg1);
5916 break;
5917 #else
5918 goto unimplemented_nowarn;
5919 #endif
5920 #endif
5921 #ifdef TARGET_NR_get_thread_area
5922 case TARGET_NR_get_thread_area:
5923 #if defined(TARGET_I386) && defined(TARGET_ABI32)
5924 ret = do_get_thread_area(cpu_env, arg1);
5925 #else
5926 goto unimplemented_nowarn;
5927 #endif
5928 #endif
5929 #ifdef TARGET_NR_getdomainname
5930 case TARGET_NR_getdomainname:
5931 goto unimplemented_nowarn;
5932 #endif
5934 #ifdef TARGET_NR_clock_gettime
5935 case TARGET_NR_clock_gettime:
5937 struct timespec ts;
5938 ret = get_errno(clock_gettime(arg1, &ts));
5939 if (!is_error(ret)) {
5940 host_to_target_timespec(arg2, &ts);
5942 break;
5944 #endif
5945 #ifdef TARGET_NR_clock_getres
5946 case TARGET_NR_clock_getres:
5948 struct timespec ts;
5949 ret = get_errno(clock_getres(arg1, &ts));
5950 if (!is_error(ret)) {
5951 host_to_target_timespec(arg2, &ts);
5953 break;
5955 #endif
5956 #ifdef TARGET_NR_clock_nanosleep
5957 case TARGET_NR_clock_nanosleep:
5959 struct timespec ts;
5960 target_to_host_timespec(&ts, arg3);
5961 ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
5962 if (arg4)
5963 host_to_target_timespec(arg4, &ts);
5964 break;
5966 #endif
5968 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
5969 case TARGET_NR_set_tid_address:
5970 ret = get_errno(set_tid_address((int *)g2h(arg1)));
5971 break;
5972 #endif
5974 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
5975 case TARGET_NR_tkill:
5976 ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
5977 break;
5978 #endif
5980 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
5981 case TARGET_NR_tgkill:
5982 ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
5983 target_to_host_signal(arg3)));
5984 break;
5985 #endif
5987 #ifdef TARGET_NR_set_robust_list
5988 case TARGET_NR_set_robust_list:
5989 goto unimplemented_nowarn;
5990 #endif
5992 #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
5993 case TARGET_NR_utimensat:
5995 struct timespec ts[2];
5996 target_to_host_timespec(ts, arg3);
5997 target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
5998 if (!arg2)
5999 ret = get_errno(sys_utimensat(arg1, NULL, ts, arg4));
6000 else {
6001 if (!(p = lock_user_string(arg2))) {
6002 ret = -TARGET_EFAULT;
6003 goto fail;
6005 ret = get_errno(sys_utimensat(arg1, path(p), ts, arg4));
6006 unlock_user(p, arg2, 0);
6009 break;
6010 #endif
6011 #if defined(USE_NPTL)
6012 case TARGET_NR_futex:
6013 ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
6014 break;
6015 #endif
6016 #ifdef TARGET_NR_inotify_init
6017 case TARGET_NR_inotify_init:
6018 ret = get_errno(sys_inotify_init());
6019 break;
6020 #endif
6021 #ifdef TARGET_NR_inotify_add_watch
6022 case TARGET_NR_inotify_add_watch:
6023 p = lock_user_string(arg2);
6024 ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
6025 unlock_user(p, arg2, 0);
6026 break;
6027 #endif
6028 #ifdef TARGET_NR_inotify_rm_watch
6029 case TARGET_NR_inotify_rm_watch:
6030 ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
6031 break;
6032 #endif
6034 default:
6035 unimplemented:
6036 gemu_log("qemu: Unsupported syscall: %d\n", num);
6037 #if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
6038 unimplemented_nowarn:
6039 #endif
6040 ret = -TARGET_ENOSYS;
6041 break;
6043 fail:
6044 #ifdef DEBUG
6045 gemu_log(" = %ld\n", ret);
6046 #endif
6047 if(do_strace)
6048 print_syscall_ret(num, ret);
6049 return ret;
6050 efault:
6051 ret = -TARGET_EFAULT;
6052 goto fail;