target-sh4: Add SH bit handling to TLB
[qemu/qemu-JZ.git] / linux-user / syscall.c
blob4065917848565fbbdbc8e293e7f713856ad560db
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 #define N_SHM_REGIONS 32
1619 static struct shm_region {
1620 abi_ulong start;
1621 abi_ulong size;
1622 } shm_regions[N_SHM_REGIONS];
1624 struct target_ipc_perm
1626 abi_long __key;
1627 abi_ulong uid;
1628 abi_ulong gid;
1629 abi_ulong cuid;
1630 abi_ulong cgid;
1631 unsigned short int mode;
1632 unsigned short int __pad1;
1633 unsigned short int __seq;
1634 unsigned short int __pad2;
1635 abi_ulong __unused1;
1636 abi_ulong __unused2;
1639 struct target_semid_ds
1641 struct target_ipc_perm sem_perm;
1642 abi_ulong sem_otime;
1643 abi_ulong __unused1;
1644 abi_ulong sem_ctime;
1645 abi_ulong __unused2;
1646 abi_ulong sem_nsems;
1647 abi_ulong __unused3;
1648 abi_ulong __unused4;
1651 static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
1652 abi_ulong target_addr)
1654 struct target_ipc_perm *target_ip;
1655 struct target_semid_ds *target_sd;
1657 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
1658 return -TARGET_EFAULT;
1659 target_ip=&(target_sd->sem_perm);
1660 host_ip->__key = tswapl(target_ip->__key);
1661 host_ip->uid = tswapl(target_ip->uid);
1662 host_ip->gid = tswapl(target_ip->gid);
1663 host_ip->cuid = tswapl(target_ip->cuid);
1664 host_ip->cgid = tswapl(target_ip->cgid);
1665 host_ip->mode = tswapl(target_ip->mode);
1666 unlock_user_struct(target_sd, target_addr, 0);
1667 return 0;
1670 static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
1671 struct ipc_perm *host_ip)
1673 struct target_ipc_perm *target_ip;
1674 struct target_semid_ds *target_sd;
1676 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
1677 return -TARGET_EFAULT;
1678 target_ip = &(target_sd->sem_perm);
1679 target_ip->__key = tswapl(host_ip->__key);
1680 target_ip->uid = tswapl(host_ip->uid);
1681 target_ip->gid = tswapl(host_ip->gid);
1682 target_ip->cuid = tswapl(host_ip->cuid);
1683 target_ip->cgid = tswapl(host_ip->cgid);
1684 target_ip->mode = tswapl(host_ip->mode);
1685 unlock_user_struct(target_sd, target_addr, 1);
1686 return 0;
1689 static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
1690 abi_ulong target_addr)
1692 struct target_semid_ds *target_sd;
1694 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
1695 return -TARGET_EFAULT;
1696 target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr);
1697 host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
1698 host_sd->sem_otime = tswapl(target_sd->sem_otime);
1699 host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
1700 unlock_user_struct(target_sd, target_addr, 0);
1701 return 0;
1704 static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
1705 struct semid_ds *host_sd)
1707 struct target_semid_ds *target_sd;
1709 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
1710 return -TARGET_EFAULT;
1711 host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm));
1712 target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
1713 target_sd->sem_otime = tswapl(host_sd->sem_otime);
1714 target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
1715 unlock_user_struct(target_sd, target_addr, 1);
1716 return 0;
1719 union semun {
1720 int val;
1721 struct semid_ds *buf;
1722 unsigned short *array;
1725 union target_semun {
1726 int val;
1727 abi_long buf;
1728 unsigned short int *array;
1731 static inline abi_long target_to_host_semun(int cmd,
1732 union semun *host_su,
1733 abi_ulong target_addr,
1734 struct semid_ds *ds)
1736 union target_semun *target_su;
1738 switch( cmd ) {
1739 case IPC_STAT:
1740 case IPC_SET:
1741 if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1742 return -TARGET_EFAULT;
1743 target_to_host_semid_ds(ds,target_su->buf);
1744 host_su->buf = ds;
1745 unlock_user_struct(target_su, target_addr, 0);
1746 break;
1747 case GETVAL:
1748 case SETVAL:
1749 if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1750 return -TARGET_EFAULT;
1751 host_su->val = tswapl(target_su->val);
1752 unlock_user_struct(target_su, target_addr, 0);
1753 break;
1754 case GETALL:
1755 case SETALL:
1756 if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1757 return -TARGET_EFAULT;
1758 *host_su->array = tswap16(*target_su->array);
1759 unlock_user_struct(target_su, target_addr, 0);
1760 break;
1761 default:
1762 gemu_log("semun operation not fully supported: %d\n", (int)cmd);
1764 return 0;
1767 static inline abi_long host_to_target_semun(int cmd,
1768 abi_ulong target_addr,
1769 union semun *host_su,
1770 struct semid_ds *ds)
1772 union target_semun *target_su;
1774 switch( cmd ) {
1775 case IPC_STAT:
1776 case IPC_SET:
1777 if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1778 return -TARGET_EFAULT;
1779 host_to_target_semid_ds(target_su->buf,ds);
1780 unlock_user_struct(target_su, target_addr, 1);
1781 break;
1782 case GETVAL:
1783 case SETVAL:
1784 if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1785 return -TARGET_EFAULT;
1786 target_su->val = tswapl(host_su->val);
1787 unlock_user_struct(target_su, target_addr, 1);
1788 break;
1789 case GETALL:
1790 case SETALL:
1791 if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1792 return -TARGET_EFAULT;
1793 *target_su->array = tswap16(*host_su->array);
1794 unlock_user_struct(target_su, target_addr, 1);
1795 break;
1796 default:
1797 gemu_log("semun operation not fully supported: %d\n", (int)cmd);
1799 return 0;
1802 static inline abi_long do_semctl(int first, int second, int third,
1803 abi_long ptr)
1805 union semun arg;
1806 struct semid_ds dsarg;
1807 int cmd = third&0xff;
1808 abi_long ret = 0;
1810 switch( cmd ) {
1811 case GETVAL:
1812 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1813 ret = get_errno(semctl(first, second, cmd, arg));
1814 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1815 break;
1816 case SETVAL:
1817 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1818 ret = get_errno(semctl(first, second, cmd, arg));
1819 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1820 break;
1821 case GETALL:
1822 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1823 ret = get_errno(semctl(first, second, cmd, arg));
1824 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1825 break;
1826 case SETALL:
1827 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1828 ret = get_errno(semctl(first, second, cmd, arg));
1829 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1830 break;
1831 case IPC_STAT:
1832 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1833 ret = get_errno(semctl(first, second, cmd, arg));
1834 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1835 break;
1836 case IPC_SET:
1837 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1838 ret = get_errno(semctl(first, second, cmd, arg));
1839 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1840 break;
1841 default:
1842 ret = get_errno(semctl(first, second, cmd, arg));
1845 return ret;
1848 struct target_msqid_ds
1850 struct target_ipc_perm msg_perm;
1851 abi_ulong msg_stime;
1852 #if TARGET_ABI_BITS == 32
1853 abi_ulong __unused1;
1854 #endif
1855 abi_ulong msg_rtime;
1856 #if TARGET_ABI_BITS == 32
1857 abi_ulong __unused2;
1858 #endif
1859 abi_ulong msg_ctime;
1860 #if TARGET_ABI_BITS == 32
1861 abi_ulong __unused3;
1862 #endif
1863 abi_ulong __msg_cbytes;
1864 abi_ulong msg_qnum;
1865 abi_ulong msg_qbytes;
1866 abi_ulong msg_lspid;
1867 abi_ulong msg_lrpid;
1868 abi_ulong __unused4;
1869 abi_ulong __unused5;
1872 static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
1873 abi_ulong target_addr)
1875 struct target_msqid_ds *target_md;
1877 if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
1878 return -TARGET_EFAULT;
1879 if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
1880 return -TARGET_EFAULT;
1881 host_md->msg_stime = tswapl(target_md->msg_stime);
1882 host_md->msg_rtime = tswapl(target_md->msg_rtime);
1883 host_md->msg_ctime = tswapl(target_md->msg_ctime);
1884 host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
1885 host_md->msg_qnum = tswapl(target_md->msg_qnum);
1886 host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
1887 host_md->msg_lspid = tswapl(target_md->msg_lspid);
1888 host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
1889 unlock_user_struct(target_md, target_addr, 0);
1890 return 0;
1893 static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
1894 struct msqid_ds *host_md)
1896 struct target_msqid_ds *target_md;
1898 if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
1899 return -TARGET_EFAULT;
1900 if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
1901 return -TARGET_EFAULT;
1902 target_md->msg_stime = tswapl(host_md->msg_stime);
1903 target_md->msg_rtime = tswapl(host_md->msg_rtime);
1904 target_md->msg_ctime = tswapl(host_md->msg_ctime);
1905 target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
1906 target_md->msg_qnum = tswapl(host_md->msg_qnum);
1907 target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
1908 target_md->msg_lspid = tswapl(host_md->msg_lspid);
1909 target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
1910 unlock_user_struct(target_md, target_addr, 1);
1911 return 0;
1914 struct target_msginfo {
1915 int msgpool;
1916 int msgmap;
1917 int msgmax;
1918 int msgmnb;
1919 int msgmni;
1920 int msgssz;
1921 int msgtql;
1922 unsigned short int msgseg;
1925 static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
1926 struct msginfo *host_msginfo)
1928 struct target_msginfo *target_msginfo;
1929 if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
1930 return -TARGET_EFAULT;
1931 __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
1932 __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
1933 __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
1934 __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
1935 __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
1936 __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
1937 __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
1938 __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
1939 unlock_user_struct(target_msginfo, target_addr, 1);
1940 return 0;
1943 static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
1945 struct msqid_ds dsarg;
1946 struct msginfo msginfo;
1947 abi_long ret = -TARGET_EINVAL;
1949 cmd &= 0xff;
1951 switch (cmd) {
1952 case IPC_STAT:
1953 case IPC_SET:
1954 case MSG_STAT:
1955 if (target_to_host_msqid_ds(&dsarg,ptr))
1956 return -TARGET_EFAULT;
1957 ret = get_errno(msgctl(msgid, cmd, &dsarg));
1958 if (host_to_target_msqid_ds(ptr,&dsarg))
1959 return -TARGET_EFAULT;
1960 break;
1961 case IPC_RMID:
1962 ret = get_errno(msgctl(msgid, cmd, NULL));
1963 break;
1964 case IPC_INFO:
1965 case MSG_INFO:
1966 ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
1967 if (host_to_target_msginfo(ptr, &msginfo))
1968 return -TARGET_EFAULT;
1969 break;
1972 return ret;
1975 struct target_msgbuf {
1976 abi_long mtype;
1977 char mtext[1];
1980 static inline abi_long do_msgsnd(int msqid, abi_long msgp,
1981 unsigned int msgsz, int msgflg)
1983 struct target_msgbuf *target_mb;
1984 struct msgbuf *host_mb;
1985 abi_long ret = 0;
1987 if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
1988 return -TARGET_EFAULT;
1989 host_mb = malloc(msgsz+sizeof(long));
1990 host_mb->mtype = (abi_long) tswapl(target_mb->mtype);
1991 memcpy(host_mb->mtext, target_mb->mtext, msgsz);
1992 ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
1993 free(host_mb);
1994 unlock_user_struct(target_mb, msgp, 0);
1996 return ret;
1999 static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2000 unsigned int msgsz, abi_long msgtyp,
2001 int msgflg)
2003 struct target_msgbuf *target_mb;
2004 char *target_mtext;
2005 struct msgbuf *host_mb;
2006 abi_long ret = 0;
2008 if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2009 return -TARGET_EFAULT;
2011 host_mb = malloc(msgsz+sizeof(long));
2012 ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapl(msgtyp), msgflg));
2014 if (ret > 0) {
2015 abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2016 target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2017 if (!target_mtext) {
2018 ret = -TARGET_EFAULT;
2019 goto end;
2021 memcpy(target_mb->mtext, host_mb->mtext, ret);
2022 unlock_user(target_mtext, target_mtext_addr, ret);
2025 target_mb->mtype = tswapl(host_mb->mtype);
2026 free(host_mb);
2028 end:
2029 if (target_mb)
2030 unlock_user_struct(target_mb, msgp, 1);
2031 return ret;
2034 #ifdef TARGET_NR_ipc
2035 /* ??? This only works with linear mappings. */
2036 /* do_ipc() must return target values and target errnos. */
2037 static abi_long do_ipc(unsigned int call, int first,
2038 int second, int third,
2039 abi_long ptr, abi_long fifth)
2041 int version;
2042 abi_long ret = 0;
2043 struct shmid_ds shm_info;
2044 int i;
2046 version = call >> 16;
2047 call &= 0xffff;
2049 switch (call) {
2050 case IPCOP_semop:
2051 ret = get_errno(semop(first,(struct sembuf *)g2h(ptr), second));
2052 break;
2054 case IPCOP_semget:
2055 ret = get_errno(semget(first, second, third));
2056 break;
2058 case IPCOP_semctl:
2059 ret = do_semctl(first, second, third, ptr);
2060 break;
2062 case IPCOP_semtimedop:
2063 gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2064 ret = -TARGET_ENOSYS;
2065 break;
2067 case IPCOP_msgget:
2068 ret = get_errno(msgget(first, second));
2069 break;
2071 case IPCOP_msgsnd:
2072 ret = do_msgsnd(first, ptr, second, third);
2073 break;
2075 case IPCOP_msgctl:
2076 ret = do_msgctl(first, second, ptr);
2077 break;
2079 case IPCOP_msgrcv:
2080 switch (version) {
2081 case 0:
2083 struct target_ipc_kludge {
2084 abi_long msgp;
2085 abi_long msgtyp;
2086 } *tmp;
2088 if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
2089 ret = -TARGET_EFAULT;
2090 break;
2093 ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
2095 unlock_user_struct(tmp, ptr, 0);
2096 break;
2098 default:
2099 ret = do_msgrcv(first, ptr, second, fifth, third);
2101 break;
2103 case IPCOP_shmat:
2105 abi_ulong raddr;
2106 void *host_addr;
2107 /* SHM_* flags are the same on all linux platforms */
2108 host_addr = shmat(first, (void *)g2h(ptr), second);
2109 if (host_addr == (void *)-1) {
2110 ret = get_errno((long)host_addr);
2111 break;
2113 raddr = h2g((unsigned long)host_addr);
2114 /* find out the length of the shared memory segment */
2116 ret = get_errno(shmctl(first, IPC_STAT, &shm_info));
2117 if (is_error(ret)) {
2118 /* can't get length, bail out */
2119 shmdt(host_addr);
2120 break;
2122 page_set_flags(raddr, raddr + shm_info.shm_segsz,
2123 PAGE_VALID | PAGE_READ |
2124 ((second & SHM_RDONLY)? 0: PAGE_WRITE));
2125 for (i = 0; i < N_SHM_REGIONS; ++i) {
2126 if (shm_regions[i].start == 0) {
2127 shm_regions[i].start = raddr;
2128 shm_regions[i].size = shm_info.shm_segsz;
2129 break;
2132 if (put_user_ual(raddr, third))
2133 return -TARGET_EFAULT;
2134 ret = 0;
2136 break;
2137 case IPCOP_shmdt:
2138 for (i = 0; i < N_SHM_REGIONS; ++i) {
2139 if (shm_regions[i].start == ptr) {
2140 shm_regions[i].start = 0;
2141 page_set_flags(ptr, shm_regions[i].size, 0);
2142 break;
2145 ret = get_errno(shmdt((void *)g2h(ptr)));
2146 break;
2148 case IPCOP_shmget:
2149 /* IPC_* flag values are the same on all linux platforms */
2150 ret = get_errno(shmget(first, second, third));
2151 break;
2153 /* IPC_* and SHM_* command values are the same on all linux platforms */
2154 case IPCOP_shmctl:
2155 switch(second) {
2156 case IPC_RMID:
2157 case SHM_LOCK:
2158 case SHM_UNLOCK:
2159 ret = get_errno(shmctl(first, second, NULL));
2160 break;
2161 default:
2162 goto unimplemented;
2164 break;
2165 default:
2166 unimplemented:
2167 gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2168 ret = -TARGET_ENOSYS;
2169 break;
2171 return ret;
2173 #endif
2175 /* kernel structure types definitions */
2176 #define IFNAMSIZ 16
2178 #define STRUCT(name, list...) STRUCT_ ## name,
2179 #define STRUCT_SPECIAL(name) STRUCT_ ## name,
2180 enum {
2181 #include "syscall_types.h"
2183 #undef STRUCT
2184 #undef STRUCT_SPECIAL
2186 #define STRUCT(name, list...) static const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };
2187 #define STRUCT_SPECIAL(name)
2188 #include "syscall_types.h"
2189 #undef STRUCT
2190 #undef STRUCT_SPECIAL
2192 typedef struct IOCTLEntry {
2193 unsigned int target_cmd;
2194 unsigned int host_cmd;
2195 const char *name;
2196 int access;
2197 const argtype arg_type[5];
2198 } IOCTLEntry;
2200 #define IOC_R 0x0001
2201 #define IOC_W 0x0002
2202 #define IOC_RW (IOC_R | IOC_W)
2204 #define MAX_STRUCT_SIZE 4096
2206 static IOCTLEntry ioctl_entries[] = {
2207 #define IOCTL(cmd, access, types...) \
2208 { TARGET_ ## cmd, cmd, #cmd, access, { types } },
2209 #include "ioctls.h"
2210 { 0, 0, },
2213 /* ??? Implement proper locking for ioctls. */
2214 /* do_ioctl() Must return target values and target errnos. */
2215 static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
2217 const IOCTLEntry *ie;
2218 const argtype *arg_type;
2219 abi_long ret;
2220 uint8_t buf_temp[MAX_STRUCT_SIZE];
2221 int target_size;
2222 void *argptr;
2224 ie = ioctl_entries;
2225 for(;;) {
2226 if (ie->target_cmd == 0) {
2227 gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
2228 return -TARGET_ENOSYS;
2230 if (ie->target_cmd == cmd)
2231 break;
2232 ie++;
2234 arg_type = ie->arg_type;
2235 #if defined(DEBUG)
2236 gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
2237 #endif
2238 switch(arg_type[0]) {
2239 case TYPE_NULL:
2240 /* no argument */
2241 ret = get_errno(ioctl(fd, ie->host_cmd));
2242 break;
2243 case TYPE_PTRVOID:
2244 case TYPE_INT:
2245 /* int argment */
2246 ret = get_errno(ioctl(fd, ie->host_cmd, arg));
2247 break;
2248 case TYPE_PTR:
2249 arg_type++;
2250 target_size = thunk_type_size(arg_type, 0);
2251 switch(ie->access) {
2252 case IOC_R:
2253 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2254 if (!is_error(ret)) {
2255 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2256 if (!argptr)
2257 return -TARGET_EFAULT;
2258 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2259 unlock_user(argptr, arg, target_size);
2261 break;
2262 case IOC_W:
2263 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2264 if (!argptr)
2265 return -TARGET_EFAULT;
2266 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2267 unlock_user(argptr, arg, 0);
2268 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2269 break;
2270 default:
2271 case IOC_RW:
2272 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2273 if (!argptr)
2274 return -TARGET_EFAULT;
2275 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2276 unlock_user(argptr, arg, 0);
2277 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2278 if (!is_error(ret)) {
2279 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2280 if (!argptr)
2281 return -TARGET_EFAULT;
2282 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2283 unlock_user(argptr, arg, target_size);
2285 break;
2287 break;
2288 default:
2289 gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
2290 (long)cmd, arg_type[0]);
2291 ret = -TARGET_ENOSYS;
2292 break;
2294 return ret;
2297 static const bitmask_transtbl iflag_tbl[] = {
2298 { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
2299 { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
2300 { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
2301 { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
2302 { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
2303 { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
2304 { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
2305 { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
2306 { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
2307 { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
2308 { TARGET_IXON, TARGET_IXON, IXON, IXON },
2309 { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
2310 { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
2311 { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
2312 { 0, 0, 0, 0 }
2315 static const bitmask_transtbl oflag_tbl[] = {
2316 { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
2317 { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
2318 { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
2319 { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
2320 { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
2321 { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
2322 { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
2323 { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
2324 { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
2325 { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
2326 { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
2327 { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
2328 { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
2329 { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
2330 { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
2331 { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
2332 { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
2333 { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
2334 { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
2335 { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
2336 { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
2337 { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
2338 { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
2339 { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
2340 { 0, 0, 0, 0 }
2343 static const bitmask_transtbl cflag_tbl[] = {
2344 { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
2345 { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
2346 { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
2347 { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
2348 { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
2349 { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
2350 { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
2351 { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
2352 { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
2353 { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
2354 { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
2355 { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
2356 { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
2357 { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
2358 { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
2359 { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
2360 { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
2361 { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
2362 { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
2363 { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
2364 { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
2365 { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
2366 { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
2367 { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
2368 { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
2369 { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
2370 { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
2371 { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
2372 { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
2373 { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
2374 { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
2375 { 0, 0, 0, 0 }
2378 static const bitmask_transtbl lflag_tbl[] = {
2379 { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
2380 { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
2381 { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
2382 { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
2383 { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
2384 { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
2385 { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
2386 { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
2387 { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
2388 { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
2389 { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
2390 { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
2391 { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
2392 { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
2393 { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
2394 { 0, 0, 0, 0 }
2397 static void target_to_host_termios (void *dst, const void *src)
2399 struct host_termios *host = dst;
2400 const struct target_termios *target = src;
2402 host->c_iflag =
2403 target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
2404 host->c_oflag =
2405 target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
2406 host->c_cflag =
2407 target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
2408 host->c_lflag =
2409 target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
2410 host->c_line = target->c_line;
2412 host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
2413 host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
2414 host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
2415 host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
2416 host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
2417 host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
2418 host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
2419 host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
2420 host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
2421 host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
2422 host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
2423 host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
2424 host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
2425 host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
2426 host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
2427 host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
2428 host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
2431 static void host_to_target_termios (void *dst, const void *src)
2433 struct target_termios *target = dst;
2434 const struct host_termios *host = src;
2436 target->c_iflag =
2437 tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
2438 target->c_oflag =
2439 tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
2440 target->c_cflag =
2441 tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
2442 target->c_lflag =
2443 tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
2444 target->c_line = host->c_line;
2446 target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
2447 target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
2448 target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
2449 target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
2450 target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
2451 target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
2452 target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
2453 target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
2454 target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
2455 target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
2456 target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
2457 target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
2458 target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
2459 target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
2460 target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
2461 target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
2462 target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
2465 static const StructEntry struct_termios_def = {
2466 .convert = { host_to_target_termios, target_to_host_termios },
2467 .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
2468 .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
2471 static bitmask_transtbl mmap_flags_tbl[] = {
2472 { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
2473 { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
2474 { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
2475 { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
2476 { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
2477 { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
2478 { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
2479 { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
2480 { 0, 0, 0, 0 }
2483 static bitmask_transtbl fcntl_flags_tbl[] = {
2484 { TARGET_O_ACCMODE, TARGET_O_WRONLY, O_ACCMODE, O_WRONLY, },
2485 { TARGET_O_ACCMODE, TARGET_O_RDWR, O_ACCMODE, O_RDWR, },
2486 { TARGET_O_CREAT, TARGET_O_CREAT, O_CREAT, O_CREAT, },
2487 { TARGET_O_EXCL, TARGET_O_EXCL, O_EXCL, O_EXCL, },
2488 { TARGET_O_NOCTTY, TARGET_O_NOCTTY, O_NOCTTY, O_NOCTTY, },
2489 { TARGET_O_TRUNC, TARGET_O_TRUNC, O_TRUNC, O_TRUNC, },
2490 { TARGET_O_APPEND, TARGET_O_APPEND, O_APPEND, O_APPEND, },
2491 { TARGET_O_NONBLOCK, TARGET_O_NONBLOCK, O_NONBLOCK, O_NONBLOCK, },
2492 { TARGET_O_SYNC, TARGET_O_SYNC, O_SYNC, O_SYNC, },
2493 { TARGET_FASYNC, TARGET_FASYNC, FASYNC, FASYNC, },
2494 { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
2495 { TARGET_O_NOFOLLOW, TARGET_O_NOFOLLOW, O_NOFOLLOW, O_NOFOLLOW, },
2496 { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
2497 #if defined(O_DIRECT)
2498 { TARGET_O_DIRECT, TARGET_O_DIRECT, O_DIRECT, O_DIRECT, },
2499 #endif
2500 { 0, 0, 0, 0 }
2503 #if defined(TARGET_I386)
2505 /* NOTE: there is really one LDT for all the threads */
2506 static uint8_t *ldt_table;
2508 static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
2510 int size;
2511 void *p;
2513 if (!ldt_table)
2514 return 0;
2515 size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
2516 if (size > bytecount)
2517 size = bytecount;
2518 p = lock_user(VERIFY_WRITE, ptr, size, 0);
2519 if (!p)
2520 return -TARGET_EFAULT;
2521 /* ??? Should this by byteswapped? */
2522 memcpy(p, ldt_table, size);
2523 unlock_user(p, ptr, size);
2524 return size;
2527 /* XXX: add locking support */
2528 static abi_long write_ldt(CPUX86State *env,
2529 abi_ulong ptr, unsigned long bytecount, int oldmode)
2531 struct target_modify_ldt_ldt_s ldt_info;
2532 struct target_modify_ldt_ldt_s *target_ldt_info;
2533 int seg_32bit, contents, read_exec_only, limit_in_pages;
2534 int seg_not_present, useable, lm;
2535 uint32_t *lp, entry_1, entry_2;
2537 if (bytecount != sizeof(ldt_info))
2538 return -TARGET_EINVAL;
2539 if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
2540 return -TARGET_EFAULT;
2541 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2542 ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2543 ldt_info.limit = tswap32(target_ldt_info->limit);
2544 ldt_info.flags = tswap32(target_ldt_info->flags);
2545 unlock_user_struct(target_ldt_info, ptr, 0);
2547 if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
2548 return -TARGET_EINVAL;
2549 seg_32bit = ldt_info.flags & 1;
2550 contents = (ldt_info.flags >> 1) & 3;
2551 read_exec_only = (ldt_info.flags >> 3) & 1;
2552 limit_in_pages = (ldt_info.flags >> 4) & 1;
2553 seg_not_present = (ldt_info.flags >> 5) & 1;
2554 useable = (ldt_info.flags >> 6) & 1;
2555 #ifdef TARGET_ABI32
2556 lm = 0;
2557 #else
2558 lm = (ldt_info.flags >> 7) & 1;
2559 #endif
2560 if (contents == 3) {
2561 if (oldmode)
2562 return -TARGET_EINVAL;
2563 if (seg_not_present == 0)
2564 return -TARGET_EINVAL;
2566 /* allocate the LDT */
2567 if (!ldt_table) {
2568 env->ldt.base = target_mmap(0,
2569 TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
2570 PROT_READ|PROT_WRITE,
2571 MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
2572 if (env->ldt.base == -1)
2573 return -TARGET_ENOMEM;
2574 memset(g2h(env->ldt.base), 0,
2575 TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
2576 env->ldt.limit = 0xffff;
2577 ldt_table = g2h(env->ldt.base);
2580 /* NOTE: same code as Linux kernel */
2581 /* Allow LDTs to be cleared by the user. */
2582 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2583 if (oldmode ||
2584 (contents == 0 &&
2585 read_exec_only == 1 &&
2586 seg_32bit == 0 &&
2587 limit_in_pages == 0 &&
2588 seg_not_present == 1 &&
2589 useable == 0 )) {
2590 entry_1 = 0;
2591 entry_2 = 0;
2592 goto install;
2596 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2597 (ldt_info.limit & 0x0ffff);
2598 entry_2 = (ldt_info.base_addr & 0xff000000) |
2599 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2600 (ldt_info.limit & 0xf0000) |
2601 ((read_exec_only ^ 1) << 9) |
2602 (contents << 10) |
2603 ((seg_not_present ^ 1) << 15) |
2604 (seg_32bit << 22) |
2605 (limit_in_pages << 23) |
2606 (lm << 21) |
2607 0x7000;
2608 if (!oldmode)
2609 entry_2 |= (useable << 20);
2611 /* Install the new entry ... */
2612 install:
2613 lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
2614 lp[0] = tswap32(entry_1);
2615 lp[1] = tswap32(entry_2);
2616 return 0;
2619 /* specific and weird i386 syscalls */
2620 static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
2621 unsigned long bytecount)
2623 abi_long ret;
2625 switch (func) {
2626 case 0:
2627 ret = read_ldt(ptr, bytecount);
2628 break;
2629 case 1:
2630 ret = write_ldt(env, ptr, bytecount, 1);
2631 break;
2632 case 0x11:
2633 ret = write_ldt(env, ptr, bytecount, 0);
2634 break;
2635 default:
2636 ret = -TARGET_ENOSYS;
2637 break;
2639 return ret;
2642 #if defined(TARGET_I386) && defined(TARGET_ABI32)
2643 static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
2645 uint64_t *gdt_table = g2h(env->gdt.base);
2646 struct target_modify_ldt_ldt_s ldt_info;
2647 struct target_modify_ldt_ldt_s *target_ldt_info;
2648 int seg_32bit, contents, read_exec_only, limit_in_pages;
2649 int seg_not_present, useable, lm;
2650 uint32_t *lp, entry_1, entry_2;
2651 int i;
2653 lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
2654 if (!target_ldt_info)
2655 return -TARGET_EFAULT;
2656 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2657 ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2658 ldt_info.limit = tswap32(target_ldt_info->limit);
2659 ldt_info.flags = tswap32(target_ldt_info->flags);
2660 if (ldt_info.entry_number == -1) {
2661 for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
2662 if (gdt_table[i] == 0) {
2663 ldt_info.entry_number = i;
2664 target_ldt_info->entry_number = tswap32(i);
2665 break;
2669 unlock_user_struct(target_ldt_info, ptr, 1);
2671 if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN ||
2672 ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
2673 return -TARGET_EINVAL;
2674 seg_32bit = ldt_info.flags & 1;
2675 contents = (ldt_info.flags >> 1) & 3;
2676 read_exec_only = (ldt_info.flags >> 3) & 1;
2677 limit_in_pages = (ldt_info.flags >> 4) & 1;
2678 seg_not_present = (ldt_info.flags >> 5) & 1;
2679 useable = (ldt_info.flags >> 6) & 1;
2680 #ifdef TARGET_ABI32
2681 lm = 0;
2682 #else
2683 lm = (ldt_info.flags >> 7) & 1;
2684 #endif
2686 if (contents == 3) {
2687 if (seg_not_present == 0)
2688 return -TARGET_EINVAL;
2691 /* NOTE: same code as Linux kernel */
2692 /* Allow LDTs to be cleared by the user. */
2693 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2694 if ((contents == 0 &&
2695 read_exec_only == 1 &&
2696 seg_32bit == 0 &&
2697 limit_in_pages == 0 &&
2698 seg_not_present == 1 &&
2699 useable == 0 )) {
2700 entry_1 = 0;
2701 entry_2 = 0;
2702 goto install;
2706 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2707 (ldt_info.limit & 0x0ffff);
2708 entry_2 = (ldt_info.base_addr & 0xff000000) |
2709 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2710 (ldt_info.limit & 0xf0000) |
2711 ((read_exec_only ^ 1) << 9) |
2712 (contents << 10) |
2713 ((seg_not_present ^ 1) << 15) |
2714 (seg_32bit << 22) |
2715 (limit_in_pages << 23) |
2716 (useable << 20) |
2717 (lm << 21) |
2718 0x7000;
2720 /* Install the new entry ... */
2721 install:
2722 lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
2723 lp[0] = tswap32(entry_1);
2724 lp[1] = tswap32(entry_2);
2725 return 0;
2728 static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
2730 struct target_modify_ldt_ldt_s *target_ldt_info;
2731 uint64_t *gdt_table = g2h(env->gdt.base);
2732 uint32_t base_addr, limit, flags;
2733 int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
2734 int seg_not_present, useable, lm;
2735 uint32_t *lp, entry_1, entry_2;
2737 lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
2738 if (!target_ldt_info)
2739 return -TARGET_EFAULT;
2740 idx = tswap32(target_ldt_info->entry_number);
2741 if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
2742 idx > TARGET_GDT_ENTRY_TLS_MAX) {
2743 unlock_user_struct(target_ldt_info, ptr, 1);
2744 return -TARGET_EINVAL;
2746 lp = (uint32_t *)(gdt_table + idx);
2747 entry_1 = tswap32(lp[0]);
2748 entry_2 = tswap32(lp[1]);
2750 read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
2751 contents = (entry_2 >> 10) & 3;
2752 seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
2753 seg_32bit = (entry_2 >> 22) & 1;
2754 limit_in_pages = (entry_2 >> 23) & 1;
2755 useable = (entry_2 >> 20) & 1;
2756 #ifdef TARGET_ABI32
2757 lm = 0;
2758 #else
2759 lm = (entry_2 >> 21) & 1;
2760 #endif
2761 flags = (seg_32bit << 0) | (contents << 1) |
2762 (read_exec_only << 3) | (limit_in_pages << 4) |
2763 (seg_not_present << 5) | (useable << 6) | (lm << 7);
2764 limit = (entry_1 & 0xffff) | (entry_2 & 0xf0000);
2765 base_addr = (entry_1 >> 16) |
2766 (entry_2 & 0xff000000) |
2767 ((entry_2 & 0xff) << 16);
2768 target_ldt_info->base_addr = tswapl(base_addr);
2769 target_ldt_info->limit = tswap32(limit);
2770 target_ldt_info->flags = tswap32(flags);
2771 unlock_user_struct(target_ldt_info, ptr, 1);
2772 return 0;
2774 #endif /* TARGET_I386 && TARGET_ABI32 */
2776 #ifndef TARGET_ABI32
2777 static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
2779 abi_long ret;
2780 abi_ulong val;
2781 int idx;
2783 switch(code) {
2784 case TARGET_ARCH_SET_GS:
2785 case TARGET_ARCH_SET_FS:
2786 if (code == TARGET_ARCH_SET_GS)
2787 idx = R_GS;
2788 else
2789 idx = R_FS;
2790 cpu_x86_load_seg(env, idx, 0);
2791 env->segs[idx].base = addr;
2792 break;
2793 case TARGET_ARCH_GET_GS:
2794 case TARGET_ARCH_GET_FS:
2795 if (code == TARGET_ARCH_GET_GS)
2796 idx = R_GS;
2797 else
2798 idx = R_FS;
2799 val = env->segs[idx].base;
2800 if (put_user(val, addr, abi_ulong))
2801 return -TARGET_EFAULT;
2802 break;
2803 default:
2804 ret = -TARGET_EINVAL;
2805 break;
2807 return 0;
2809 #endif
2811 #endif /* defined(TARGET_I386) */
2813 #if defined(USE_NPTL)
2815 #define NEW_STACK_SIZE PTHREAD_STACK_MIN
2817 static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
2818 typedef struct {
2819 CPUState *env;
2820 pthread_mutex_t mutex;
2821 pthread_cond_t cond;
2822 pthread_t thread;
2823 uint32_t tid;
2824 abi_ulong child_tidptr;
2825 abi_ulong parent_tidptr;
2826 sigset_t sigmask;
2827 } new_thread_info;
2829 static void *clone_func(void *arg)
2831 new_thread_info *info = arg;
2832 CPUState *env;
2834 env = info->env;
2835 thread_env = env;
2836 info->tid = gettid();
2837 if (info->child_tidptr)
2838 put_user_u32(info->tid, info->child_tidptr);
2839 if (info->parent_tidptr)
2840 put_user_u32(info->tid, info->parent_tidptr);
2841 /* Enable signals. */
2842 sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
2843 /* Signal to the parent that we're ready. */
2844 pthread_mutex_lock(&info->mutex);
2845 pthread_cond_broadcast(&info->cond);
2846 pthread_mutex_unlock(&info->mutex);
2847 /* Wait until the parent has finshed initializing the tls state. */
2848 pthread_mutex_lock(&clone_lock);
2849 pthread_mutex_unlock(&clone_lock);
2850 cpu_loop(env);
2851 /* never exits */
2852 return NULL;
2854 #else
2855 /* this stack is the equivalent of the kernel stack associated with a
2856 thread/process */
2857 #define NEW_STACK_SIZE 8192
2859 static int clone_func(void *arg)
2861 CPUState *env = arg;
2862 cpu_loop(env);
2863 /* never exits */
2864 return 0;
2866 #endif
2868 /* do_fork() Must return host values and target errnos (unlike most
2869 do_*() functions). */
2870 static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
2871 abi_ulong parent_tidptr, target_ulong newtls,
2872 abi_ulong child_tidptr)
2874 int ret;
2875 TaskState *ts;
2876 uint8_t *new_stack;
2877 CPUState *new_env;
2878 #if defined(USE_NPTL)
2879 unsigned int nptl_flags;
2880 sigset_t sigmask;
2881 #endif
2883 /* Emulate vfork() with fork() */
2884 if (flags & CLONE_VFORK)
2885 flags &= ~(CLONE_VFORK | CLONE_VM);
2887 if (flags & CLONE_VM) {
2888 #if defined(USE_NPTL)
2889 new_thread_info info;
2890 pthread_attr_t attr;
2891 #endif
2892 ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
2893 init_task_state(ts);
2894 new_stack = ts->stack;
2895 /* we create a new CPU instance. */
2896 new_env = cpu_copy(env);
2897 /* Init regs that differ from the parent. */
2898 cpu_clone_regs(new_env, newsp);
2899 new_env->opaque = ts;
2900 #if defined(USE_NPTL)
2901 nptl_flags = flags;
2902 flags &= ~CLONE_NPTL_FLAGS2;
2904 /* TODO: Implement CLONE_CHILD_CLEARTID. */
2905 if (nptl_flags & CLONE_SETTLS)
2906 cpu_set_tls (new_env, newtls);
2908 /* Grab a mutex so that thread setup appears atomic. */
2909 pthread_mutex_lock(&clone_lock);
2911 memset(&info, 0, sizeof(info));
2912 pthread_mutex_init(&info.mutex, NULL);
2913 pthread_mutex_lock(&info.mutex);
2914 pthread_cond_init(&info.cond, NULL);
2915 info.env = new_env;
2916 if (nptl_flags & CLONE_CHILD_SETTID)
2917 info.child_tidptr = child_tidptr;
2918 if (nptl_flags & CLONE_PARENT_SETTID)
2919 info.parent_tidptr = parent_tidptr;
2921 ret = pthread_attr_init(&attr);
2922 ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE);
2923 /* It is not safe to deliver signals until the child has finished
2924 initializing, so temporarily block all signals. */
2925 sigfillset(&sigmask);
2926 sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
2928 ret = pthread_create(&info.thread, &attr, clone_func, &info);
2930 sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
2931 pthread_attr_destroy(&attr);
2932 if (ret == 0) {
2933 /* Wait for the child to initialize. */
2934 pthread_cond_wait(&info.cond, &info.mutex);
2935 ret = info.tid;
2936 if (flags & CLONE_PARENT_SETTID)
2937 put_user_u32(ret, parent_tidptr);
2938 } else {
2939 ret = -1;
2941 pthread_mutex_unlock(&info.mutex);
2942 pthread_cond_destroy(&info.cond);
2943 pthread_mutex_destroy(&info.mutex);
2944 pthread_mutex_unlock(&clone_lock);
2945 #else
2946 if (flags & CLONE_NPTL_FLAGS2)
2947 return -EINVAL;
2948 /* This is probably going to die very quickly, but do it anyway. */
2949 #ifdef __ia64__
2950 ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
2951 #else
2952 ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
2953 #endif
2954 #endif
2955 } else {
2956 /* if no CLONE_VM, we consider it is a fork */
2957 if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
2958 return -EINVAL;
2959 fork_start();
2960 ret = fork();
2961 #if defined(USE_NPTL)
2962 /* There is a race condition here. The parent process could
2963 theoretically read the TID in the child process before the child
2964 tid is set. This would require using either ptrace
2965 (not implemented) or having *_tidptr to point at a shared memory
2966 mapping. We can't repeat the spinlock hack used above because
2967 the child process gets its own copy of the lock. */
2968 if (ret == 0) {
2969 cpu_clone_regs(env, newsp);
2970 fork_end(1);
2971 /* Child Process. */
2972 if (flags & CLONE_CHILD_SETTID)
2973 put_user_u32(gettid(), child_tidptr);
2974 if (flags & CLONE_PARENT_SETTID)
2975 put_user_u32(gettid(), parent_tidptr);
2976 ts = (TaskState *)env->opaque;
2977 if (flags & CLONE_SETTLS)
2978 cpu_set_tls (env, newtls);
2979 /* TODO: Implement CLONE_CHILD_CLEARTID. */
2980 } else {
2981 fork_end(0);
2983 #else
2984 if (ret == 0) {
2985 cpu_clone_regs(env, newsp);
2987 #endif
2989 return ret;
2992 static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
2994 struct flock fl;
2995 struct target_flock *target_fl;
2996 struct flock64 fl64;
2997 struct target_flock64 *target_fl64;
2998 abi_long ret;
3000 switch(cmd) {
3001 case TARGET_F_GETLK:
3002 if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3003 return -TARGET_EFAULT;
3004 fl.l_type = tswap16(target_fl->l_type);
3005 fl.l_whence = tswap16(target_fl->l_whence);
3006 fl.l_start = tswapl(target_fl->l_start);
3007 fl.l_len = tswapl(target_fl->l_len);
3008 fl.l_pid = tswapl(target_fl->l_pid);
3009 unlock_user_struct(target_fl, arg, 0);
3010 ret = get_errno(fcntl(fd, cmd, &fl));
3011 if (ret == 0) {
3012 if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
3013 return -TARGET_EFAULT;
3014 target_fl->l_type = tswap16(fl.l_type);
3015 target_fl->l_whence = tswap16(fl.l_whence);
3016 target_fl->l_start = tswapl(fl.l_start);
3017 target_fl->l_len = tswapl(fl.l_len);
3018 target_fl->l_pid = tswapl(fl.l_pid);
3019 unlock_user_struct(target_fl, arg, 1);
3021 break;
3023 case TARGET_F_SETLK:
3024 case TARGET_F_SETLKW:
3025 if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3026 return -TARGET_EFAULT;
3027 fl.l_type = tswap16(target_fl->l_type);
3028 fl.l_whence = tswap16(target_fl->l_whence);
3029 fl.l_start = tswapl(target_fl->l_start);
3030 fl.l_len = tswapl(target_fl->l_len);
3031 fl.l_pid = tswapl(target_fl->l_pid);
3032 unlock_user_struct(target_fl, arg, 0);
3033 ret = get_errno(fcntl(fd, cmd, &fl));
3034 break;
3036 case TARGET_F_GETLK64:
3037 if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3038 return -TARGET_EFAULT;
3039 fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3040 fl64.l_whence = tswap16(target_fl64->l_whence);
3041 fl64.l_start = tswapl(target_fl64->l_start);
3042 fl64.l_len = tswapl(target_fl64->l_len);
3043 fl64.l_pid = tswap16(target_fl64->l_pid);
3044 unlock_user_struct(target_fl64, arg, 0);
3045 ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
3046 if (ret == 0) {
3047 if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
3048 return -TARGET_EFAULT;
3049 target_fl64->l_type = tswap16(fl64.l_type) >> 1;
3050 target_fl64->l_whence = tswap16(fl64.l_whence);
3051 target_fl64->l_start = tswapl(fl64.l_start);
3052 target_fl64->l_len = tswapl(fl64.l_len);
3053 target_fl64->l_pid = tswapl(fl64.l_pid);
3054 unlock_user_struct(target_fl64, arg, 1);
3056 break;
3057 case TARGET_F_SETLK64:
3058 case TARGET_F_SETLKW64:
3059 if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3060 return -TARGET_EFAULT;
3061 fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3062 fl64.l_whence = tswap16(target_fl64->l_whence);
3063 fl64.l_start = tswapl(target_fl64->l_start);
3064 fl64.l_len = tswapl(target_fl64->l_len);
3065 fl64.l_pid = tswap16(target_fl64->l_pid);
3066 unlock_user_struct(target_fl64, arg, 0);
3067 ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
3068 break;
3070 case F_GETFL:
3071 ret = get_errno(fcntl(fd, cmd, arg));
3072 if (ret >= 0) {
3073 ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
3075 break;
3077 case F_SETFL:
3078 ret = get_errno(fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
3079 break;
3081 default:
3082 ret = get_errno(fcntl(fd, cmd, arg));
3083 break;
3085 return ret;
3088 #ifdef USE_UID16
3090 static inline int high2lowuid(int uid)
3092 if (uid > 65535)
3093 return 65534;
3094 else
3095 return uid;
3098 static inline int high2lowgid(int gid)
3100 if (gid > 65535)
3101 return 65534;
3102 else
3103 return gid;
3106 static inline int low2highuid(int uid)
3108 if ((int16_t)uid == -1)
3109 return -1;
3110 else
3111 return uid;
3114 static inline int low2highgid(int gid)
3116 if ((int16_t)gid == -1)
3117 return -1;
3118 else
3119 return gid;
3122 #endif /* USE_UID16 */
3124 void syscall_init(void)
3126 IOCTLEntry *ie;
3127 const argtype *arg_type;
3128 int size;
3129 int i;
3131 #define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3132 #define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3133 #include "syscall_types.h"
3134 #undef STRUCT
3135 #undef STRUCT_SPECIAL
3137 /* we patch the ioctl size if necessary. We rely on the fact that
3138 no ioctl has all the bits at '1' in the size field */
3139 ie = ioctl_entries;
3140 while (ie->target_cmd != 0) {
3141 if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
3142 TARGET_IOC_SIZEMASK) {
3143 arg_type = ie->arg_type;
3144 if (arg_type[0] != TYPE_PTR) {
3145 fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
3146 ie->target_cmd);
3147 exit(1);
3149 arg_type++;
3150 size = thunk_type_size(arg_type, 0);
3151 ie->target_cmd = (ie->target_cmd &
3152 ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
3153 (size << TARGET_IOC_SIZESHIFT);
3156 /* Build target_to_host_errno_table[] table from
3157 * host_to_target_errno_table[]. */
3158 for (i=0; i < ERRNO_TABLE_SIZE; i++)
3159 target_to_host_errno_table[host_to_target_errno_table[i]] = i;
3161 /* automatic consistency check if same arch */
3162 #if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
3163 (defined(__x86_64__) && defined(TARGET_X86_64))
3164 if (unlikely(ie->target_cmd != ie->host_cmd)) {
3165 fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
3166 ie->name, ie->target_cmd, ie->host_cmd);
3168 #endif
3169 ie++;
3173 #if TARGET_ABI_BITS == 32
3174 static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
3176 #ifdef TARGET_WORDS_BIGENDIAN
3177 return ((uint64_t)word0 << 32) | word1;
3178 #else
3179 return ((uint64_t)word1 << 32) | word0;
3180 #endif
3182 #else /* TARGET_ABI_BITS == 32 */
3183 static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
3185 return word0;
3187 #endif /* TARGET_ABI_BITS != 32 */
3189 #ifdef TARGET_NR_truncate64
3190 static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
3191 abi_long arg2,
3192 abi_long arg3,
3193 abi_long arg4)
3195 #ifdef TARGET_ARM
3196 if (((CPUARMState *)cpu_env)->eabi)
3198 arg2 = arg3;
3199 arg3 = arg4;
3201 #endif
3202 return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
3204 #endif
3206 #ifdef TARGET_NR_ftruncate64
3207 static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
3208 abi_long arg2,
3209 abi_long arg3,
3210 abi_long arg4)
3212 #ifdef TARGET_ARM
3213 if (((CPUARMState *)cpu_env)->eabi)
3215 arg2 = arg3;
3216 arg3 = arg4;
3218 #endif
3219 return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
3221 #endif
3223 static inline abi_long target_to_host_timespec(struct timespec *host_ts,
3224 abi_ulong target_addr)
3226 struct target_timespec *target_ts;
3228 if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
3229 return -TARGET_EFAULT;
3230 host_ts->tv_sec = tswapl(target_ts->tv_sec);
3231 host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
3232 unlock_user_struct(target_ts, target_addr, 0);
3233 return 0;
3236 static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3237 struct timespec *host_ts)
3239 struct target_timespec *target_ts;
3241 if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
3242 return -TARGET_EFAULT;
3243 target_ts->tv_sec = tswapl(host_ts->tv_sec);
3244 target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
3245 unlock_user_struct(target_ts, target_addr, 1);
3246 return 0;
3249 #ifdef TARGET_NR_stat64
3250 static inline abi_long host_to_target_stat64(void *cpu_env,
3251 abi_ulong target_addr,
3252 struct stat *host_st)
3254 #ifdef TARGET_ARM
3255 if (((CPUARMState *)cpu_env)->eabi) {
3256 struct target_eabi_stat64 *target_st;
3258 if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3259 return -TARGET_EFAULT;
3260 memset(target_st, 0, sizeof(struct target_eabi_stat64));
3261 __put_user(host_st->st_dev, &target_st->st_dev);
3262 __put_user(host_st->st_ino, &target_st->st_ino);
3263 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3264 __put_user(host_st->st_ino, &target_st->__st_ino);
3265 #endif
3266 __put_user(host_st->st_mode, &target_st->st_mode);
3267 __put_user(host_st->st_nlink, &target_st->st_nlink);
3268 __put_user(host_st->st_uid, &target_st->st_uid);
3269 __put_user(host_st->st_gid, &target_st->st_gid);
3270 __put_user(host_st->st_rdev, &target_st->st_rdev);
3271 __put_user(host_st->st_size, &target_st->st_size);
3272 __put_user(host_st->st_blksize, &target_st->st_blksize);
3273 __put_user(host_st->st_blocks, &target_st->st_blocks);
3274 __put_user(host_st->st_atime, &target_st->target_st_atime);
3275 __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3276 __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3277 unlock_user_struct(target_st, target_addr, 1);
3278 } else
3279 #endif
3281 struct target_stat64 *target_st;
3283 if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3284 return -TARGET_EFAULT;
3285 memset(target_st, 0, sizeof(struct target_stat64));
3286 __put_user(host_st->st_dev, &target_st->st_dev);
3287 __put_user(host_st->st_ino, &target_st->st_ino);
3288 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3289 __put_user(host_st->st_ino, &target_st->__st_ino);
3290 #endif
3291 __put_user(host_st->st_mode, &target_st->st_mode);
3292 __put_user(host_st->st_nlink, &target_st->st_nlink);
3293 __put_user(host_st->st_uid, &target_st->st_uid);
3294 __put_user(host_st->st_gid, &target_st->st_gid);
3295 __put_user(host_st->st_rdev, &target_st->st_rdev);
3296 /* XXX: better use of kernel struct */
3297 __put_user(host_st->st_size, &target_st->st_size);
3298 __put_user(host_st->st_blksize, &target_st->st_blksize);
3299 __put_user(host_st->st_blocks, &target_st->st_blocks);
3300 __put_user(host_st->st_atime, &target_st->target_st_atime);
3301 __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3302 __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3303 unlock_user_struct(target_st, target_addr, 1);
3306 return 0;
3308 #endif
3310 #if defined(USE_NPTL)
3311 /* ??? Using host futex calls even when target atomic operations
3312 are not really atomic probably breaks things. However implementing
3313 futexes locally would make futexes shared between multiple processes
3314 tricky. However they're probably useless because guest atomic
3315 operations won't work either. */
3316 static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
3317 target_ulong uaddr2, int val3)
3319 struct timespec ts, *pts;
3321 /* ??? We assume FUTEX_* constants are the same on both host
3322 and target. */
3323 switch (op) {
3324 case FUTEX_WAIT:
3325 if (timeout) {
3326 pts = &ts;
3327 target_to_host_timespec(pts, timeout);
3328 } else {
3329 pts = NULL;
3331 return get_errno(sys_futex(g2h(uaddr), FUTEX_WAIT, tswap32(val),
3332 pts, NULL, 0));
3333 case FUTEX_WAKE:
3334 return get_errno(sys_futex(g2h(uaddr), FUTEX_WAKE, val, NULL, NULL, 0));
3335 case FUTEX_FD:
3336 return get_errno(sys_futex(g2h(uaddr), FUTEX_FD, val, NULL, NULL, 0));
3337 case FUTEX_REQUEUE:
3338 return get_errno(sys_futex(g2h(uaddr), FUTEX_REQUEUE, val,
3339 NULL, g2h(uaddr2), 0));
3340 case FUTEX_CMP_REQUEUE:
3341 return get_errno(sys_futex(g2h(uaddr), FUTEX_CMP_REQUEUE, val,
3342 NULL, g2h(uaddr2), tswap32(val3)));
3343 default:
3344 return -TARGET_ENOSYS;
3347 #endif
3349 int get_osversion(void)
3351 static int osversion;
3352 struct new_utsname buf;
3353 const char *s;
3354 int i, n, tmp;
3355 if (osversion)
3356 return osversion;
3357 if (qemu_uname_release && *qemu_uname_release) {
3358 s = qemu_uname_release;
3359 } else {
3360 if (sys_uname(&buf))
3361 return 0;
3362 s = buf.release;
3364 tmp = 0;
3365 for (i = 0; i < 3; i++) {
3366 n = 0;
3367 while (*s >= '0' && *s <= '9') {
3368 n *= 10;
3369 n += *s - '0';
3370 s++;
3372 tmp = (tmp << 8) + n;
3373 if (*s == '.')
3374 s++;
3376 osversion = tmp;
3377 return osversion;
3380 /* do_syscall() should always have a single exit point at the end so
3381 that actions, such as logging of syscall results, can be performed.
3382 All errnos that do_syscall() returns must be -TARGET_<errcode>. */
3383 abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3384 abi_long arg2, abi_long arg3, abi_long arg4,
3385 abi_long arg5, abi_long arg6)
3387 abi_long ret;
3388 struct stat st;
3389 struct statfs stfs;
3390 void *p;
3392 #ifdef DEBUG
3393 gemu_log("syscall %d", num);
3394 #endif
3395 if(do_strace)
3396 print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
3398 switch(num) {
3399 case TARGET_NR_exit:
3400 #ifdef HAVE_GPROF
3401 _mcleanup();
3402 #endif
3403 gdb_exit(cpu_env, arg1);
3404 /* XXX: should free thread stack and CPU env */
3405 sys_exit(arg1);
3406 ret = 0; /* avoid warning */
3407 break;
3408 case TARGET_NR_read:
3409 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
3410 goto efault;
3411 ret = get_errno(read(arg1, p, arg3));
3412 unlock_user(p, arg2, ret);
3413 break;
3414 case TARGET_NR_write:
3415 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
3416 goto efault;
3417 ret = get_errno(write(arg1, p, arg3));
3418 unlock_user(p, arg2, 0);
3419 break;
3420 case TARGET_NR_open:
3421 if (!(p = lock_user_string(arg1)))
3422 goto efault;
3423 ret = get_errno(open(path(p),
3424 target_to_host_bitmask(arg2, fcntl_flags_tbl),
3425 arg3));
3426 unlock_user(p, arg1, 0);
3427 break;
3428 #if defined(TARGET_NR_openat) && defined(__NR_openat)
3429 case TARGET_NR_openat:
3430 if (!(p = lock_user_string(arg2)))
3431 goto efault;
3432 ret = get_errno(sys_openat(arg1,
3433 path(p),
3434 target_to_host_bitmask(arg3, fcntl_flags_tbl),
3435 arg4));
3436 unlock_user(p, arg2, 0);
3437 break;
3438 #endif
3439 case TARGET_NR_close:
3440 ret = get_errno(close(arg1));
3441 break;
3442 case TARGET_NR_brk:
3443 ret = do_brk(arg1);
3444 break;
3445 case TARGET_NR_fork:
3446 ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
3447 break;
3448 #ifdef TARGET_NR_waitpid
3449 case TARGET_NR_waitpid:
3451 int status;
3452 ret = get_errno(waitpid(arg1, &status, arg3));
3453 if (!is_error(ret) && arg2
3454 && put_user_s32(status, arg2))
3455 goto efault;
3457 break;
3458 #endif
3459 #ifdef TARGET_NR_waitid
3460 case TARGET_NR_waitid:
3462 siginfo_t info;
3463 info.si_pid = 0;
3464 ret = get_errno(waitid(arg1, arg2, &info, arg4));
3465 if (!is_error(ret) && arg3 && info.si_pid != 0) {
3466 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
3467 goto efault;
3468 host_to_target_siginfo(p, &info);
3469 unlock_user(p, arg3, sizeof(target_siginfo_t));
3472 break;
3473 #endif
3474 #ifdef TARGET_NR_creat /* not on alpha */
3475 case TARGET_NR_creat:
3476 if (!(p = lock_user_string(arg1)))
3477 goto efault;
3478 ret = get_errno(creat(p, arg2));
3479 unlock_user(p, arg1, 0);
3480 break;
3481 #endif
3482 case TARGET_NR_link:
3484 void * p2;
3485 p = lock_user_string(arg1);
3486 p2 = lock_user_string(arg2);
3487 if (!p || !p2)
3488 ret = -TARGET_EFAULT;
3489 else
3490 ret = get_errno(link(p, p2));
3491 unlock_user(p2, arg2, 0);
3492 unlock_user(p, arg1, 0);
3494 break;
3495 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
3496 case TARGET_NR_linkat:
3498 void * p2 = NULL;
3499 if (!arg2 || !arg4)
3500 goto efault;
3501 p = lock_user_string(arg2);
3502 p2 = lock_user_string(arg4);
3503 if (!p || !p2)
3504 ret = -TARGET_EFAULT;
3505 else
3506 ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
3507 unlock_user(p, arg2, 0);
3508 unlock_user(p2, arg4, 0);
3510 break;
3511 #endif
3512 case TARGET_NR_unlink:
3513 if (!(p = lock_user_string(arg1)))
3514 goto efault;
3515 ret = get_errno(unlink(p));
3516 unlock_user(p, arg1, 0);
3517 break;
3518 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
3519 case TARGET_NR_unlinkat:
3520 if (!(p = lock_user_string(arg2)))
3521 goto efault;
3522 ret = get_errno(sys_unlinkat(arg1, p, arg3));
3523 unlock_user(p, arg2, 0);
3524 break;
3525 #endif
3526 case TARGET_NR_execve:
3528 char **argp, **envp;
3529 int argc, envc;
3530 abi_ulong gp;
3531 abi_ulong guest_argp;
3532 abi_ulong guest_envp;
3533 abi_ulong addr;
3534 char **q;
3536 argc = 0;
3537 guest_argp = arg2;
3538 for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
3539 if (get_user_ual(addr, gp))
3540 goto efault;
3541 if (!addr)
3542 break;
3543 argc++;
3545 envc = 0;
3546 guest_envp = arg3;
3547 for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
3548 if (get_user_ual(addr, gp))
3549 goto efault;
3550 if (!addr)
3551 break;
3552 envc++;
3555 argp = alloca((argc + 1) * sizeof(void *));
3556 envp = alloca((envc + 1) * sizeof(void *));
3558 for (gp = guest_argp, q = argp; gp;
3559 gp += sizeof(abi_ulong), q++) {
3560 if (get_user_ual(addr, gp))
3561 goto execve_efault;
3562 if (!addr)
3563 break;
3564 if (!(*q = lock_user_string(addr)))
3565 goto execve_efault;
3567 *q = NULL;
3569 for (gp = guest_envp, q = envp; gp;
3570 gp += sizeof(abi_ulong), q++) {
3571 if (get_user_ual(addr, gp))
3572 goto execve_efault;
3573 if (!addr)
3574 break;
3575 if (!(*q = lock_user_string(addr)))
3576 goto execve_efault;
3578 *q = NULL;
3580 if (!(p = lock_user_string(arg1)))
3581 goto execve_efault;
3582 ret = get_errno(execve(p, argp, envp));
3583 unlock_user(p, arg1, 0);
3585 goto execve_end;
3587 execve_efault:
3588 ret = -TARGET_EFAULT;
3590 execve_end:
3591 for (gp = guest_argp, q = argp; *q;
3592 gp += sizeof(abi_ulong), q++) {
3593 if (get_user_ual(addr, gp)
3594 || !addr)
3595 break;
3596 unlock_user(*q, addr, 0);
3598 for (gp = guest_envp, q = envp; *q;
3599 gp += sizeof(abi_ulong), q++) {
3600 if (get_user_ual(addr, gp)
3601 || !addr)
3602 break;
3603 unlock_user(*q, addr, 0);
3606 break;
3607 case TARGET_NR_chdir:
3608 if (!(p = lock_user_string(arg1)))
3609 goto efault;
3610 ret = get_errno(chdir(p));
3611 unlock_user(p, arg1, 0);
3612 break;
3613 #ifdef TARGET_NR_time
3614 case TARGET_NR_time:
3616 time_t host_time;
3617 ret = get_errno(time(&host_time));
3618 if (!is_error(ret)
3619 && arg1
3620 && put_user_sal(host_time, arg1))
3621 goto efault;
3623 break;
3624 #endif
3625 case TARGET_NR_mknod:
3626 if (!(p = lock_user_string(arg1)))
3627 goto efault;
3628 ret = get_errno(mknod(p, arg2, arg3));
3629 unlock_user(p, arg1, 0);
3630 break;
3631 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
3632 case TARGET_NR_mknodat:
3633 if (!(p = lock_user_string(arg2)))
3634 goto efault;
3635 ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
3636 unlock_user(p, arg2, 0);
3637 break;
3638 #endif
3639 case TARGET_NR_chmod:
3640 if (!(p = lock_user_string(arg1)))
3641 goto efault;
3642 ret = get_errno(chmod(p, arg2));
3643 unlock_user(p, arg1, 0);
3644 break;
3645 #ifdef TARGET_NR_break
3646 case TARGET_NR_break:
3647 goto unimplemented;
3648 #endif
3649 #ifdef TARGET_NR_oldstat
3650 case TARGET_NR_oldstat:
3651 goto unimplemented;
3652 #endif
3653 case TARGET_NR_lseek:
3654 ret = get_errno(lseek(arg1, arg2, arg3));
3655 break;
3656 #ifdef TARGET_NR_getxpid
3657 case TARGET_NR_getxpid:
3658 #else
3659 case TARGET_NR_getpid:
3660 #endif
3661 ret = get_errno(getpid());
3662 break;
3663 case TARGET_NR_mount:
3665 /* need to look at the data field */
3666 void *p2, *p3;
3667 p = lock_user_string(arg1);
3668 p2 = lock_user_string(arg2);
3669 p3 = lock_user_string(arg3);
3670 if (!p || !p2 || !p3)
3671 ret = -TARGET_EFAULT;
3672 else
3673 /* FIXME - arg5 should be locked, but it isn't clear how to
3674 * do that since it's not guaranteed to be a NULL-terminated
3675 * string.
3677 ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
3678 unlock_user(p, arg1, 0);
3679 unlock_user(p2, arg2, 0);
3680 unlock_user(p3, arg3, 0);
3681 break;
3683 #ifdef TARGET_NR_umount
3684 case TARGET_NR_umount:
3685 if (!(p = lock_user_string(arg1)))
3686 goto efault;
3687 ret = get_errno(umount(p));
3688 unlock_user(p, arg1, 0);
3689 break;
3690 #endif
3691 #ifdef TARGET_NR_stime /* not on alpha */
3692 case TARGET_NR_stime:
3694 time_t host_time;
3695 if (get_user_sal(host_time, arg1))
3696 goto efault;
3697 ret = get_errno(stime(&host_time));
3699 break;
3700 #endif
3701 case TARGET_NR_ptrace:
3702 goto unimplemented;
3703 #ifdef TARGET_NR_alarm /* not on alpha */
3704 case TARGET_NR_alarm:
3705 ret = alarm(arg1);
3706 break;
3707 #endif
3708 #ifdef TARGET_NR_oldfstat
3709 case TARGET_NR_oldfstat:
3710 goto unimplemented;
3711 #endif
3712 #ifdef TARGET_NR_pause /* not on alpha */
3713 case TARGET_NR_pause:
3714 ret = get_errno(pause());
3715 break;
3716 #endif
3717 #ifdef TARGET_NR_utime
3718 case TARGET_NR_utime:
3720 struct utimbuf tbuf, *host_tbuf;
3721 struct target_utimbuf *target_tbuf;
3722 if (arg2) {
3723 if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
3724 goto efault;
3725 tbuf.actime = tswapl(target_tbuf->actime);
3726 tbuf.modtime = tswapl(target_tbuf->modtime);
3727 unlock_user_struct(target_tbuf, arg2, 0);
3728 host_tbuf = &tbuf;
3729 } else {
3730 host_tbuf = NULL;
3732 if (!(p = lock_user_string(arg1)))
3733 goto efault;
3734 ret = get_errno(utime(p, host_tbuf));
3735 unlock_user(p, arg1, 0);
3737 break;
3738 #endif
3739 case TARGET_NR_utimes:
3741 struct timeval *tvp, tv[2];
3742 if (arg2) {
3743 if (copy_from_user_timeval(&tv[0], arg2)
3744 || copy_from_user_timeval(&tv[1],
3745 arg2 + sizeof(struct target_timeval)))
3746 goto efault;
3747 tvp = tv;
3748 } else {
3749 tvp = NULL;
3751 if (!(p = lock_user_string(arg1)))
3752 goto efault;
3753 ret = get_errno(utimes(p, tvp));
3754 unlock_user(p, arg1, 0);
3756 break;
3757 #if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
3758 case TARGET_NR_futimesat:
3760 struct timeval *tvp, tv[2];
3761 if (arg3) {
3762 if (copy_from_user_timeval(&tv[0], arg3)
3763 || copy_from_user_timeval(&tv[1],
3764 arg3 + sizeof(struct target_timeval)))
3765 goto efault;
3766 tvp = tv;
3767 } else {
3768 tvp = NULL;
3770 if (!(p = lock_user_string(arg2)))
3771 goto efault;
3772 ret = get_errno(sys_futimesat(arg1, path(p), tvp));
3773 unlock_user(p, arg2, 0);
3775 break;
3776 #endif
3777 #ifdef TARGET_NR_stty
3778 case TARGET_NR_stty:
3779 goto unimplemented;
3780 #endif
3781 #ifdef TARGET_NR_gtty
3782 case TARGET_NR_gtty:
3783 goto unimplemented;
3784 #endif
3785 case TARGET_NR_access:
3786 if (!(p = lock_user_string(arg1)))
3787 goto efault;
3788 ret = get_errno(access(p, arg2));
3789 unlock_user(p, arg1, 0);
3790 break;
3791 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
3792 case TARGET_NR_faccessat:
3793 if (!(p = lock_user_string(arg2)))
3794 goto efault;
3795 ret = get_errno(sys_faccessat(arg1, p, arg3, arg4));
3796 unlock_user(p, arg2, 0);
3797 break;
3798 #endif
3799 #ifdef TARGET_NR_nice /* not on alpha */
3800 case TARGET_NR_nice:
3801 ret = get_errno(nice(arg1));
3802 break;
3803 #endif
3804 #ifdef TARGET_NR_ftime
3805 case TARGET_NR_ftime:
3806 goto unimplemented;
3807 #endif
3808 case TARGET_NR_sync:
3809 sync();
3810 ret = 0;
3811 break;
3812 case TARGET_NR_kill:
3813 ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
3814 break;
3815 case TARGET_NR_rename:
3817 void *p2;
3818 p = lock_user_string(arg1);
3819 p2 = lock_user_string(arg2);
3820 if (!p || !p2)
3821 ret = -TARGET_EFAULT;
3822 else
3823 ret = get_errno(rename(p, p2));
3824 unlock_user(p2, arg2, 0);
3825 unlock_user(p, arg1, 0);
3827 break;
3828 #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
3829 case TARGET_NR_renameat:
3831 void *p2;
3832 p = lock_user_string(arg2);
3833 p2 = lock_user_string(arg4);
3834 if (!p || !p2)
3835 ret = -TARGET_EFAULT;
3836 else
3837 ret = get_errno(sys_renameat(arg1, p, arg3, p2));
3838 unlock_user(p2, arg4, 0);
3839 unlock_user(p, arg2, 0);
3841 break;
3842 #endif
3843 case TARGET_NR_mkdir:
3844 if (!(p = lock_user_string(arg1)))
3845 goto efault;
3846 ret = get_errno(mkdir(p, arg2));
3847 unlock_user(p, arg1, 0);
3848 break;
3849 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
3850 case TARGET_NR_mkdirat:
3851 if (!(p = lock_user_string(arg2)))
3852 goto efault;
3853 ret = get_errno(sys_mkdirat(arg1, p, arg3));
3854 unlock_user(p, arg2, 0);
3855 break;
3856 #endif
3857 case TARGET_NR_rmdir:
3858 if (!(p = lock_user_string(arg1)))
3859 goto efault;
3860 ret = get_errno(rmdir(p));
3861 unlock_user(p, arg1, 0);
3862 break;
3863 case TARGET_NR_dup:
3864 ret = get_errno(dup(arg1));
3865 break;
3866 case TARGET_NR_pipe:
3868 int host_pipe[2];
3869 ret = get_errno(pipe(host_pipe));
3870 if (!is_error(ret)) {
3871 #if defined(TARGET_MIPS)
3872 CPUMIPSState *env = (CPUMIPSState*)cpu_env;
3873 env->active_tc.gpr[3] = host_pipe[1];
3874 ret = host_pipe[0];
3875 #elif defined(TARGET_SH4)
3876 ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
3877 ret = host_pipe[0];
3878 #else
3879 if (put_user_s32(host_pipe[0], arg1)
3880 || put_user_s32(host_pipe[1], arg1 + sizeof(host_pipe[0])))
3881 goto efault;
3882 #endif
3885 break;
3886 case TARGET_NR_times:
3888 struct target_tms *tmsp;
3889 struct tms tms;
3890 ret = get_errno(times(&tms));
3891 if (arg1) {
3892 tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
3893 if (!tmsp)
3894 goto efault;
3895 tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
3896 tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
3897 tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
3898 tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime));
3900 if (!is_error(ret))
3901 ret = host_to_target_clock_t(ret);
3903 break;
3904 #ifdef TARGET_NR_prof
3905 case TARGET_NR_prof:
3906 goto unimplemented;
3907 #endif
3908 #ifdef TARGET_NR_signal
3909 case TARGET_NR_signal:
3910 goto unimplemented;
3911 #endif
3912 case TARGET_NR_acct:
3913 if (!(p = lock_user_string(arg1)))
3914 goto efault;
3915 ret = get_errno(acct(path(p)));
3916 unlock_user(p, arg1, 0);
3917 break;
3918 #ifdef TARGET_NR_umount2 /* not on alpha */
3919 case TARGET_NR_umount2:
3920 if (!(p = lock_user_string(arg1)))
3921 goto efault;
3922 ret = get_errno(umount2(p, arg2));
3923 unlock_user(p, arg1, 0);
3924 break;
3925 #endif
3926 #ifdef TARGET_NR_lock
3927 case TARGET_NR_lock:
3928 goto unimplemented;
3929 #endif
3930 case TARGET_NR_ioctl:
3931 ret = do_ioctl(arg1, arg2, arg3);
3932 break;
3933 case TARGET_NR_fcntl:
3934 ret = do_fcntl(arg1, arg2, arg3);
3935 break;
3936 #ifdef TARGET_NR_mpx
3937 case TARGET_NR_mpx:
3938 goto unimplemented;
3939 #endif
3940 case TARGET_NR_setpgid:
3941 ret = get_errno(setpgid(arg1, arg2));
3942 break;
3943 #ifdef TARGET_NR_ulimit
3944 case TARGET_NR_ulimit:
3945 goto unimplemented;
3946 #endif
3947 #ifdef TARGET_NR_oldolduname
3948 case TARGET_NR_oldolduname:
3949 goto unimplemented;
3950 #endif
3951 case TARGET_NR_umask:
3952 ret = get_errno(umask(arg1));
3953 break;
3954 case TARGET_NR_chroot:
3955 if (!(p = lock_user_string(arg1)))
3956 goto efault;
3957 ret = get_errno(chroot(p));
3958 unlock_user(p, arg1, 0);
3959 break;
3960 case TARGET_NR_ustat:
3961 goto unimplemented;
3962 case TARGET_NR_dup2:
3963 ret = get_errno(dup2(arg1, arg2));
3964 break;
3965 #ifdef TARGET_NR_getppid /* not on alpha */
3966 case TARGET_NR_getppid:
3967 ret = get_errno(getppid());
3968 break;
3969 #endif
3970 case TARGET_NR_getpgrp:
3971 ret = get_errno(getpgrp());
3972 break;
3973 case TARGET_NR_setsid:
3974 ret = get_errno(setsid());
3975 break;
3976 #ifdef TARGET_NR_sigaction
3977 case TARGET_NR_sigaction:
3979 #if !defined(TARGET_MIPS)
3980 struct target_old_sigaction *old_act;
3981 struct target_sigaction act, oact, *pact;
3982 if (arg2) {
3983 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
3984 goto efault;
3985 act._sa_handler = old_act->_sa_handler;
3986 target_siginitset(&act.sa_mask, old_act->sa_mask);
3987 act.sa_flags = old_act->sa_flags;
3988 act.sa_restorer = old_act->sa_restorer;
3989 unlock_user_struct(old_act, arg2, 0);
3990 pact = &act;
3991 } else {
3992 pact = NULL;
3994 ret = get_errno(do_sigaction(arg1, pact, &oact));
3995 if (!is_error(ret) && arg3) {
3996 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
3997 goto efault;
3998 old_act->_sa_handler = oact._sa_handler;
3999 old_act->sa_mask = oact.sa_mask.sig[0];
4000 old_act->sa_flags = oact.sa_flags;
4001 old_act->sa_restorer = oact.sa_restorer;
4002 unlock_user_struct(old_act, arg3, 1);
4004 #else
4005 struct target_sigaction act, oact, *pact, *old_act;
4007 if (arg2) {
4008 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4009 goto efault;
4010 act._sa_handler = old_act->_sa_handler;
4011 target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
4012 act.sa_flags = old_act->sa_flags;
4013 unlock_user_struct(old_act, arg2, 0);
4014 pact = &act;
4015 } else {
4016 pact = NULL;
4019 ret = get_errno(do_sigaction(arg1, pact, &oact));
4021 if (!is_error(ret) && arg3) {
4022 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4023 goto efault;
4024 old_act->_sa_handler = oact._sa_handler;
4025 old_act->sa_flags = oact.sa_flags;
4026 old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
4027 old_act->sa_mask.sig[1] = 0;
4028 old_act->sa_mask.sig[2] = 0;
4029 old_act->sa_mask.sig[3] = 0;
4030 unlock_user_struct(old_act, arg3, 1);
4032 #endif
4034 break;
4035 #endif
4036 case TARGET_NR_rt_sigaction:
4038 struct target_sigaction *act;
4039 struct target_sigaction *oact;
4041 if (arg2) {
4042 if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
4043 goto efault;
4044 } else
4045 act = NULL;
4046 if (arg3) {
4047 if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
4048 ret = -TARGET_EFAULT;
4049 goto rt_sigaction_fail;
4051 } else
4052 oact = NULL;
4053 ret = get_errno(do_sigaction(arg1, act, oact));
4054 rt_sigaction_fail:
4055 if (act)
4056 unlock_user_struct(act, arg2, 0);
4057 if (oact)
4058 unlock_user_struct(oact, arg3, 1);
4060 break;
4061 #ifdef TARGET_NR_sgetmask /* not on alpha */
4062 case TARGET_NR_sgetmask:
4064 sigset_t cur_set;
4065 abi_ulong target_set;
4066 sigprocmask(0, NULL, &cur_set);
4067 host_to_target_old_sigset(&target_set, &cur_set);
4068 ret = target_set;
4070 break;
4071 #endif
4072 #ifdef TARGET_NR_ssetmask /* not on alpha */
4073 case TARGET_NR_ssetmask:
4075 sigset_t set, oset, cur_set;
4076 abi_ulong target_set = arg1;
4077 sigprocmask(0, NULL, &cur_set);
4078 target_to_host_old_sigset(&set, &target_set);
4079 sigorset(&set, &set, &cur_set);
4080 sigprocmask(SIG_SETMASK, &set, &oset);
4081 host_to_target_old_sigset(&target_set, &oset);
4082 ret = target_set;
4084 break;
4085 #endif
4086 #ifdef TARGET_NR_sigprocmask
4087 case TARGET_NR_sigprocmask:
4089 int how = arg1;
4090 sigset_t set, oldset, *set_ptr;
4092 if (arg2) {
4093 switch(how) {
4094 case TARGET_SIG_BLOCK:
4095 how = SIG_BLOCK;
4096 break;
4097 case TARGET_SIG_UNBLOCK:
4098 how = SIG_UNBLOCK;
4099 break;
4100 case TARGET_SIG_SETMASK:
4101 how = SIG_SETMASK;
4102 break;
4103 default:
4104 ret = -TARGET_EINVAL;
4105 goto fail;
4107 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4108 goto efault;
4109 target_to_host_old_sigset(&set, p);
4110 unlock_user(p, arg2, 0);
4111 set_ptr = &set;
4112 } else {
4113 how = 0;
4114 set_ptr = NULL;
4116 ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
4117 if (!is_error(ret) && arg3) {
4118 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4119 goto efault;
4120 host_to_target_old_sigset(p, &oldset);
4121 unlock_user(p, arg3, sizeof(target_sigset_t));
4124 break;
4125 #endif
4126 case TARGET_NR_rt_sigprocmask:
4128 int how = arg1;
4129 sigset_t set, oldset, *set_ptr;
4131 if (arg2) {
4132 switch(how) {
4133 case TARGET_SIG_BLOCK:
4134 how = SIG_BLOCK;
4135 break;
4136 case TARGET_SIG_UNBLOCK:
4137 how = SIG_UNBLOCK;
4138 break;
4139 case TARGET_SIG_SETMASK:
4140 how = SIG_SETMASK;
4141 break;
4142 default:
4143 ret = -TARGET_EINVAL;
4144 goto fail;
4146 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4147 goto efault;
4148 target_to_host_sigset(&set, p);
4149 unlock_user(p, arg2, 0);
4150 set_ptr = &set;
4151 } else {
4152 how = 0;
4153 set_ptr = NULL;
4155 ret = get_errno(sigprocmask(how, set_ptr, &oldset));
4156 if (!is_error(ret) && arg3) {
4157 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4158 goto efault;
4159 host_to_target_sigset(p, &oldset);
4160 unlock_user(p, arg3, sizeof(target_sigset_t));
4163 break;
4164 #ifdef TARGET_NR_sigpending
4165 case TARGET_NR_sigpending:
4167 sigset_t set;
4168 ret = get_errno(sigpending(&set));
4169 if (!is_error(ret)) {
4170 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4171 goto efault;
4172 host_to_target_old_sigset(p, &set);
4173 unlock_user(p, arg1, sizeof(target_sigset_t));
4176 break;
4177 #endif
4178 case TARGET_NR_rt_sigpending:
4180 sigset_t set;
4181 ret = get_errno(sigpending(&set));
4182 if (!is_error(ret)) {
4183 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4184 goto efault;
4185 host_to_target_sigset(p, &set);
4186 unlock_user(p, arg1, sizeof(target_sigset_t));
4189 break;
4190 #ifdef TARGET_NR_sigsuspend
4191 case TARGET_NR_sigsuspend:
4193 sigset_t set;
4194 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4195 goto efault;
4196 target_to_host_old_sigset(&set, p);
4197 unlock_user(p, arg1, 0);
4198 ret = get_errno(sigsuspend(&set));
4200 break;
4201 #endif
4202 case TARGET_NR_rt_sigsuspend:
4204 sigset_t set;
4205 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4206 goto efault;
4207 target_to_host_sigset(&set, p);
4208 unlock_user(p, arg1, 0);
4209 ret = get_errno(sigsuspend(&set));
4211 break;
4212 case TARGET_NR_rt_sigtimedwait:
4214 sigset_t set;
4215 struct timespec uts, *puts;
4216 siginfo_t uinfo;
4218 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4219 goto efault;
4220 target_to_host_sigset(&set, p);
4221 unlock_user(p, arg1, 0);
4222 if (arg3) {
4223 puts = &uts;
4224 target_to_host_timespec(puts, arg3);
4225 } else {
4226 puts = NULL;
4228 ret = get_errno(sigtimedwait(&set, &uinfo, puts));
4229 if (!is_error(ret) && arg2) {
4230 if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
4231 goto efault;
4232 host_to_target_siginfo(p, &uinfo);
4233 unlock_user(p, arg2, sizeof(target_siginfo_t));
4236 break;
4237 case TARGET_NR_rt_sigqueueinfo:
4239 siginfo_t uinfo;
4240 if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
4241 goto efault;
4242 target_to_host_siginfo(&uinfo, p);
4243 unlock_user(p, arg1, 0);
4244 ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
4246 break;
4247 #ifdef TARGET_NR_sigreturn
4248 case TARGET_NR_sigreturn:
4249 /* NOTE: ret is eax, so not transcoding must be done */
4250 ret = do_sigreturn(cpu_env);
4251 break;
4252 #endif
4253 case TARGET_NR_rt_sigreturn:
4254 /* NOTE: ret is eax, so not transcoding must be done */
4255 ret = do_rt_sigreturn(cpu_env);
4256 break;
4257 case TARGET_NR_sethostname:
4258 if (!(p = lock_user_string(arg1)))
4259 goto efault;
4260 ret = get_errno(sethostname(p, arg2));
4261 unlock_user(p, arg1, 0);
4262 break;
4263 case TARGET_NR_setrlimit:
4265 /* XXX: convert resource ? */
4266 int resource = arg1;
4267 struct target_rlimit *target_rlim;
4268 struct rlimit rlim;
4269 if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
4270 goto efault;
4271 rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4272 rlim.rlim_max = tswapl(target_rlim->rlim_max);
4273 unlock_user_struct(target_rlim, arg2, 0);
4274 ret = get_errno(setrlimit(resource, &rlim));
4276 break;
4277 case TARGET_NR_getrlimit:
4279 /* XXX: convert resource ? */
4280 int resource = arg1;
4281 struct target_rlimit *target_rlim;
4282 struct rlimit rlim;
4284 ret = get_errno(getrlimit(resource, &rlim));
4285 if (!is_error(ret)) {
4286 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
4287 goto efault;
4288 rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4289 rlim.rlim_max = tswapl(target_rlim->rlim_max);
4290 unlock_user_struct(target_rlim, arg2, 1);
4293 break;
4294 case TARGET_NR_getrusage:
4296 struct rusage rusage;
4297 ret = get_errno(getrusage(arg1, &rusage));
4298 if (!is_error(ret)) {
4299 host_to_target_rusage(arg2, &rusage);
4302 break;
4303 case TARGET_NR_gettimeofday:
4305 struct timeval tv;
4306 ret = get_errno(gettimeofday(&tv, NULL));
4307 if (!is_error(ret)) {
4308 if (copy_to_user_timeval(arg1, &tv))
4309 goto efault;
4312 break;
4313 case TARGET_NR_settimeofday:
4315 struct timeval tv;
4316 if (copy_from_user_timeval(&tv, arg1))
4317 goto efault;
4318 ret = get_errno(settimeofday(&tv, NULL));
4320 break;
4321 #ifdef TARGET_NR_select
4322 case TARGET_NR_select:
4324 struct target_sel_arg_struct *sel;
4325 abi_ulong inp, outp, exp, tvp;
4326 long nsel;
4328 if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
4329 goto efault;
4330 nsel = tswapl(sel->n);
4331 inp = tswapl(sel->inp);
4332 outp = tswapl(sel->outp);
4333 exp = tswapl(sel->exp);
4334 tvp = tswapl(sel->tvp);
4335 unlock_user_struct(sel, arg1, 0);
4336 ret = do_select(nsel, inp, outp, exp, tvp);
4338 break;
4339 #endif
4340 case TARGET_NR_symlink:
4342 void *p2;
4343 p = lock_user_string(arg1);
4344 p2 = lock_user_string(arg2);
4345 if (!p || !p2)
4346 ret = -TARGET_EFAULT;
4347 else
4348 ret = get_errno(symlink(p, p2));
4349 unlock_user(p2, arg2, 0);
4350 unlock_user(p, arg1, 0);
4352 break;
4353 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
4354 case TARGET_NR_symlinkat:
4356 void *p2;
4357 p = lock_user_string(arg1);
4358 p2 = lock_user_string(arg3);
4359 if (!p || !p2)
4360 ret = -TARGET_EFAULT;
4361 else
4362 ret = get_errno(sys_symlinkat(p, arg2, p2));
4363 unlock_user(p2, arg3, 0);
4364 unlock_user(p, arg1, 0);
4366 break;
4367 #endif
4368 #ifdef TARGET_NR_oldlstat
4369 case TARGET_NR_oldlstat:
4370 goto unimplemented;
4371 #endif
4372 case TARGET_NR_readlink:
4374 void *p2;
4375 p = lock_user_string(arg1);
4376 p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
4377 if (!p || !p2)
4378 ret = -TARGET_EFAULT;
4379 else
4380 ret = get_errno(readlink(path(p), p2, arg3));
4381 unlock_user(p2, arg2, ret);
4382 unlock_user(p, arg1, 0);
4384 break;
4385 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
4386 case TARGET_NR_readlinkat:
4388 void *p2;
4389 p = lock_user_string(arg2);
4390 p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
4391 if (!p || !p2)
4392 ret = -TARGET_EFAULT;
4393 else
4394 ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
4395 unlock_user(p2, arg3, ret);
4396 unlock_user(p, arg2, 0);
4398 break;
4399 #endif
4400 #ifdef TARGET_NR_uselib
4401 case TARGET_NR_uselib:
4402 goto unimplemented;
4403 #endif
4404 #ifdef TARGET_NR_swapon
4405 case TARGET_NR_swapon:
4406 if (!(p = lock_user_string(arg1)))
4407 goto efault;
4408 ret = get_errno(swapon(p, arg2));
4409 unlock_user(p, arg1, 0);
4410 break;
4411 #endif
4412 case TARGET_NR_reboot:
4413 goto unimplemented;
4414 #ifdef TARGET_NR_readdir
4415 case TARGET_NR_readdir:
4416 goto unimplemented;
4417 #endif
4418 #ifdef TARGET_NR_mmap
4419 case TARGET_NR_mmap:
4420 #if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS)
4422 abi_ulong *v;
4423 abi_ulong v1, v2, v3, v4, v5, v6;
4424 if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
4425 goto efault;
4426 v1 = tswapl(v[0]);
4427 v2 = tswapl(v[1]);
4428 v3 = tswapl(v[2]);
4429 v4 = tswapl(v[3]);
4430 v5 = tswapl(v[4]);
4431 v6 = tswapl(v[5]);
4432 unlock_user(v, arg1, 0);
4433 ret = get_errno(target_mmap(v1, v2, v3,
4434 target_to_host_bitmask(v4, mmap_flags_tbl),
4435 v5, v6));
4437 #else
4438 ret = get_errno(target_mmap(arg1, arg2, arg3,
4439 target_to_host_bitmask(arg4, mmap_flags_tbl),
4440 arg5,
4441 arg6));
4442 #endif
4443 break;
4444 #endif
4445 #ifdef TARGET_NR_mmap2
4446 case TARGET_NR_mmap2:
4447 #ifndef MMAP_SHIFT
4448 #define MMAP_SHIFT 12
4449 #endif
4450 ret = get_errno(target_mmap(arg1, arg2, arg3,
4451 target_to_host_bitmask(arg4, mmap_flags_tbl),
4452 arg5,
4453 arg6 << MMAP_SHIFT));
4454 break;
4455 #endif
4456 case TARGET_NR_munmap:
4457 ret = get_errno(target_munmap(arg1, arg2));
4458 break;
4459 case TARGET_NR_mprotect:
4460 ret = get_errno(target_mprotect(arg1, arg2, arg3));
4461 break;
4462 #ifdef TARGET_NR_mremap
4463 case TARGET_NR_mremap:
4464 ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
4465 break;
4466 #endif
4467 /* ??? msync/mlock/munlock are broken for softmmu. */
4468 #ifdef TARGET_NR_msync
4469 case TARGET_NR_msync:
4470 ret = get_errno(msync(g2h(arg1), arg2, arg3));
4471 break;
4472 #endif
4473 #ifdef TARGET_NR_mlock
4474 case TARGET_NR_mlock:
4475 ret = get_errno(mlock(g2h(arg1), arg2));
4476 break;
4477 #endif
4478 #ifdef TARGET_NR_munlock
4479 case TARGET_NR_munlock:
4480 ret = get_errno(munlock(g2h(arg1), arg2));
4481 break;
4482 #endif
4483 #ifdef TARGET_NR_mlockall
4484 case TARGET_NR_mlockall:
4485 ret = get_errno(mlockall(arg1));
4486 break;
4487 #endif
4488 #ifdef TARGET_NR_munlockall
4489 case TARGET_NR_munlockall:
4490 ret = get_errno(munlockall());
4491 break;
4492 #endif
4493 case TARGET_NR_truncate:
4494 if (!(p = lock_user_string(arg1)))
4495 goto efault;
4496 ret = get_errno(truncate(p, arg2));
4497 unlock_user(p, arg1, 0);
4498 break;
4499 case TARGET_NR_ftruncate:
4500 ret = get_errno(ftruncate(arg1, arg2));
4501 break;
4502 case TARGET_NR_fchmod:
4503 ret = get_errno(fchmod(arg1, arg2));
4504 break;
4505 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
4506 case TARGET_NR_fchmodat:
4507 if (!(p = lock_user_string(arg2)))
4508 goto efault;
4509 ret = get_errno(sys_fchmodat(arg1, p, arg3, arg4));
4510 unlock_user(p, arg2, 0);
4511 break;
4512 #endif
4513 case TARGET_NR_getpriority:
4514 /* libc does special remapping of the return value of
4515 * sys_getpriority() so it's just easiest to call
4516 * sys_getpriority() directly rather than through libc. */
4517 ret = sys_getpriority(arg1, arg2);
4518 break;
4519 case TARGET_NR_setpriority:
4520 ret = get_errno(setpriority(arg1, arg2, arg3));
4521 break;
4522 #ifdef TARGET_NR_profil
4523 case TARGET_NR_profil:
4524 goto unimplemented;
4525 #endif
4526 case TARGET_NR_statfs:
4527 if (!(p = lock_user_string(arg1)))
4528 goto efault;
4529 ret = get_errno(statfs(path(p), &stfs));
4530 unlock_user(p, arg1, 0);
4531 convert_statfs:
4532 if (!is_error(ret)) {
4533 struct target_statfs *target_stfs;
4535 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
4536 goto efault;
4537 __put_user(stfs.f_type, &target_stfs->f_type);
4538 __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4539 __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4540 __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4541 __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4542 __put_user(stfs.f_files, &target_stfs->f_files);
4543 __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4544 __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4545 __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4546 __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4547 unlock_user_struct(target_stfs, arg2, 1);
4549 break;
4550 case TARGET_NR_fstatfs:
4551 ret = get_errno(fstatfs(arg1, &stfs));
4552 goto convert_statfs;
4553 #ifdef TARGET_NR_statfs64
4554 case TARGET_NR_statfs64:
4555 if (!(p = lock_user_string(arg1)))
4556 goto efault;
4557 ret = get_errno(statfs(path(p), &stfs));
4558 unlock_user(p, arg1, 0);
4559 convert_statfs64:
4560 if (!is_error(ret)) {
4561 struct target_statfs64 *target_stfs;
4563 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
4564 goto efault;
4565 __put_user(stfs.f_type, &target_stfs->f_type);
4566 __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4567 __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4568 __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4569 __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4570 __put_user(stfs.f_files, &target_stfs->f_files);
4571 __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4572 __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4573 __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4574 __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4575 unlock_user_struct(target_stfs, arg3, 1);
4577 break;
4578 case TARGET_NR_fstatfs64:
4579 ret = get_errno(fstatfs(arg1, &stfs));
4580 goto convert_statfs64;
4581 #endif
4582 #ifdef TARGET_NR_ioperm
4583 case TARGET_NR_ioperm:
4584 goto unimplemented;
4585 #endif
4586 #ifdef TARGET_NR_socketcall
4587 case TARGET_NR_socketcall:
4588 ret = do_socketcall(arg1, arg2);
4589 break;
4590 #endif
4591 #ifdef TARGET_NR_accept
4592 case TARGET_NR_accept:
4593 ret = do_accept(arg1, arg2, arg3);
4594 break;
4595 #endif
4596 #ifdef TARGET_NR_bind
4597 case TARGET_NR_bind:
4598 ret = do_bind(arg1, arg2, arg3);
4599 break;
4600 #endif
4601 #ifdef TARGET_NR_connect
4602 case TARGET_NR_connect:
4603 ret = do_connect(arg1, arg2, arg3);
4604 break;
4605 #endif
4606 #ifdef TARGET_NR_getpeername
4607 case TARGET_NR_getpeername:
4608 ret = do_getpeername(arg1, arg2, arg3);
4609 break;
4610 #endif
4611 #ifdef TARGET_NR_getsockname
4612 case TARGET_NR_getsockname:
4613 ret = do_getsockname(arg1, arg2, arg3);
4614 break;
4615 #endif
4616 #ifdef TARGET_NR_getsockopt
4617 case TARGET_NR_getsockopt:
4618 ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
4619 break;
4620 #endif
4621 #ifdef TARGET_NR_listen
4622 case TARGET_NR_listen:
4623 ret = get_errno(listen(arg1, arg2));
4624 break;
4625 #endif
4626 #ifdef TARGET_NR_recv
4627 case TARGET_NR_recv:
4628 ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
4629 break;
4630 #endif
4631 #ifdef TARGET_NR_recvfrom
4632 case TARGET_NR_recvfrom:
4633 ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
4634 break;
4635 #endif
4636 #ifdef TARGET_NR_recvmsg
4637 case TARGET_NR_recvmsg:
4638 ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
4639 break;
4640 #endif
4641 #ifdef TARGET_NR_send
4642 case TARGET_NR_send:
4643 ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
4644 break;
4645 #endif
4646 #ifdef TARGET_NR_sendmsg
4647 case TARGET_NR_sendmsg:
4648 ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
4649 break;
4650 #endif
4651 #ifdef TARGET_NR_sendto
4652 case TARGET_NR_sendto:
4653 ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
4654 break;
4655 #endif
4656 #ifdef TARGET_NR_shutdown
4657 case TARGET_NR_shutdown:
4658 ret = get_errno(shutdown(arg1, arg2));
4659 break;
4660 #endif
4661 #ifdef TARGET_NR_socket
4662 case TARGET_NR_socket:
4663 ret = do_socket(arg1, arg2, arg3);
4664 break;
4665 #endif
4666 #ifdef TARGET_NR_socketpair
4667 case TARGET_NR_socketpair:
4668 ret = do_socketpair(arg1, arg2, arg3, arg4);
4669 break;
4670 #endif
4671 #ifdef TARGET_NR_setsockopt
4672 case TARGET_NR_setsockopt:
4673 ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
4674 break;
4675 #endif
4677 case TARGET_NR_syslog:
4678 if (!(p = lock_user_string(arg2)))
4679 goto efault;
4680 ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
4681 unlock_user(p, arg2, 0);
4682 break;
4684 case TARGET_NR_setitimer:
4686 struct itimerval value, ovalue, *pvalue;
4688 if (arg2) {
4689 pvalue = &value;
4690 if (copy_from_user_timeval(&pvalue->it_interval, arg2)
4691 || copy_from_user_timeval(&pvalue->it_value,
4692 arg2 + sizeof(struct target_timeval)))
4693 goto efault;
4694 } else {
4695 pvalue = NULL;
4697 ret = get_errno(setitimer(arg1, pvalue, &ovalue));
4698 if (!is_error(ret) && arg3) {
4699 if (copy_to_user_timeval(arg3,
4700 &ovalue.it_interval)
4701 || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
4702 &ovalue.it_value))
4703 goto efault;
4706 break;
4707 case TARGET_NR_getitimer:
4709 struct itimerval value;
4711 ret = get_errno(getitimer(arg1, &value));
4712 if (!is_error(ret) && arg2) {
4713 if (copy_to_user_timeval(arg2,
4714 &value.it_interval)
4715 || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
4716 &value.it_value))
4717 goto efault;
4720 break;
4721 case TARGET_NR_stat:
4722 if (!(p = lock_user_string(arg1)))
4723 goto efault;
4724 ret = get_errno(stat(path(p), &st));
4725 unlock_user(p, arg1, 0);
4726 goto do_stat;
4727 case TARGET_NR_lstat:
4728 if (!(p = lock_user_string(arg1)))
4729 goto efault;
4730 ret = get_errno(lstat(path(p), &st));
4731 unlock_user(p, arg1, 0);
4732 goto do_stat;
4733 case TARGET_NR_fstat:
4735 ret = get_errno(fstat(arg1, &st));
4736 do_stat:
4737 if (!is_error(ret)) {
4738 struct target_stat *target_st;
4740 if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
4741 goto efault;
4742 __put_user(st.st_dev, &target_st->st_dev);
4743 __put_user(st.st_ino, &target_st->st_ino);
4744 __put_user(st.st_mode, &target_st->st_mode);
4745 __put_user(st.st_uid, &target_st->st_uid);
4746 __put_user(st.st_gid, &target_st->st_gid);
4747 __put_user(st.st_nlink, &target_st->st_nlink);
4748 __put_user(st.st_rdev, &target_st->st_rdev);
4749 __put_user(st.st_size, &target_st->st_size);
4750 __put_user(st.st_blksize, &target_st->st_blksize);
4751 __put_user(st.st_blocks, &target_st->st_blocks);
4752 __put_user(st.st_atime, &target_st->target_st_atime);
4753 __put_user(st.st_mtime, &target_st->target_st_mtime);
4754 __put_user(st.st_ctime, &target_st->target_st_ctime);
4755 unlock_user_struct(target_st, arg2, 1);
4758 break;
4759 #ifdef TARGET_NR_olduname
4760 case TARGET_NR_olduname:
4761 goto unimplemented;
4762 #endif
4763 #ifdef TARGET_NR_iopl
4764 case TARGET_NR_iopl:
4765 goto unimplemented;
4766 #endif
4767 case TARGET_NR_vhangup:
4768 ret = get_errno(vhangup());
4769 break;
4770 #ifdef TARGET_NR_idle
4771 case TARGET_NR_idle:
4772 goto unimplemented;
4773 #endif
4774 #ifdef TARGET_NR_syscall
4775 case TARGET_NR_syscall:
4776 ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
4777 break;
4778 #endif
4779 case TARGET_NR_wait4:
4781 int status;
4782 abi_long status_ptr = arg2;
4783 struct rusage rusage, *rusage_ptr;
4784 abi_ulong target_rusage = arg4;
4785 if (target_rusage)
4786 rusage_ptr = &rusage;
4787 else
4788 rusage_ptr = NULL;
4789 ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
4790 if (!is_error(ret)) {
4791 if (status_ptr) {
4792 if (put_user_s32(status, status_ptr))
4793 goto efault;
4795 if (target_rusage)
4796 host_to_target_rusage(target_rusage, &rusage);
4799 break;
4800 #ifdef TARGET_NR_swapoff
4801 case TARGET_NR_swapoff:
4802 if (!(p = lock_user_string(arg1)))
4803 goto efault;
4804 ret = get_errno(swapoff(p));
4805 unlock_user(p, arg1, 0);
4806 break;
4807 #endif
4808 case TARGET_NR_sysinfo:
4810 struct target_sysinfo *target_value;
4811 struct sysinfo value;
4812 ret = get_errno(sysinfo(&value));
4813 if (!is_error(ret) && arg1)
4815 if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
4816 goto efault;
4817 __put_user(value.uptime, &target_value->uptime);
4818 __put_user(value.loads[0], &target_value->loads[0]);
4819 __put_user(value.loads[1], &target_value->loads[1]);
4820 __put_user(value.loads[2], &target_value->loads[2]);
4821 __put_user(value.totalram, &target_value->totalram);
4822 __put_user(value.freeram, &target_value->freeram);
4823 __put_user(value.sharedram, &target_value->sharedram);
4824 __put_user(value.bufferram, &target_value->bufferram);
4825 __put_user(value.totalswap, &target_value->totalswap);
4826 __put_user(value.freeswap, &target_value->freeswap);
4827 __put_user(value.procs, &target_value->procs);
4828 __put_user(value.totalhigh, &target_value->totalhigh);
4829 __put_user(value.freehigh, &target_value->freehigh);
4830 __put_user(value.mem_unit, &target_value->mem_unit);
4831 unlock_user_struct(target_value, arg1, 1);
4834 break;
4835 #ifdef TARGET_NR_ipc
4836 case TARGET_NR_ipc:
4837 ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
4838 break;
4839 #endif
4841 #ifdef TARGET_NR_msgctl
4842 case TARGET_NR_msgctl:
4843 ret = do_msgctl(arg1, arg2, arg3);
4844 break;
4845 #endif
4846 #ifdef TARGET_NR_msgget
4847 case TARGET_NR_msgget:
4848 ret = get_errno(msgget(arg1, arg2));
4849 break;
4850 #endif
4851 #ifdef TARGET_NR_msgrcv
4852 case TARGET_NR_msgrcv:
4853 ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
4854 break;
4855 #endif
4856 #ifdef TARGET_NR_msgsnd
4857 case TARGET_NR_msgsnd:
4858 ret = do_msgsnd(arg1, arg2, arg3, arg4);
4859 break;
4860 #endif
4861 case TARGET_NR_fsync:
4862 ret = get_errno(fsync(arg1));
4863 break;
4864 case TARGET_NR_clone:
4865 #if defined(TARGET_SH4)
4866 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
4867 #else
4868 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
4869 #endif
4870 break;
4871 #ifdef __NR_exit_group
4872 /* new thread calls */
4873 case TARGET_NR_exit_group:
4874 #ifdef HAVE_GPROF
4875 _mcleanup();
4876 #endif
4877 gdb_exit(cpu_env, arg1);
4878 ret = get_errno(exit_group(arg1));
4879 break;
4880 #endif
4881 case TARGET_NR_setdomainname:
4882 if (!(p = lock_user_string(arg1)))
4883 goto efault;
4884 ret = get_errno(setdomainname(p, arg2));
4885 unlock_user(p, arg1, 0);
4886 break;
4887 case TARGET_NR_uname:
4888 /* no need to transcode because we use the linux syscall */
4890 struct new_utsname * buf;
4892 if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
4893 goto efault;
4894 ret = get_errno(sys_uname(buf));
4895 if (!is_error(ret)) {
4896 /* Overrite the native machine name with whatever is being
4897 emulated. */
4898 strcpy (buf->machine, UNAME_MACHINE);
4899 /* Allow the user to override the reported release. */
4900 if (qemu_uname_release && *qemu_uname_release)
4901 strcpy (buf->release, qemu_uname_release);
4903 unlock_user_struct(buf, arg1, 1);
4905 break;
4906 #ifdef TARGET_I386
4907 case TARGET_NR_modify_ldt:
4908 ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
4909 break;
4910 #if !defined(TARGET_X86_64)
4911 case TARGET_NR_vm86old:
4912 goto unimplemented;
4913 case TARGET_NR_vm86:
4914 ret = do_vm86(cpu_env, arg1, arg2);
4915 break;
4916 #endif
4917 #endif
4918 case TARGET_NR_adjtimex:
4919 goto unimplemented;
4920 #ifdef TARGET_NR_create_module
4921 case TARGET_NR_create_module:
4922 #endif
4923 case TARGET_NR_init_module:
4924 case TARGET_NR_delete_module:
4925 #ifdef TARGET_NR_get_kernel_syms
4926 case TARGET_NR_get_kernel_syms:
4927 #endif
4928 goto unimplemented;
4929 case TARGET_NR_quotactl:
4930 goto unimplemented;
4931 case TARGET_NR_getpgid:
4932 ret = get_errno(getpgid(arg1));
4933 break;
4934 case TARGET_NR_fchdir:
4935 ret = get_errno(fchdir(arg1));
4936 break;
4937 #ifdef TARGET_NR_bdflush /* not on x86_64 */
4938 case TARGET_NR_bdflush:
4939 goto unimplemented;
4940 #endif
4941 #ifdef TARGET_NR_sysfs
4942 case TARGET_NR_sysfs:
4943 goto unimplemented;
4944 #endif
4945 case TARGET_NR_personality:
4946 ret = get_errno(personality(arg1));
4947 break;
4948 #ifdef TARGET_NR_afs_syscall
4949 case TARGET_NR_afs_syscall:
4950 goto unimplemented;
4951 #endif
4952 #ifdef TARGET_NR__llseek /* Not on alpha */
4953 case TARGET_NR__llseek:
4955 #if defined (__x86_64__)
4956 ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
4957 if (put_user_s64(ret, arg4))
4958 goto efault;
4959 #else
4960 int64_t res;
4961 ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
4962 if (put_user_s64(res, arg4))
4963 goto efault;
4964 #endif
4966 break;
4967 #endif
4968 case TARGET_NR_getdents:
4969 #if TARGET_ABI_BITS != 32
4970 goto unimplemented;
4971 #elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
4973 struct target_dirent *target_dirp;
4974 struct linux_dirent *dirp;
4975 abi_long count = arg3;
4977 dirp = malloc(count);
4978 if (!dirp) {
4979 ret = -TARGET_ENOMEM;
4980 goto fail;
4983 ret = get_errno(sys_getdents(arg1, dirp, count));
4984 if (!is_error(ret)) {
4985 struct linux_dirent *de;
4986 struct target_dirent *tde;
4987 int len = ret;
4988 int reclen, treclen;
4989 int count1, tnamelen;
4991 count1 = 0;
4992 de = dirp;
4993 if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4994 goto efault;
4995 tde = target_dirp;
4996 while (len > 0) {
4997 reclen = de->d_reclen;
4998 treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
4999 tde->d_reclen = tswap16(treclen);
5000 tde->d_ino = tswapl(de->d_ino);
5001 tde->d_off = tswapl(de->d_off);
5002 tnamelen = treclen - (2 * sizeof(abi_long) + 2);
5003 if (tnamelen > 256)
5004 tnamelen = 256;
5005 /* XXX: may not be correct */
5006 pstrcpy(tde->d_name, tnamelen, de->d_name);
5007 de = (struct linux_dirent *)((char *)de + reclen);
5008 len -= reclen;
5009 tde = (struct target_dirent *)((char *)tde + treclen);
5010 count1 += treclen;
5012 ret = count1;
5013 unlock_user(target_dirp, arg2, ret);
5015 free(dirp);
5017 #else
5019 struct linux_dirent *dirp;
5020 abi_long count = arg3;
5022 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5023 goto efault;
5024 ret = get_errno(sys_getdents(arg1, dirp, count));
5025 if (!is_error(ret)) {
5026 struct linux_dirent *de;
5027 int len = ret;
5028 int reclen;
5029 de = dirp;
5030 while (len > 0) {
5031 reclen = de->d_reclen;
5032 if (reclen > len)
5033 break;
5034 de->d_reclen = tswap16(reclen);
5035 tswapls(&de->d_ino);
5036 tswapls(&de->d_off);
5037 de = (struct linux_dirent *)((char *)de + reclen);
5038 len -= reclen;
5041 unlock_user(dirp, arg2, ret);
5043 #endif
5044 break;
5045 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
5046 case TARGET_NR_getdents64:
5048 struct linux_dirent64 *dirp;
5049 abi_long count = arg3;
5050 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5051 goto efault;
5052 ret = get_errno(sys_getdents64(arg1, dirp, count));
5053 if (!is_error(ret)) {
5054 struct linux_dirent64 *de;
5055 int len = ret;
5056 int reclen;
5057 de = dirp;
5058 while (len > 0) {
5059 reclen = de->d_reclen;
5060 if (reclen > len)
5061 break;
5062 de->d_reclen = tswap16(reclen);
5063 tswap64s((uint64_t *)&de->d_ino);
5064 tswap64s((uint64_t *)&de->d_off);
5065 de = (struct linux_dirent64 *)((char *)de + reclen);
5066 len -= reclen;
5069 unlock_user(dirp, arg2, ret);
5071 break;
5072 #endif /* TARGET_NR_getdents64 */
5073 #ifdef TARGET_NR__newselect
5074 case TARGET_NR__newselect:
5075 ret = do_select(arg1, arg2, arg3, arg4, arg5);
5076 break;
5077 #endif
5078 #ifdef TARGET_NR_poll
5079 case TARGET_NR_poll:
5081 struct target_pollfd *target_pfd;
5082 unsigned int nfds = arg2;
5083 int timeout = arg3;
5084 struct pollfd *pfd;
5085 unsigned int i;
5087 target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
5088 if (!target_pfd)
5089 goto efault;
5090 pfd = alloca(sizeof(struct pollfd) * nfds);
5091 for(i = 0; i < nfds; i++) {
5092 pfd[i].fd = tswap32(target_pfd[i].fd);
5093 pfd[i].events = tswap16(target_pfd[i].events);
5095 ret = get_errno(poll(pfd, nfds, timeout));
5096 if (!is_error(ret)) {
5097 for(i = 0; i < nfds; i++) {
5098 target_pfd[i].revents = tswap16(pfd[i].revents);
5100 ret += nfds * (sizeof(struct target_pollfd)
5101 - sizeof(struct pollfd));
5103 unlock_user(target_pfd, arg1, ret);
5105 break;
5106 #endif
5107 case TARGET_NR_flock:
5108 /* NOTE: the flock constant seems to be the same for every
5109 Linux platform */
5110 ret = get_errno(flock(arg1, arg2));
5111 break;
5112 case TARGET_NR_readv:
5114 int count = arg3;
5115 struct iovec *vec;
5117 vec = alloca(count * sizeof(struct iovec));
5118 if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
5119 goto efault;
5120 ret = get_errno(readv(arg1, vec, count));
5121 unlock_iovec(vec, arg2, count, 1);
5123 break;
5124 case TARGET_NR_writev:
5126 int count = arg3;
5127 struct iovec *vec;
5129 vec = alloca(count * sizeof(struct iovec));
5130 if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
5131 goto efault;
5132 ret = get_errno(writev(arg1, vec, count));
5133 unlock_iovec(vec, arg2, count, 0);
5135 break;
5136 case TARGET_NR_getsid:
5137 ret = get_errno(getsid(arg1));
5138 break;
5139 #if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
5140 case TARGET_NR_fdatasync:
5141 ret = get_errno(fdatasync(arg1));
5142 break;
5143 #endif
5144 case TARGET_NR__sysctl:
5145 /* We don't implement this, but ENOTDIR is always a safe
5146 return value. */
5147 ret = -TARGET_ENOTDIR;
5148 break;
5149 case TARGET_NR_sched_setparam:
5151 struct sched_param *target_schp;
5152 struct sched_param schp;
5154 if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
5155 goto efault;
5156 schp.sched_priority = tswap32(target_schp->sched_priority);
5157 unlock_user_struct(target_schp, arg2, 0);
5158 ret = get_errno(sched_setparam(arg1, &schp));
5160 break;
5161 case TARGET_NR_sched_getparam:
5163 struct sched_param *target_schp;
5164 struct sched_param schp;
5165 ret = get_errno(sched_getparam(arg1, &schp));
5166 if (!is_error(ret)) {
5167 if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
5168 goto efault;
5169 target_schp->sched_priority = tswap32(schp.sched_priority);
5170 unlock_user_struct(target_schp, arg2, 1);
5173 break;
5174 case TARGET_NR_sched_setscheduler:
5176 struct sched_param *target_schp;
5177 struct sched_param schp;
5178 if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
5179 goto efault;
5180 schp.sched_priority = tswap32(target_schp->sched_priority);
5181 unlock_user_struct(target_schp, arg3, 0);
5182 ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
5184 break;
5185 case TARGET_NR_sched_getscheduler:
5186 ret = get_errno(sched_getscheduler(arg1));
5187 break;
5188 case TARGET_NR_sched_yield:
5189 ret = get_errno(sched_yield());
5190 break;
5191 case TARGET_NR_sched_get_priority_max:
5192 ret = get_errno(sched_get_priority_max(arg1));
5193 break;
5194 case TARGET_NR_sched_get_priority_min:
5195 ret = get_errno(sched_get_priority_min(arg1));
5196 break;
5197 case TARGET_NR_sched_rr_get_interval:
5199 struct timespec ts;
5200 ret = get_errno(sched_rr_get_interval(arg1, &ts));
5201 if (!is_error(ret)) {
5202 host_to_target_timespec(arg2, &ts);
5205 break;
5206 case TARGET_NR_nanosleep:
5208 struct timespec req, rem;
5209 target_to_host_timespec(&req, arg1);
5210 ret = get_errno(nanosleep(&req, &rem));
5211 if (is_error(ret) && arg2) {
5212 host_to_target_timespec(arg2, &rem);
5215 break;
5216 #ifdef TARGET_NR_query_module
5217 case TARGET_NR_query_module:
5218 goto unimplemented;
5219 #endif
5220 #ifdef TARGET_NR_nfsservctl
5221 case TARGET_NR_nfsservctl:
5222 goto unimplemented;
5223 #endif
5224 case TARGET_NR_prctl:
5225 switch (arg1)
5227 case PR_GET_PDEATHSIG:
5229 int deathsig;
5230 ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
5231 if (!is_error(ret) && arg2
5232 && put_user_ual(deathsig, arg2))
5233 goto efault;
5235 break;
5236 default:
5237 ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
5238 break;
5240 break;
5241 #ifdef TARGET_NR_arch_prctl
5242 case TARGET_NR_arch_prctl:
5243 #if defined(TARGET_I386) && !defined(TARGET_ABI32)
5244 ret = do_arch_prctl(cpu_env, arg1, arg2);
5245 break;
5246 #else
5247 goto unimplemented;
5248 #endif
5249 #endif
5250 #ifdef TARGET_NR_pread
5251 case TARGET_NR_pread:
5252 #ifdef TARGET_ARM
5253 if (((CPUARMState *)cpu_env)->eabi)
5254 arg4 = arg5;
5255 #endif
5256 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5257 goto efault;
5258 ret = get_errno(pread(arg1, p, arg3, arg4));
5259 unlock_user(p, arg2, ret);
5260 break;
5261 case TARGET_NR_pwrite:
5262 #ifdef TARGET_ARM
5263 if (((CPUARMState *)cpu_env)->eabi)
5264 arg4 = arg5;
5265 #endif
5266 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5267 goto efault;
5268 ret = get_errno(pwrite(arg1, p, arg3, arg4));
5269 unlock_user(p, arg2, 0);
5270 break;
5271 #endif
5272 #ifdef TARGET_NR_pread64
5273 case TARGET_NR_pread64:
5274 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5275 goto efault;
5276 ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
5277 unlock_user(p, arg2, ret);
5278 break;
5279 case TARGET_NR_pwrite64:
5280 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5281 goto efault;
5282 ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
5283 unlock_user(p, arg2, 0);
5284 break;
5285 #endif
5286 case TARGET_NR_getcwd:
5287 if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
5288 goto efault;
5289 ret = get_errno(sys_getcwd1(p, arg2));
5290 unlock_user(p, arg1, ret);
5291 break;
5292 case TARGET_NR_capget:
5293 goto unimplemented;
5294 case TARGET_NR_capset:
5295 goto unimplemented;
5296 case TARGET_NR_sigaltstack:
5297 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
5298 defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA)
5299 ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env));
5300 break;
5301 #else
5302 goto unimplemented;
5303 #endif
5304 case TARGET_NR_sendfile:
5305 goto unimplemented;
5306 #ifdef TARGET_NR_getpmsg
5307 case TARGET_NR_getpmsg:
5308 goto unimplemented;
5309 #endif
5310 #ifdef TARGET_NR_putpmsg
5311 case TARGET_NR_putpmsg:
5312 goto unimplemented;
5313 #endif
5314 #ifdef TARGET_NR_vfork
5315 case TARGET_NR_vfork:
5316 ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
5317 0, 0, 0, 0));
5318 break;
5319 #endif
5320 #ifdef TARGET_NR_ugetrlimit
5321 case TARGET_NR_ugetrlimit:
5323 struct rlimit rlim;
5324 ret = get_errno(getrlimit(arg1, &rlim));
5325 if (!is_error(ret)) {
5326 struct target_rlimit *target_rlim;
5327 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
5328 goto efault;
5329 target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
5330 target_rlim->rlim_max = tswapl(rlim.rlim_max);
5331 unlock_user_struct(target_rlim, arg2, 1);
5333 break;
5335 #endif
5336 #ifdef TARGET_NR_truncate64
5337 case TARGET_NR_truncate64:
5338 if (!(p = lock_user_string(arg1)))
5339 goto efault;
5340 ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
5341 unlock_user(p, arg1, 0);
5342 break;
5343 #endif
5344 #ifdef TARGET_NR_ftruncate64
5345 case TARGET_NR_ftruncate64:
5346 ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
5347 break;
5348 #endif
5349 #ifdef TARGET_NR_stat64
5350 case TARGET_NR_stat64:
5351 if (!(p = lock_user_string(arg1)))
5352 goto efault;
5353 ret = get_errno(stat(path(p), &st));
5354 unlock_user(p, arg1, 0);
5355 if (!is_error(ret))
5356 ret = host_to_target_stat64(cpu_env, arg2, &st);
5357 break;
5358 #endif
5359 #ifdef TARGET_NR_lstat64
5360 case TARGET_NR_lstat64:
5361 if (!(p = lock_user_string(arg1)))
5362 goto efault;
5363 ret = get_errno(lstat(path(p), &st));
5364 unlock_user(p, arg1, 0);
5365 if (!is_error(ret))
5366 ret = host_to_target_stat64(cpu_env, arg2, &st);
5367 break;
5368 #endif
5369 #ifdef TARGET_NR_fstat64
5370 case TARGET_NR_fstat64:
5371 ret = get_errno(fstat(arg1, &st));
5372 if (!is_error(ret))
5373 ret = host_to_target_stat64(cpu_env, arg2, &st);
5374 break;
5375 #endif
5376 #if defined(TARGET_NR_fstatat64) && defined(__NR_fstatat64)
5377 case TARGET_NR_fstatat64:
5378 if (!(p = lock_user_string(arg2)))
5379 goto efault;
5380 ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
5381 if (!is_error(ret))
5382 ret = host_to_target_stat64(cpu_env, arg3, &st);
5383 break;
5384 #endif
5385 #ifdef USE_UID16
5386 case TARGET_NR_lchown:
5387 if (!(p = lock_user_string(arg1)))
5388 goto efault;
5389 ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
5390 unlock_user(p, arg1, 0);
5391 break;
5392 case TARGET_NR_getuid:
5393 ret = get_errno(high2lowuid(getuid()));
5394 break;
5395 case TARGET_NR_getgid:
5396 ret = get_errno(high2lowgid(getgid()));
5397 break;
5398 case TARGET_NR_geteuid:
5399 ret = get_errno(high2lowuid(geteuid()));
5400 break;
5401 case TARGET_NR_getegid:
5402 ret = get_errno(high2lowgid(getegid()));
5403 break;
5404 case TARGET_NR_setreuid:
5405 ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
5406 break;
5407 case TARGET_NR_setregid:
5408 ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
5409 break;
5410 case TARGET_NR_getgroups:
5412 int gidsetsize = arg1;
5413 uint16_t *target_grouplist;
5414 gid_t *grouplist;
5415 int i;
5417 grouplist = alloca(gidsetsize * sizeof(gid_t));
5418 ret = get_errno(getgroups(gidsetsize, grouplist));
5419 if (gidsetsize == 0)
5420 break;
5421 if (!is_error(ret)) {
5422 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
5423 if (!target_grouplist)
5424 goto efault;
5425 for(i = 0;i < ret; i++)
5426 target_grouplist[i] = tswap16(grouplist[i]);
5427 unlock_user(target_grouplist, arg2, gidsetsize * 2);
5430 break;
5431 case TARGET_NR_setgroups:
5433 int gidsetsize = arg1;
5434 uint16_t *target_grouplist;
5435 gid_t *grouplist;
5436 int i;
5438 grouplist = alloca(gidsetsize * sizeof(gid_t));
5439 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
5440 if (!target_grouplist) {
5441 ret = -TARGET_EFAULT;
5442 goto fail;
5444 for(i = 0;i < gidsetsize; i++)
5445 grouplist[i] = tswap16(target_grouplist[i]);
5446 unlock_user(target_grouplist, arg2, 0);
5447 ret = get_errno(setgroups(gidsetsize, grouplist));
5449 break;
5450 case TARGET_NR_fchown:
5451 ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
5452 break;
5453 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
5454 case TARGET_NR_fchownat:
5455 if (!(p = lock_user_string(arg2)))
5456 goto efault;
5457 ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
5458 unlock_user(p, arg2, 0);
5459 break;
5460 #endif
5461 #ifdef TARGET_NR_setresuid
5462 case TARGET_NR_setresuid:
5463 ret = get_errno(setresuid(low2highuid(arg1),
5464 low2highuid(arg2),
5465 low2highuid(arg3)));
5466 break;
5467 #endif
5468 #ifdef TARGET_NR_getresuid
5469 case TARGET_NR_getresuid:
5471 uid_t ruid, euid, suid;
5472 ret = get_errno(getresuid(&ruid, &euid, &suid));
5473 if (!is_error(ret)) {
5474 if (put_user_u16(high2lowuid(ruid), arg1)
5475 || put_user_u16(high2lowuid(euid), arg2)
5476 || put_user_u16(high2lowuid(suid), arg3))
5477 goto efault;
5480 break;
5481 #endif
5482 #ifdef TARGET_NR_getresgid
5483 case TARGET_NR_setresgid:
5484 ret = get_errno(setresgid(low2highgid(arg1),
5485 low2highgid(arg2),
5486 low2highgid(arg3)));
5487 break;
5488 #endif
5489 #ifdef TARGET_NR_getresgid
5490 case TARGET_NR_getresgid:
5492 gid_t rgid, egid, sgid;
5493 ret = get_errno(getresgid(&rgid, &egid, &sgid));
5494 if (!is_error(ret)) {
5495 if (put_user_u16(high2lowgid(rgid), arg1)
5496 || put_user_u16(high2lowgid(egid), arg2)
5497 || put_user_u16(high2lowgid(sgid), arg3))
5498 goto efault;
5501 break;
5502 #endif
5503 case TARGET_NR_chown:
5504 if (!(p = lock_user_string(arg1)))
5505 goto efault;
5506 ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
5507 unlock_user(p, arg1, 0);
5508 break;
5509 case TARGET_NR_setuid:
5510 ret = get_errno(setuid(low2highuid(arg1)));
5511 break;
5512 case TARGET_NR_setgid:
5513 ret = get_errno(setgid(low2highgid(arg1)));
5514 break;
5515 case TARGET_NR_setfsuid:
5516 ret = get_errno(setfsuid(arg1));
5517 break;
5518 case TARGET_NR_setfsgid:
5519 ret = get_errno(setfsgid(arg1));
5520 break;
5521 #endif /* USE_UID16 */
5523 #ifdef TARGET_NR_lchown32
5524 case TARGET_NR_lchown32:
5525 if (!(p = lock_user_string(arg1)))
5526 goto efault;
5527 ret = get_errno(lchown(p, arg2, arg3));
5528 unlock_user(p, arg1, 0);
5529 break;
5530 #endif
5531 #ifdef TARGET_NR_getuid32
5532 case TARGET_NR_getuid32:
5533 ret = get_errno(getuid());
5534 break;
5535 #endif
5537 #if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
5538 /* Alpha specific */
5539 case TARGET_NR_getxuid:
5541 uid_t euid;
5542 euid=geteuid();
5543 ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
5545 ret = get_errno(getuid());
5546 break;
5547 #endif
5548 #if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
5549 /* Alpha specific */
5550 case TARGET_NR_getxgid:
5552 uid_t egid;
5553 egid=getegid();
5554 ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
5556 ret = get_errno(getgid());
5557 break;
5558 #endif
5560 #ifdef TARGET_NR_getgid32
5561 case TARGET_NR_getgid32:
5562 ret = get_errno(getgid());
5563 break;
5564 #endif
5565 #ifdef TARGET_NR_geteuid32
5566 case TARGET_NR_geteuid32:
5567 ret = get_errno(geteuid());
5568 break;
5569 #endif
5570 #ifdef TARGET_NR_getegid32
5571 case TARGET_NR_getegid32:
5572 ret = get_errno(getegid());
5573 break;
5574 #endif
5575 #ifdef TARGET_NR_setreuid32
5576 case TARGET_NR_setreuid32:
5577 ret = get_errno(setreuid(arg1, arg2));
5578 break;
5579 #endif
5580 #ifdef TARGET_NR_setregid32
5581 case TARGET_NR_setregid32:
5582 ret = get_errno(setregid(arg1, arg2));
5583 break;
5584 #endif
5585 #ifdef TARGET_NR_getgroups32
5586 case TARGET_NR_getgroups32:
5588 int gidsetsize = arg1;
5589 uint32_t *target_grouplist;
5590 gid_t *grouplist;
5591 int i;
5593 grouplist = alloca(gidsetsize * sizeof(gid_t));
5594 ret = get_errno(getgroups(gidsetsize, grouplist));
5595 if (gidsetsize == 0)
5596 break;
5597 if (!is_error(ret)) {
5598 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
5599 if (!target_grouplist) {
5600 ret = -TARGET_EFAULT;
5601 goto fail;
5603 for(i = 0;i < ret; i++)
5604 target_grouplist[i] = tswap32(grouplist[i]);
5605 unlock_user(target_grouplist, arg2, gidsetsize * 4);
5608 break;
5609 #endif
5610 #ifdef TARGET_NR_setgroups32
5611 case TARGET_NR_setgroups32:
5613 int gidsetsize = arg1;
5614 uint32_t *target_grouplist;
5615 gid_t *grouplist;
5616 int i;
5618 grouplist = alloca(gidsetsize * sizeof(gid_t));
5619 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
5620 if (!target_grouplist) {
5621 ret = -TARGET_EFAULT;
5622 goto fail;
5624 for(i = 0;i < gidsetsize; i++)
5625 grouplist[i] = tswap32(target_grouplist[i]);
5626 unlock_user(target_grouplist, arg2, 0);
5627 ret = get_errno(setgroups(gidsetsize, grouplist));
5629 break;
5630 #endif
5631 #ifdef TARGET_NR_fchown32
5632 case TARGET_NR_fchown32:
5633 ret = get_errno(fchown(arg1, arg2, arg3));
5634 break;
5635 #endif
5636 #ifdef TARGET_NR_setresuid32
5637 case TARGET_NR_setresuid32:
5638 ret = get_errno(setresuid(arg1, arg2, arg3));
5639 break;
5640 #endif
5641 #ifdef TARGET_NR_getresuid32
5642 case TARGET_NR_getresuid32:
5644 uid_t ruid, euid, suid;
5645 ret = get_errno(getresuid(&ruid, &euid, &suid));
5646 if (!is_error(ret)) {
5647 if (put_user_u32(ruid, arg1)
5648 || put_user_u32(euid, arg2)
5649 || put_user_u32(suid, arg3))
5650 goto efault;
5653 break;
5654 #endif
5655 #ifdef TARGET_NR_setresgid32
5656 case TARGET_NR_setresgid32:
5657 ret = get_errno(setresgid(arg1, arg2, arg3));
5658 break;
5659 #endif
5660 #ifdef TARGET_NR_getresgid32
5661 case TARGET_NR_getresgid32:
5663 gid_t rgid, egid, sgid;
5664 ret = get_errno(getresgid(&rgid, &egid, &sgid));
5665 if (!is_error(ret)) {
5666 if (put_user_u32(rgid, arg1)
5667 || put_user_u32(egid, arg2)
5668 || put_user_u32(sgid, arg3))
5669 goto efault;
5672 break;
5673 #endif
5674 #ifdef TARGET_NR_chown32
5675 case TARGET_NR_chown32:
5676 if (!(p = lock_user_string(arg1)))
5677 goto efault;
5678 ret = get_errno(chown(p, arg2, arg3));
5679 unlock_user(p, arg1, 0);
5680 break;
5681 #endif
5682 #ifdef TARGET_NR_setuid32
5683 case TARGET_NR_setuid32:
5684 ret = get_errno(setuid(arg1));
5685 break;
5686 #endif
5687 #ifdef TARGET_NR_setgid32
5688 case TARGET_NR_setgid32:
5689 ret = get_errno(setgid(arg1));
5690 break;
5691 #endif
5692 #ifdef TARGET_NR_setfsuid32
5693 case TARGET_NR_setfsuid32:
5694 ret = get_errno(setfsuid(arg1));
5695 break;
5696 #endif
5697 #ifdef TARGET_NR_setfsgid32
5698 case TARGET_NR_setfsgid32:
5699 ret = get_errno(setfsgid(arg1));
5700 break;
5701 #endif
5703 case TARGET_NR_pivot_root:
5704 goto unimplemented;
5705 #ifdef TARGET_NR_mincore
5706 case TARGET_NR_mincore:
5708 void *a;
5709 ret = -TARGET_EFAULT;
5710 if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
5711 goto efault;
5712 if (!(p = lock_user_string(arg3)))
5713 goto mincore_fail;
5714 ret = get_errno(mincore(a, arg2, p));
5715 unlock_user(p, arg3, ret);
5716 mincore_fail:
5717 unlock_user(a, arg1, 0);
5719 break;
5720 #endif
5721 #ifdef TARGET_NR_arm_fadvise64_64
5722 case TARGET_NR_arm_fadvise64_64:
5725 * arm_fadvise64_64 looks like fadvise64_64 but
5726 * with different argument order
5728 abi_long temp;
5729 temp = arg3;
5730 arg3 = arg4;
5731 arg4 = temp;
5733 #endif
5734 #if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64)
5735 #ifdef TARGET_NR_fadvise64_64
5736 case TARGET_NR_fadvise64_64:
5737 #endif
5738 /* This is a hint, so ignoring and returning success is ok. */
5739 ret = get_errno(0);
5740 break;
5741 #endif
5742 #ifdef TARGET_NR_madvise
5743 case TARGET_NR_madvise:
5744 /* A straight passthrough may not be safe because qemu sometimes
5745 turns private flie-backed mappings into anonymous mappings.
5746 This will break MADV_DONTNEED.
5747 This is a hint, so ignoring and returning success is ok. */
5748 ret = get_errno(0);
5749 break;
5750 #endif
5751 #if TARGET_ABI_BITS == 32
5752 case TARGET_NR_fcntl64:
5754 int cmd;
5755 struct flock64 fl;
5756 struct target_flock64 *target_fl;
5757 #ifdef TARGET_ARM
5758 struct target_eabi_flock64 *target_efl;
5759 #endif
5761 switch(arg2){
5762 case TARGET_F_GETLK64:
5763 cmd = F_GETLK64;
5764 break;
5765 case TARGET_F_SETLK64:
5766 cmd = F_SETLK64;
5767 break;
5768 case TARGET_F_SETLKW64:
5769 cmd = F_SETLK64;
5770 break;
5771 default:
5772 cmd = arg2;
5773 break;
5776 switch(arg2) {
5777 case TARGET_F_GETLK64:
5778 #ifdef TARGET_ARM
5779 if (((CPUARMState *)cpu_env)->eabi) {
5780 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1))
5781 goto efault;
5782 fl.l_type = tswap16(target_efl->l_type);
5783 fl.l_whence = tswap16(target_efl->l_whence);
5784 fl.l_start = tswap64(target_efl->l_start);
5785 fl.l_len = tswap64(target_efl->l_len);
5786 fl.l_pid = tswapl(target_efl->l_pid);
5787 unlock_user_struct(target_efl, arg3, 0);
5788 } else
5789 #endif
5791 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1))
5792 goto efault;
5793 fl.l_type = tswap16(target_fl->l_type);
5794 fl.l_whence = tswap16(target_fl->l_whence);
5795 fl.l_start = tswap64(target_fl->l_start);
5796 fl.l_len = tswap64(target_fl->l_len);
5797 fl.l_pid = tswapl(target_fl->l_pid);
5798 unlock_user_struct(target_fl, arg3, 0);
5800 ret = get_errno(fcntl(arg1, cmd, &fl));
5801 if (ret == 0) {
5802 #ifdef TARGET_ARM
5803 if (((CPUARMState *)cpu_env)->eabi) {
5804 if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0))
5805 goto efault;
5806 target_efl->l_type = tswap16(fl.l_type);
5807 target_efl->l_whence = tswap16(fl.l_whence);
5808 target_efl->l_start = tswap64(fl.l_start);
5809 target_efl->l_len = tswap64(fl.l_len);
5810 target_efl->l_pid = tswapl(fl.l_pid);
5811 unlock_user_struct(target_efl, arg3, 1);
5812 } else
5813 #endif
5815 if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0))
5816 goto efault;
5817 target_fl->l_type = tswap16(fl.l_type);
5818 target_fl->l_whence = tswap16(fl.l_whence);
5819 target_fl->l_start = tswap64(fl.l_start);
5820 target_fl->l_len = tswap64(fl.l_len);
5821 target_fl->l_pid = tswapl(fl.l_pid);
5822 unlock_user_struct(target_fl, arg3, 1);
5825 break;
5827 case TARGET_F_SETLK64:
5828 case TARGET_F_SETLKW64:
5829 #ifdef TARGET_ARM
5830 if (((CPUARMState *)cpu_env)->eabi) {
5831 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1))
5832 goto efault;
5833 fl.l_type = tswap16(target_efl->l_type);
5834 fl.l_whence = tswap16(target_efl->l_whence);
5835 fl.l_start = tswap64(target_efl->l_start);
5836 fl.l_len = tswap64(target_efl->l_len);
5837 fl.l_pid = tswapl(target_efl->l_pid);
5838 unlock_user_struct(target_efl, arg3, 0);
5839 } else
5840 #endif
5842 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1))
5843 goto efault;
5844 fl.l_type = tswap16(target_fl->l_type);
5845 fl.l_whence = tswap16(target_fl->l_whence);
5846 fl.l_start = tswap64(target_fl->l_start);
5847 fl.l_len = tswap64(target_fl->l_len);
5848 fl.l_pid = tswapl(target_fl->l_pid);
5849 unlock_user_struct(target_fl, arg3, 0);
5851 ret = get_errno(fcntl(arg1, cmd, &fl));
5852 break;
5853 default:
5854 ret = do_fcntl(arg1, cmd, arg3);
5855 break;
5857 break;
5859 #endif
5860 #ifdef TARGET_NR_cacheflush
5861 case TARGET_NR_cacheflush:
5862 /* self-modifying code is handled automatically, so nothing needed */
5863 ret = 0;
5864 break;
5865 #endif
5866 #ifdef TARGET_NR_security
5867 case TARGET_NR_security:
5868 goto unimplemented;
5869 #endif
5870 #ifdef TARGET_NR_getpagesize
5871 case TARGET_NR_getpagesize:
5872 ret = TARGET_PAGE_SIZE;
5873 break;
5874 #endif
5875 case TARGET_NR_gettid:
5876 ret = get_errno(gettid());
5877 break;
5878 #ifdef TARGET_NR_readahead
5879 case TARGET_NR_readahead:
5880 #if TARGET_ABI_BITS == 32
5881 #ifdef TARGET_ARM
5882 if (((CPUARMState *)cpu_env)->eabi)
5884 arg2 = arg3;
5885 arg3 = arg4;
5886 arg4 = arg5;
5888 #endif
5889 ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
5890 #else
5891 ret = get_errno(readahead(arg1, arg2, arg3));
5892 #endif
5893 break;
5894 #endif
5895 #ifdef TARGET_NR_setxattr
5896 case TARGET_NR_setxattr:
5897 case TARGET_NR_lsetxattr:
5898 case TARGET_NR_fsetxattr:
5899 case TARGET_NR_getxattr:
5900 case TARGET_NR_lgetxattr:
5901 case TARGET_NR_fgetxattr:
5902 case TARGET_NR_listxattr:
5903 case TARGET_NR_llistxattr:
5904 case TARGET_NR_flistxattr:
5905 case TARGET_NR_removexattr:
5906 case TARGET_NR_lremovexattr:
5907 case TARGET_NR_fremovexattr:
5908 goto unimplemented_nowarn;
5909 #endif
5910 #ifdef TARGET_NR_set_thread_area
5911 case TARGET_NR_set_thread_area:
5912 #if defined(TARGET_MIPS)
5913 ((CPUMIPSState *) cpu_env)->tls_value = arg1;
5914 ret = 0;
5915 break;
5916 #elif defined(TARGET_I386) && defined(TARGET_ABI32)
5917 ret = do_set_thread_area(cpu_env, arg1);
5918 break;
5919 #else
5920 goto unimplemented_nowarn;
5921 #endif
5922 #endif
5923 #ifdef TARGET_NR_get_thread_area
5924 case TARGET_NR_get_thread_area:
5925 #if defined(TARGET_I386) && defined(TARGET_ABI32)
5926 ret = do_get_thread_area(cpu_env, arg1);
5927 #else
5928 goto unimplemented_nowarn;
5929 #endif
5930 #endif
5931 #ifdef TARGET_NR_getdomainname
5932 case TARGET_NR_getdomainname:
5933 goto unimplemented_nowarn;
5934 #endif
5936 #ifdef TARGET_NR_clock_gettime
5937 case TARGET_NR_clock_gettime:
5939 struct timespec ts;
5940 ret = get_errno(clock_gettime(arg1, &ts));
5941 if (!is_error(ret)) {
5942 host_to_target_timespec(arg2, &ts);
5944 break;
5946 #endif
5947 #ifdef TARGET_NR_clock_getres
5948 case TARGET_NR_clock_getres:
5950 struct timespec ts;
5951 ret = get_errno(clock_getres(arg1, &ts));
5952 if (!is_error(ret)) {
5953 host_to_target_timespec(arg2, &ts);
5955 break;
5957 #endif
5958 #ifdef TARGET_NR_clock_nanosleep
5959 case TARGET_NR_clock_nanosleep:
5961 struct timespec ts;
5962 target_to_host_timespec(&ts, arg3);
5963 ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
5964 if (arg4)
5965 host_to_target_timespec(arg4, &ts);
5966 break;
5968 #endif
5970 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
5971 case TARGET_NR_set_tid_address:
5972 ret = get_errno(set_tid_address((int *)g2h(arg1)));
5973 break;
5974 #endif
5976 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
5977 case TARGET_NR_tkill:
5978 ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
5979 break;
5980 #endif
5982 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
5983 case TARGET_NR_tgkill:
5984 ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
5985 target_to_host_signal(arg3)));
5986 break;
5987 #endif
5989 #ifdef TARGET_NR_set_robust_list
5990 case TARGET_NR_set_robust_list:
5991 goto unimplemented_nowarn;
5992 #endif
5994 #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
5995 case TARGET_NR_utimensat:
5997 struct timespec ts[2];
5998 target_to_host_timespec(ts, arg3);
5999 target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
6000 if (!arg2)
6001 ret = get_errno(sys_utimensat(arg1, NULL, ts, arg4));
6002 else {
6003 if (!(p = lock_user_string(arg2))) {
6004 ret = -TARGET_EFAULT;
6005 goto fail;
6007 ret = get_errno(sys_utimensat(arg1, path(p), ts, arg4));
6008 unlock_user(p, arg2, 0);
6011 break;
6012 #endif
6013 #if defined(USE_NPTL)
6014 case TARGET_NR_futex:
6015 ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
6016 break;
6017 #endif
6018 #ifdef TARGET_NR_inotify_init
6019 case TARGET_NR_inotify_init:
6020 ret = get_errno(sys_inotify_init());
6021 break;
6022 #endif
6023 #ifdef TARGET_NR_inotify_add_watch
6024 case TARGET_NR_inotify_add_watch:
6025 p = lock_user_string(arg2);
6026 ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
6027 unlock_user(p, arg2, 0);
6028 break;
6029 #endif
6030 #ifdef TARGET_NR_inotify_rm_watch
6031 case TARGET_NR_inotify_rm_watch:
6032 ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
6033 break;
6034 #endif
6036 default:
6037 unimplemented:
6038 gemu_log("qemu: Unsupported syscall: %d\n", num);
6039 #if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
6040 unimplemented_nowarn:
6041 #endif
6042 ret = -TARGET_ENOSYS;
6043 break;
6045 fail:
6046 #ifdef DEBUG
6047 gemu_log(" = %ld\n", ret);
6048 #endif
6049 if(do_strace)
6050 print_syscall_ret(num, ret);
6051 return ret;
6052 efault:
6053 ret = -TARGET_EFAULT;
6054 goto fail;