Sparc32: convert slavio interrupt controller to qdev
[qemu-kvm/fedora.git] / linux-user / syscall.c
blob000962328e5b8f216712649bd3e689c6e7aa35ca
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., 51 Franklin Street - Fifth Floor, Boston,
19 * MA 02110-1301, USA.
21 #define _ATFILE_SOURCE
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <stdarg.h>
25 #include <string.h>
26 #include <elf.h>
27 #include <endian.h>
28 #include <errno.h>
29 #include <unistd.h>
30 #include <fcntl.h>
31 #include <time.h>
32 #include <limits.h>
33 #include <mqueue.h>
34 #include <sys/types.h>
35 #include <sys/ipc.h>
36 #include <sys/msg.h>
37 #include <sys/wait.h>
38 #include <sys/time.h>
39 #include <sys/stat.h>
40 #include <sys/mount.h>
41 #include <sys/prctl.h>
42 #include <sys/resource.h>
43 #include <sys/mman.h>
44 #include <sys/swap.h>
45 #include <signal.h>
46 #include <sched.h>
47 #include <sys/socket.h>
48 #include <sys/un.h>
49 #include <sys/uio.h>
50 #include <sys/poll.h>
51 #include <sys/times.h>
52 #include <sys/shm.h>
53 #include <sys/sem.h>
54 #include <sys/statfs.h>
55 #include <utime.h>
56 #include <sys/sysinfo.h>
57 #include <sys/utsname.h>
58 //#include <sys/user.h>
59 #include <netinet/ip.h>
60 #include <netinet/tcp.h>
61 #include <qemu-common.h>
62 #ifdef HAVE_GPROF
63 #include <sys/gmon.h>
64 #endif
66 #define termios host_termios
67 #define winsize host_winsize
68 #define termio host_termio
69 #define sgttyb host_sgttyb /* same as target */
70 #define tchars host_tchars /* same as target */
71 #define ltchars host_ltchars /* same as target */
73 #include <linux/termios.h>
74 #include <linux/unistd.h>
75 #include <linux/utsname.h>
76 #include <linux/cdrom.h>
77 #include <linux/hdreg.h>
78 #include <linux/soundcard.h>
79 #include <linux/kd.h>
80 #include <linux/mtio.h>
81 #include <linux/fs.h>
82 #include "linux_loop.h"
84 #include "qemu.h"
85 #include "qemu-common.h"
87 #if defined(USE_NPTL)
88 #define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
89 CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
90 #else
91 /* XXX: Hardcode the above values. */
92 #define CLONE_NPTL_FLAGS2 0
93 #endif
95 //#define DEBUG
97 //#include <linux/msdos_fs.h>
98 #define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct linux_dirent [2])
99 #define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct linux_dirent [2])
102 #undef _syscall0
103 #undef _syscall1
104 #undef _syscall2
105 #undef _syscall3
106 #undef _syscall4
107 #undef _syscall5
108 #undef _syscall6
110 #define _syscall0(type,name) \
111 static type name (void) \
113 return syscall(__NR_##name); \
116 #define _syscall1(type,name,type1,arg1) \
117 static type name (type1 arg1) \
119 return syscall(__NR_##name, arg1); \
122 #define _syscall2(type,name,type1,arg1,type2,arg2) \
123 static type name (type1 arg1,type2 arg2) \
125 return syscall(__NR_##name, arg1, arg2); \
128 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
129 static type name (type1 arg1,type2 arg2,type3 arg3) \
131 return syscall(__NR_##name, arg1, arg2, arg3); \
134 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
135 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4) \
137 return syscall(__NR_##name, arg1, arg2, arg3, arg4); \
140 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
141 type5,arg5) \
142 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
144 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5); \
148 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
149 type5,arg5,type6,arg6) \
150 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \
151 type6 arg6) \
153 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6); \
157 #define __NR_sys_uname __NR_uname
158 #define __NR_sys_faccessat __NR_faccessat
159 #define __NR_sys_fchmodat __NR_fchmodat
160 #define __NR_sys_fchownat __NR_fchownat
161 #define __NR_sys_fstatat64 __NR_fstatat64
162 #define __NR_sys_futimesat __NR_futimesat
163 #define __NR_sys_getcwd1 __NR_getcwd
164 #define __NR_sys_getdents __NR_getdents
165 #define __NR_sys_getdents64 __NR_getdents64
166 #define __NR_sys_getpriority __NR_getpriority
167 #define __NR_sys_linkat __NR_linkat
168 #define __NR_sys_mkdirat __NR_mkdirat
169 #define __NR_sys_mknodat __NR_mknodat
170 #define __NR_sys_newfstatat __NR_newfstatat
171 #define __NR_sys_openat __NR_openat
172 #define __NR_sys_readlinkat __NR_readlinkat
173 #define __NR_sys_renameat __NR_renameat
174 #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
175 #define __NR_sys_symlinkat __NR_symlinkat
176 #define __NR_sys_syslog __NR_syslog
177 #define __NR_sys_tgkill __NR_tgkill
178 #define __NR_sys_tkill __NR_tkill
179 #define __NR_sys_unlinkat __NR_unlinkat
180 #define __NR_sys_utimensat __NR_utimensat
181 #define __NR_sys_futex __NR_futex
182 #define __NR_sys_inotify_init __NR_inotify_init
183 #define __NR_sys_inotify_add_watch __NR_inotify_add_watch
184 #define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
186 #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
187 #define __NR__llseek __NR_lseek
188 #endif
190 #ifdef __NR_gettid
191 _syscall0(int, gettid)
192 #else
193 /* This is a replacement for the host gettid() and must return a host
194 errno. */
195 static int gettid(void) {
196 return -ENOSYS;
198 #endif
199 #if TARGET_ABI_BITS == 32
200 _syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
201 #endif
202 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
203 _syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
204 #endif
205 _syscall2(int, sys_getpriority, int, which, int, who);
206 #if defined(TARGET_NR__llseek) && !defined (__x86_64__)
207 _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo,
208 loff_t *, res, uint, wh);
209 #endif
210 _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
211 _syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
212 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
213 _syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
214 #endif
215 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
216 _syscall2(int,sys_tkill,int,tid,int,sig)
217 #endif
218 #ifdef __NR_exit_group
219 _syscall1(int,exit_group,int,error_code)
220 #endif
221 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
222 _syscall1(int,set_tid_address,int *,tidptr)
223 #endif
224 #if defined(USE_NPTL)
225 #if defined(TARGET_NR_futex) && defined(__NR_futex)
226 _syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
227 const struct timespec *,timeout,int *,uaddr2,int,val3)
228 #endif
229 #endif
231 static bitmask_transtbl fcntl_flags_tbl[] = {
232 { TARGET_O_ACCMODE, TARGET_O_WRONLY, O_ACCMODE, O_WRONLY, },
233 { TARGET_O_ACCMODE, TARGET_O_RDWR, O_ACCMODE, O_RDWR, },
234 { TARGET_O_CREAT, TARGET_O_CREAT, O_CREAT, O_CREAT, },
235 { TARGET_O_EXCL, TARGET_O_EXCL, O_EXCL, O_EXCL, },
236 { TARGET_O_NOCTTY, TARGET_O_NOCTTY, O_NOCTTY, O_NOCTTY, },
237 { TARGET_O_TRUNC, TARGET_O_TRUNC, O_TRUNC, O_TRUNC, },
238 { TARGET_O_APPEND, TARGET_O_APPEND, O_APPEND, O_APPEND, },
239 { TARGET_O_NONBLOCK, TARGET_O_NONBLOCK, O_NONBLOCK, O_NONBLOCK, },
240 { TARGET_O_SYNC, TARGET_O_SYNC, O_SYNC, O_SYNC, },
241 { TARGET_FASYNC, TARGET_FASYNC, FASYNC, FASYNC, },
242 { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
243 { TARGET_O_NOFOLLOW, TARGET_O_NOFOLLOW, O_NOFOLLOW, O_NOFOLLOW, },
244 { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
245 #if defined(O_DIRECT)
246 { TARGET_O_DIRECT, TARGET_O_DIRECT, O_DIRECT, O_DIRECT, },
247 #endif
248 { 0, 0, 0, 0 }
251 #define COPY_UTSNAME_FIELD(dest, src) \
252 do { \
253 /* __NEW_UTS_LEN doesn't include terminating null */ \
254 (void) strncpy((dest), (src), __NEW_UTS_LEN); \
255 (dest)[__NEW_UTS_LEN] = '\0'; \
256 } while (0)
258 static int sys_uname(struct new_utsname *buf)
260 struct utsname uts_buf;
262 if (uname(&uts_buf) < 0)
263 return (-1);
266 * Just in case these have some differences, we
267 * translate utsname to new_utsname (which is the
268 * struct linux kernel uses).
271 bzero(buf, sizeof (*buf));
272 COPY_UTSNAME_FIELD(buf->sysname, uts_buf.sysname);
273 COPY_UTSNAME_FIELD(buf->nodename, uts_buf.nodename);
274 COPY_UTSNAME_FIELD(buf->release, uts_buf.release);
275 COPY_UTSNAME_FIELD(buf->version, uts_buf.version);
276 COPY_UTSNAME_FIELD(buf->machine, uts_buf.machine);
277 #ifdef _GNU_SOURCE
278 COPY_UTSNAME_FIELD(buf->domainname, uts_buf.domainname);
279 #endif
280 return (0);
282 #undef COPY_UTSNAME_FIELD
285 static int sys_getcwd1(char *buf, size_t size)
287 if (getcwd(buf, size) == NULL) {
288 /* getcwd() sets errno */
289 return (-1);
291 return strlen(buf)+1;
294 #ifdef CONFIG_ATFILE
296 * Host system seems to have atfile syscall stubs available. We
297 * now enable them one by one as specified by target syscall_nr.h.
300 #ifdef TARGET_NR_faccessat
301 static int sys_faccessat(int dirfd, const char *pathname, int mode)
303 return (faccessat(dirfd, pathname, mode, 0));
305 #endif
306 #ifdef TARGET_NR_fchmodat
307 static int sys_fchmodat(int dirfd, const char *pathname, mode_t mode)
309 return (fchmodat(dirfd, pathname, mode, 0));
311 #endif
312 #if defined(TARGET_NR_fchownat) && defined(USE_UID16)
313 static int sys_fchownat(int dirfd, const char *pathname, uid_t owner,
314 gid_t group, int flags)
316 return (fchownat(dirfd, pathname, owner, group, flags));
318 #endif
319 #ifdef __NR_fstatat64
320 static int sys_fstatat64(int dirfd, const char *pathname, struct stat *buf,
321 int flags)
323 return (fstatat(dirfd, pathname, buf, flags));
325 #endif
326 #ifdef __NR_newfstatat
327 static int sys_newfstatat(int dirfd, const char *pathname, struct stat *buf,
328 int flags)
330 return (fstatat(dirfd, pathname, buf, flags));
332 #endif
333 #ifdef TARGET_NR_futimesat
334 static int sys_futimesat(int dirfd, const char *pathname,
335 const struct timeval times[2])
337 return (futimesat(dirfd, pathname, times));
339 #endif
340 #ifdef TARGET_NR_linkat
341 static int sys_linkat(int olddirfd, const char *oldpath,
342 int newdirfd, const char *newpath, int flags)
344 return (linkat(olddirfd, oldpath, newdirfd, newpath, flags));
346 #endif
347 #ifdef TARGET_NR_mkdirat
348 static int sys_mkdirat(int dirfd, const char *pathname, mode_t mode)
350 return (mkdirat(dirfd, pathname, mode));
352 #endif
353 #ifdef TARGET_NR_mknodat
354 static int sys_mknodat(int dirfd, const char *pathname, mode_t mode,
355 dev_t dev)
357 return (mknodat(dirfd, pathname, mode, dev));
359 #endif
360 #ifdef TARGET_NR_openat
361 static int sys_openat(int dirfd, const char *pathname, int flags, ...)
364 * open(2) has extra parameter 'mode' when called with
365 * flag O_CREAT.
367 if ((flags & O_CREAT) != 0) {
368 va_list ap;
369 mode_t mode;
372 * Get the 'mode' parameter and translate it to
373 * host bits.
375 va_start(ap, flags);
376 mode = va_arg(ap, mode_t);
377 mode = target_to_host_bitmask(mode, fcntl_flags_tbl);
378 va_end(ap);
380 return (openat(dirfd, pathname, flags, mode));
382 return (openat(dirfd, pathname, flags));
384 #endif
385 #ifdef TARGET_NR_readlinkat
386 static int sys_readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz)
388 return (readlinkat(dirfd, pathname, buf, bufsiz));
390 #endif
391 #ifdef TARGET_NR_renameat
392 static int sys_renameat(int olddirfd, const char *oldpath,
393 int newdirfd, const char *newpath)
395 return (renameat(olddirfd, oldpath, newdirfd, newpath));
397 #endif
398 #ifdef TARGET_NR_symlinkat
399 static int sys_symlinkat(const char *oldpath, int newdirfd, const char *newpath)
401 return (symlinkat(oldpath, newdirfd, newpath));
403 #endif
404 #ifdef TARGET_NR_unlinkat
405 static int sys_unlinkat(int dirfd, const char *pathname, int flags)
407 return (unlinkat(dirfd, pathname, flags));
409 #endif
410 #else /* !CONFIG_ATFILE */
413 * Try direct syscalls instead
415 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
416 _syscall3(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode)
417 #endif
418 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
419 _syscall3(int,sys_fchmodat,int,dirfd,const char *,pathname, mode_t,mode)
420 #endif
421 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) && defined(USE_UID16)
422 _syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
423 uid_t,owner,gid_t,group,int,flags)
424 #endif
425 #if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
426 defined(__NR_fstatat64)
427 _syscall4(int,sys_fstatat64,int,dirfd,const char *,pathname,
428 struct stat *,buf,int,flags)
429 #endif
430 #if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
431 _syscall3(int,sys_futimesat,int,dirfd,const char *,pathname,
432 const struct timeval *,times)
433 #endif
434 #if (defined(TARGET_NR_newfstatat) || defined(TARGET_NR_fstatat64) ) && \
435 defined(__NR_newfstatat)
436 _syscall4(int,sys_newfstatat,int,dirfd,const char *,pathname,
437 struct stat *,buf,int,flags)
438 #endif
439 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
440 _syscall5(int,sys_linkat,int,olddirfd,const char *,oldpath,
441 int,newdirfd,const char *,newpath,int,flags)
442 #endif
443 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
444 _syscall3(int,sys_mkdirat,int,dirfd,const char *,pathname,mode_t,mode)
445 #endif
446 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
447 _syscall4(int,sys_mknodat,int,dirfd,const char *,pathname,
448 mode_t,mode,dev_t,dev)
449 #endif
450 #if defined(TARGET_NR_openat) && defined(__NR_openat)
451 _syscall4(int,sys_openat,int,dirfd,const char *,pathname,int,flags,mode_t,mode)
452 #endif
453 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
454 _syscall4(int,sys_readlinkat,int,dirfd,const char *,pathname,
455 char *,buf,size_t,bufsize)
456 #endif
457 #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
458 _syscall4(int,sys_renameat,int,olddirfd,const char *,oldpath,
459 int,newdirfd,const char *,newpath)
460 #endif
461 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
462 _syscall3(int,sys_symlinkat,const char *,oldpath,
463 int,newdirfd,const char *,newpath)
464 #endif
465 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
466 _syscall3(int,sys_unlinkat,int,dirfd,const char *,pathname,int,flags)
467 #endif
469 #endif /* CONFIG_ATFILE */
471 #ifdef CONFIG_UTIMENSAT
472 static int sys_utimensat(int dirfd, const char *pathname,
473 const struct timespec times[2], int flags)
475 if (pathname == NULL)
476 return futimens(dirfd, times);
477 else
478 return utimensat(dirfd, pathname, times, flags);
480 #else
481 #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
482 _syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
483 const struct timespec *,tsp,int,flags)
484 #endif
485 #endif /* CONFIG_UTIMENSAT */
487 #ifdef CONFIG_INOTIFY
488 #include <sys/inotify.h>
490 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
491 static int sys_inotify_init(void)
493 return (inotify_init());
495 #endif
496 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
497 static int sys_inotify_add_watch(int fd,const char *pathname, int32_t mask)
499 return (inotify_add_watch(fd, pathname, mask));
501 #endif
502 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
503 static int sys_inotify_rm_watch(int fd, int32_t wd)
505 return (inotify_rm_watch(fd, wd));
507 #endif
508 #else
509 /* Userspace can usually survive runtime without inotify */
510 #undef TARGET_NR_inotify_init
511 #undef TARGET_NR_inotify_add_watch
512 #undef TARGET_NR_inotify_rm_watch
513 #endif /* CONFIG_INOTIFY */
516 extern int personality(int);
517 extern int flock(int, int);
518 extern int setfsuid(int);
519 extern int setfsgid(int);
520 extern int setgroups(int, gid_t *);
522 #define ERRNO_TABLE_SIZE 1200
524 /* target_to_host_errno_table[] is initialized from
525 * host_to_target_errno_table[] in syscall_init(). */
526 static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
530 * This list is the union of errno values overridden in asm-<arch>/errno.h
531 * minus the errnos that are not actually generic to all archs.
533 static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
534 [EIDRM] = TARGET_EIDRM,
535 [ECHRNG] = TARGET_ECHRNG,
536 [EL2NSYNC] = TARGET_EL2NSYNC,
537 [EL3HLT] = TARGET_EL3HLT,
538 [EL3RST] = TARGET_EL3RST,
539 [ELNRNG] = TARGET_ELNRNG,
540 [EUNATCH] = TARGET_EUNATCH,
541 [ENOCSI] = TARGET_ENOCSI,
542 [EL2HLT] = TARGET_EL2HLT,
543 [EDEADLK] = TARGET_EDEADLK,
544 [ENOLCK] = TARGET_ENOLCK,
545 [EBADE] = TARGET_EBADE,
546 [EBADR] = TARGET_EBADR,
547 [EXFULL] = TARGET_EXFULL,
548 [ENOANO] = TARGET_ENOANO,
549 [EBADRQC] = TARGET_EBADRQC,
550 [EBADSLT] = TARGET_EBADSLT,
551 [EBFONT] = TARGET_EBFONT,
552 [ENOSTR] = TARGET_ENOSTR,
553 [ENODATA] = TARGET_ENODATA,
554 [ETIME] = TARGET_ETIME,
555 [ENOSR] = TARGET_ENOSR,
556 [ENONET] = TARGET_ENONET,
557 [ENOPKG] = TARGET_ENOPKG,
558 [EREMOTE] = TARGET_EREMOTE,
559 [ENOLINK] = TARGET_ENOLINK,
560 [EADV] = TARGET_EADV,
561 [ESRMNT] = TARGET_ESRMNT,
562 [ECOMM] = TARGET_ECOMM,
563 [EPROTO] = TARGET_EPROTO,
564 [EDOTDOT] = TARGET_EDOTDOT,
565 [EMULTIHOP] = TARGET_EMULTIHOP,
566 [EBADMSG] = TARGET_EBADMSG,
567 [ENAMETOOLONG] = TARGET_ENAMETOOLONG,
568 [EOVERFLOW] = TARGET_EOVERFLOW,
569 [ENOTUNIQ] = TARGET_ENOTUNIQ,
570 [EBADFD] = TARGET_EBADFD,
571 [EREMCHG] = TARGET_EREMCHG,
572 [ELIBACC] = TARGET_ELIBACC,
573 [ELIBBAD] = TARGET_ELIBBAD,
574 [ELIBSCN] = TARGET_ELIBSCN,
575 [ELIBMAX] = TARGET_ELIBMAX,
576 [ELIBEXEC] = TARGET_ELIBEXEC,
577 [EILSEQ] = TARGET_EILSEQ,
578 [ENOSYS] = TARGET_ENOSYS,
579 [ELOOP] = TARGET_ELOOP,
580 [ERESTART] = TARGET_ERESTART,
581 [ESTRPIPE] = TARGET_ESTRPIPE,
582 [ENOTEMPTY] = TARGET_ENOTEMPTY,
583 [EUSERS] = TARGET_EUSERS,
584 [ENOTSOCK] = TARGET_ENOTSOCK,
585 [EDESTADDRREQ] = TARGET_EDESTADDRREQ,
586 [EMSGSIZE] = TARGET_EMSGSIZE,
587 [EPROTOTYPE] = TARGET_EPROTOTYPE,
588 [ENOPROTOOPT] = TARGET_ENOPROTOOPT,
589 [EPROTONOSUPPORT] = TARGET_EPROTONOSUPPORT,
590 [ESOCKTNOSUPPORT] = TARGET_ESOCKTNOSUPPORT,
591 [EOPNOTSUPP] = TARGET_EOPNOTSUPP,
592 [EPFNOSUPPORT] = TARGET_EPFNOSUPPORT,
593 [EAFNOSUPPORT] = TARGET_EAFNOSUPPORT,
594 [EADDRINUSE] = TARGET_EADDRINUSE,
595 [EADDRNOTAVAIL] = TARGET_EADDRNOTAVAIL,
596 [ENETDOWN] = TARGET_ENETDOWN,
597 [ENETUNREACH] = TARGET_ENETUNREACH,
598 [ENETRESET] = TARGET_ENETRESET,
599 [ECONNABORTED] = TARGET_ECONNABORTED,
600 [ECONNRESET] = TARGET_ECONNRESET,
601 [ENOBUFS] = TARGET_ENOBUFS,
602 [EISCONN] = TARGET_EISCONN,
603 [ENOTCONN] = TARGET_ENOTCONN,
604 [EUCLEAN] = TARGET_EUCLEAN,
605 [ENOTNAM] = TARGET_ENOTNAM,
606 [ENAVAIL] = TARGET_ENAVAIL,
607 [EISNAM] = TARGET_EISNAM,
608 [EREMOTEIO] = TARGET_EREMOTEIO,
609 [ESHUTDOWN] = TARGET_ESHUTDOWN,
610 [ETOOMANYREFS] = TARGET_ETOOMANYREFS,
611 [ETIMEDOUT] = TARGET_ETIMEDOUT,
612 [ECONNREFUSED] = TARGET_ECONNREFUSED,
613 [EHOSTDOWN] = TARGET_EHOSTDOWN,
614 [EHOSTUNREACH] = TARGET_EHOSTUNREACH,
615 [EALREADY] = TARGET_EALREADY,
616 [EINPROGRESS] = TARGET_EINPROGRESS,
617 [ESTALE] = TARGET_ESTALE,
618 [ECANCELED] = TARGET_ECANCELED,
619 [ENOMEDIUM] = TARGET_ENOMEDIUM,
620 [EMEDIUMTYPE] = TARGET_EMEDIUMTYPE,
621 #ifdef ENOKEY
622 [ENOKEY] = TARGET_ENOKEY,
623 #endif
624 #ifdef EKEYEXPIRED
625 [EKEYEXPIRED] = TARGET_EKEYEXPIRED,
626 #endif
627 #ifdef EKEYREVOKED
628 [EKEYREVOKED] = TARGET_EKEYREVOKED,
629 #endif
630 #ifdef EKEYREJECTED
631 [EKEYREJECTED] = TARGET_EKEYREJECTED,
632 #endif
633 #ifdef EOWNERDEAD
634 [EOWNERDEAD] = TARGET_EOWNERDEAD,
635 #endif
636 #ifdef ENOTRECOVERABLE
637 [ENOTRECOVERABLE] = TARGET_ENOTRECOVERABLE,
638 #endif
641 static inline int host_to_target_errno(int err)
643 if(host_to_target_errno_table[err])
644 return host_to_target_errno_table[err];
645 return err;
648 static inline int target_to_host_errno(int err)
650 if (target_to_host_errno_table[err])
651 return target_to_host_errno_table[err];
652 return err;
655 static inline abi_long get_errno(abi_long ret)
657 if (ret == -1)
658 return -host_to_target_errno(errno);
659 else
660 return ret;
663 static inline int is_error(abi_long ret)
665 return (abi_ulong)ret >= (abi_ulong)(-4096);
668 char *target_strerror(int err)
670 return strerror(target_to_host_errno(err));
673 static abi_ulong target_brk;
674 static abi_ulong target_original_brk;
676 void target_set_brk(abi_ulong new_brk)
678 target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
681 /* do_brk() must return target values and target errnos. */
682 abi_long do_brk(abi_ulong new_brk)
684 abi_ulong brk_page;
685 abi_long mapped_addr;
686 int new_alloc_size;
688 if (!new_brk)
689 return target_brk;
690 if (new_brk < target_original_brk)
691 return target_brk;
693 brk_page = HOST_PAGE_ALIGN(target_brk);
695 /* If the new brk is less than this, set it and we're done... */
696 if (new_brk < brk_page) {
697 target_brk = new_brk;
698 return target_brk;
701 /* We need to allocate more memory after the brk... */
702 new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
703 mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
704 PROT_READ|PROT_WRITE,
705 MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
707 if (!is_error(mapped_addr))
708 target_brk = new_brk;
710 return target_brk;
713 static inline abi_long copy_from_user_fdset(fd_set *fds,
714 abi_ulong target_fds_addr,
715 int n)
717 int i, nw, j, k;
718 abi_ulong b, *target_fds;
720 nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
721 if (!(target_fds = lock_user(VERIFY_READ,
722 target_fds_addr,
723 sizeof(abi_ulong) * nw,
724 1)))
725 return -TARGET_EFAULT;
727 FD_ZERO(fds);
728 k = 0;
729 for (i = 0; i < nw; i++) {
730 /* grab the abi_ulong */
731 __get_user(b, &target_fds[i]);
732 for (j = 0; j < TARGET_ABI_BITS; j++) {
733 /* check the bit inside the abi_ulong */
734 if ((b >> j) & 1)
735 FD_SET(k, fds);
736 k++;
740 unlock_user(target_fds, target_fds_addr, 0);
742 return 0;
745 static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
746 const fd_set *fds,
747 int n)
749 int i, nw, j, k;
750 abi_long v;
751 abi_ulong *target_fds;
753 nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
754 if (!(target_fds = lock_user(VERIFY_WRITE,
755 target_fds_addr,
756 sizeof(abi_ulong) * nw,
757 0)))
758 return -TARGET_EFAULT;
760 k = 0;
761 for (i = 0; i < nw; i++) {
762 v = 0;
763 for (j = 0; j < TARGET_ABI_BITS; j++) {
764 v |= ((FD_ISSET(k, fds) != 0) << j);
765 k++;
767 __put_user(v, &target_fds[i]);
770 unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
772 return 0;
775 #if defined(__alpha__)
776 #define HOST_HZ 1024
777 #else
778 #define HOST_HZ 100
779 #endif
781 static inline abi_long host_to_target_clock_t(long ticks)
783 #if HOST_HZ == TARGET_HZ
784 return ticks;
785 #else
786 return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
787 #endif
790 static inline abi_long host_to_target_rusage(abi_ulong target_addr,
791 const struct rusage *rusage)
793 struct target_rusage *target_rusage;
795 if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
796 return -TARGET_EFAULT;
797 target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
798 target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
799 target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
800 target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec);
801 target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss);
802 target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss);
803 target_rusage->ru_idrss = tswapl(rusage->ru_idrss);
804 target_rusage->ru_isrss = tswapl(rusage->ru_isrss);
805 target_rusage->ru_minflt = tswapl(rusage->ru_minflt);
806 target_rusage->ru_majflt = tswapl(rusage->ru_majflt);
807 target_rusage->ru_nswap = tswapl(rusage->ru_nswap);
808 target_rusage->ru_inblock = tswapl(rusage->ru_inblock);
809 target_rusage->ru_oublock = tswapl(rusage->ru_oublock);
810 target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd);
811 target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv);
812 target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);
813 target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
814 target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
815 unlock_user_struct(target_rusage, target_addr, 1);
817 return 0;
820 static inline abi_long copy_from_user_timeval(struct timeval *tv,
821 abi_ulong target_tv_addr)
823 struct target_timeval *target_tv;
825 if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
826 return -TARGET_EFAULT;
828 __get_user(tv->tv_sec, &target_tv->tv_sec);
829 __get_user(tv->tv_usec, &target_tv->tv_usec);
831 unlock_user_struct(target_tv, target_tv_addr, 0);
833 return 0;
836 static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
837 const struct timeval *tv)
839 struct target_timeval *target_tv;
841 if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
842 return -TARGET_EFAULT;
844 __put_user(tv->tv_sec, &target_tv->tv_sec);
845 __put_user(tv->tv_usec, &target_tv->tv_usec);
847 unlock_user_struct(target_tv, target_tv_addr, 1);
849 return 0;
852 static inline abi_long copy_from_user_mq_attr(struct mq_attr *attr,
853 abi_ulong target_mq_attr_addr)
855 struct target_mq_attr *target_mq_attr;
857 if (!lock_user_struct(VERIFY_READ, target_mq_attr,
858 target_mq_attr_addr, 1))
859 return -TARGET_EFAULT;
861 __get_user(attr->mq_flags, &target_mq_attr->mq_flags);
862 __get_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
863 __get_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
864 __get_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
866 unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0);
868 return 0;
871 static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr,
872 const struct mq_attr *attr)
874 struct target_mq_attr *target_mq_attr;
876 if (!lock_user_struct(VERIFY_WRITE, target_mq_attr,
877 target_mq_attr_addr, 0))
878 return -TARGET_EFAULT;
880 __put_user(attr->mq_flags, &target_mq_attr->mq_flags);
881 __put_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
882 __put_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
883 __put_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
885 unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1);
887 return 0;
890 /* do_select() must return target values and target errnos. */
891 static abi_long do_select(int n,
892 abi_ulong rfd_addr, abi_ulong wfd_addr,
893 abi_ulong efd_addr, abi_ulong target_tv_addr)
895 fd_set rfds, wfds, efds;
896 fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
897 struct timeval tv, *tv_ptr;
898 abi_long ret;
900 if (rfd_addr) {
901 if (copy_from_user_fdset(&rfds, rfd_addr, n))
902 return -TARGET_EFAULT;
903 rfds_ptr = &rfds;
904 } else {
905 rfds_ptr = NULL;
907 if (wfd_addr) {
908 if (copy_from_user_fdset(&wfds, wfd_addr, n))
909 return -TARGET_EFAULT;
910 wfds_ptr = &wfds;
911 } else {
912 wfds_ptr = NULL;
914 if (efd_addr) {
915 if (copy_from_user_fdset(&efds, efd_addr, n))
916 return -TARGET_EFAULT;
917 efds_ptr = &efds;
918 } else {
919 efds_ptr = NULL;
922 if (target_tv_addr) {
923 if (copy_from_user_timeval(&tv, target_tv_addr))
924 return -TARGET_EFAULT;
925 tv_ptr = &tv;
926 } else {
927 tv_ptr = NULL;
930 ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
932 if (!is_error(ret)) {
933 if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
934 return -TARGET_EFAULT;
935 if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
936 return -TARGET_EFAULT;
937 if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
938 return -TARGET_EFAULT;
940 if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
941 return -TARGET_EFAULT;
944 return ret;
947 static abi_long do_pipe2(int host_pipe[], int flags)
949 #ifdef CONFIG_PIPE2
950 return pipe2(host_pipe, flags);
951 #else
952 return -ENOSYS;
953 #endif
956 static abi_long do_pipe(void *cpu_env, abi_ulong pipedes, int flags)
958 int host_pipe[2];
959 abi_long ret;
960 ret = flags ? do_pipe2(host_pipe, flags) : pipe(host_pipe);
962 if (is_error(ret))
963 return get_errno(ret);
964 #if defined(TARGET_MIPS)
965 ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1];
966 ret = host_pipe[0];
967 #elif defined(TARGET_SH4)
968 ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
969 ret = host_pipe[0];
970 #else
971 if (put_user_s32(host_pipe[0], pipedes)
972 || put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0])))
973 return -TARGET_EFAULT;
974 #endif
975 return get_errno(ret);
978 static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn,
979 abi_ulong target_addr,
980 socklen_t len)
982 struct target_ip_mreqn *target_smreqn;
984 target_smreqn = lock_user(VERIFY_READ, target_addr, len, 1);
985 if (!target_smreqn)
986 return -TARGET_EFAULT;
987 mreqn->imr_multiaddr.s_addr = target_smreqn->imr_multiaddr.s_addr;
988 mreqn->imr_address.s_addr = target_smreqn->imr_address.s_addr;
989 if (len == sizeof(struct target_ip_mreqn))
990 mreqn->imr_ifindex = tswapl(target_smreqn->imr_ifindex);
991 unlock_user(target_smreqn, target_addr, 0);
993 return 0;
996 static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
997 abi_ulong target_addr,
998 socklen_t len)
1000 const socklen_t unix_maxlen = sizeof (struct sockaddr_un);
1001 sa_family_t sa_family;
1002 struct target_sockaddr *target_saddr;
1004 target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
1005 if (!target_saddr)
1006 return -TARGET_EFAULT;
1008 sa_family = tswap16(target_saddr->sa_family);
1010 /* Oops. The caller might send a incomplete sun_path; sun_path
1011 * must be terminated by \0 (see the manual page), but
1012 * unfortunately it is quite common to specify sockaddr_un
1013 * length as "strlen(x->sun_path)" while it should be
1014 * "strlen(...) + 1". We'll fix that here if needed.
1015 * Linux kernel has a similar feature.
1018 if (sa_family == AF_UNIX) {
1019 if (len < unix_maxlen && len > 0) {
1020 char *cp = (char*)target_saddr;
1022 if ( cp[len-1] && !cp[len] )
1023 len++;
1025 if (len > unix_maxlen)
1026 len = unix_maxlen;
1029 memcpy(addr, target_saddr, len);
1030 addr->sa_family = sa_family;
1031 unlock_user(target_saddr, target_addr, 0);
1033 return 0;
1036 static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
1037 struct sockaddr *addr,
1038 socklen_t len)
1040 struct target_sockaddr *target_saddr;
1042 target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
1043 if (!target_saddr)
1044 return -TARGET_EFAULT;
1045 memcpy(target_saddr, addr, len);
1046 target_saddr->sa_family = tswap16(addr->sa_family);
1047 unlock_user(target_saddr, target_addr, len);
1049 return 0;
1052 /* ??? Should this also swap msgh->name? */
1053 static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
1054 struct target_msghdr *target_msgh)
1056 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1057 abi_long msg_controllen;
1058 abi_ulong target_cmsg_addr;
1059 struct target_cmsghdr *target_cmsg;
1060 socklen_t space = 0;
1062 msg_controllen = tswapl(target_msgh->msg_controllen);
1063 if (msg_controllen < sizeof (struct target_cmsghdr))
1064 goto the_end;
1065 target_cmsg_addr = tswapl(target_msgh->msg_control);
1066 target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
1067 if (!target_cmsg)
1068 return -TARGET_EFAULT;
1070 while (cmsg && target_cmsg) {
1071 void *data = CMSG_DATA(cmsg);
1072 void *target_data = TARGET_CMSG_DATA(target_cmsg);
1074 int len = tswapl(target_cmsg->cmsg_len)
1075 - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
1077 space += CMSG_SPACE(len);
1078 if (space > msgh->msg_controllen) {
1079 space -= CMSG_SPACE(len);
1080 gemu_log("Host cmsg overflow\n");
1081 break;
1084 cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
1085 cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
1086 cmsg->cmsg_len = CMSG_LEN(len);
1088 if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1089 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1090 memcpy(data, target_data, len);
1091 } else {
1092 int *fd = (int *)data;
1093 int *target_fd = (int *)target_data;
1094 int i, numfds = len / sizeof(int);
1096 for (i = 0; i < numfds; i++)
1097 fd[i] = tswap32(target_fd[i]);
1100 cmsg = CMSG_NXTHDR(msgh, cmsg);
1101 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1103 unlock_user(target_cmsg, target_cmsg_addr, 0);
1104 the_end:
1105 msgh->msg_controllen = space;
1106 return 0;
1109 /* ??? Should this also swap msgh->name? */
1110 static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
1111 struct msghdr *msgh)
1113 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1114 abi_long msg_controllen;
1115 abi_ulong target_cmsg_addr;
1116 struct target_cmsghdr *target_cmsg;
1117 socklen_t space = 0;
1119 msg_controllen = tswapl(target_msgh->msg_controllen);
1120 if (msg_controllen < sizeof (struct target_cmsghdr))
1121 goto the_end;
1122 target_cmsg_addr = tswapl(target_msgh->msg_control);
1123 target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
1124 if (!target_cmsg)
1125 return -TARGET_EFAULT;
1127 while (cmsg && target_cmsg) {
1128 void *data = CMSG_DATA(cmsg);
1129 void *target_data = TARGET_CMSG_DATA(target_cmsg);
1131 int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
1133 space += TARGET_CMSG_SPACE(len);
1134 if (space > msg_controllen) {
1135 space -= TARGET_CMSG_SPACE(len);
1136 gemu_log("Target cmsg overflow\n");
1137 break;
1140 target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
1141 target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
1142 target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
1144 if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1145 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1146 memcpy(target_data, data, len);
1147 } else {
1148 int *fd = (int *)data;
1149 int *target_fd = (int *)target_data;
1150 int i, numfds = len / sizeof(int);
1152 for (i = 0; i < numfds; i++)
1153 target_fd[i] = tswap32(fd[i]);
1156 cmsg = CMSG_NXTHDR(msgh, cmsg);
1157 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1159 unlock_user(target_cmsg, target_cmsg_addr, space);
1160 the_end:
1161 target_msgh->msg_controllen = tswapl(space);
1162 return 0;
1165 /* do_setsockopt() Must return target values and target errnos. */
1166 static abi_long do_setsockopt(int sockfd, int level, int optname,
1167 abi_ulong optval_addr, socklen_t optlen)
1169 abi_long ret;
1170 int val;
1171 struct ip_mreqn *ip_mreq;
1172 struct ip_mreq_source *ip_mreq_source;
1174 switch(level) {
1175 case SOL_TCP:
1176 /* TCP options all take an 'int' value. */
1177 if (optlen < sizeof(uint32_t))
1178 return -TARGET_EINVAL;
1180 if (get_user_u32(val, optval_addr))
1181 return -TARGET_EFAULT;
1182 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1183 break;
1184 case SOL_IP:
1185 switch(optname) {
1186 case IP_TOS:
1187 case IP_TTL:
1188 case IP_HDRINCL:
1189 case IP_ROUTER_ALERT:
1190 case IP_RECVOPTS:
1191 case IP_RETOPTS:
1192 case IP_PKTINFO:
1193 case IP_MTU_DISCOVER:
1194 case IP_RECVERR:
1195 case IP_RECVTOS:
1196 #ifdef IP_FREEBIND
1197 case IP_FREEBIND:
1198 #endif
1199 case IP_MULTICAST_TTL:
1200 case IP_MULTICAST_LOOP:
1201 val = 0;
1202 if (optlen >= sizeof(uint32_t)) {
1203 if (get_user_u32(val, optval_addr))
1204 return -TARGET_EFAULT;
1205 } else if (optlen >= 1) {
1206 if (get_user_u8(val, optval_addr))
1207 return -TARGET_EFAULT;
1209 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1210 break;
1211 case IP_ADD_MEMBERSHIP:
1212 case IP_DROP_MEMBERSHIP:
1213 if (optlen < sizeof (struct target_ip_mreq) ||
1214 optlen > sizeof (struct target_ip_mreqn))
1215 return -TARGET_EINVAL;
1217 ip_mreq = (struct ip_mreqn *) alloca(optlen);
1218 target_to_host_ip_mreq(ip_mreq, optval_addr, optlen);
1219 ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq, optlen));
1220 break;
1222 case IP_BLOCK_SOURCE:
1223 case IP_UNBLOCK_SOURCE:
1224 case IP_ADD_SOURCE_MEMBERSHIP:
1225 case IP_DROP_SOURCE_MEMBERSHIP:
1226 if (optlen != sizeof (struct target_ip_mreq_source))
1227 return -TARGET_EINVAL;
1229 ip_mreq_source = lock_user(VERIFY_READ, optval_addr, optlen, 1);
1230 ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq_source, optlen));
1231 unlock_user (ip_mreq_source, optval_addr, 0);
1232 break;
1234 default:
1235 goto unimplemented;
1237 break;
1238 case TARGET_SOL_SOCKET:
1239 switch (optname) {
1240 /* Options with 'int' argument. */
1241 case TARGET_SO_DEBUG:
1242 optname = SO_DEBUG;
1243 break;
1244 case TARGET_SO_REUSEADDR:
1245 optname = SO_REUSEADDR;
1246 break;
1247 case TARGET_SO_TYPE:
1248 optname = SO_TYPE;
1249 break;
1250 case TARGET_SO_ERROR:
1251 optname = SO_ERROR;
1252 break;
1253 case TARGET_SO_DONTROUTE:
1254 optname = SO_DONTROUTE;
1255 break;
1256 case TARGET_SO_BROADCAST:
1257 optname = SO_BROADCAST;
1258 break;
1259 case TARGET_SO_SNDBUF:
1260 optname = SO_SNDBUF;
1261 break;
1262 case TARGET_SO_RCVBUF:
1263 optname = SO_RCVBUF;
1264 break;
1265 case TARGET_SO_KEEPALIVE:
1266 optname = SO_KEEPALIVE;
1267 break;
1268 case TARGET_SO_OOBINLINE:
1269 optname = SO_OOBINLINE;
1270 break;
1271 case TARGET_SO_NO_CHECK:
1272 optname = SO_NO_CHECK;
1273 break;
1274 case TARGET_SO_PRIORITY:
1275 optname = SO_PRIORITY;
1276 break;
1277 #ifdef SO_BSDCOMPAT
1278 case TARGET_SO_BSDCOMPAT:
1279 optname = SO_BSDCOMPAT;
1280 break;
1281 #endif
1282 case TARGET_SO_PASSCRED:
1283 optname = SO_PASSCRED;
1284 break;
1285 case TARGET_SO_TIMESTAMP:
1286 optname = SO_TIMESTAMP;
1287 break;
1288 case TARGET_SO_RCVLOWAT:
1289 optname = SO_RCVLOWAT;
1290 break;
1291 case TARGET_SO_RCVTIMEO:
1292 optname = SO_RCVTIMEO;
1293 break;
1294 case TARGET_SO_SNDTIMEO:
1295 optname = SO_SNDTIMEO;
1296 break;
1297 break;
1298 default:
1299 goto unimplemented;
1301 if (optlen < sizeof(uint32_t))
1302 return -TARGET_EINVAL;
1304 if (get_user_u32(val, optval_addr))
1305 return -TARGET_EFAULT;
1306 ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
1307 break;
1308 default:
1309 unimplemented:
1310 gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
1311 ret = -TARGET_ENOPROTOOPT;
1313 return ret;
1316 /* do_getsockopt() Must return target values and target errnos. */
1317 static abi_long do_getsockopt(int sockfd, int level, int optname,
1318 abi_ulong optval_addr, abi_ulong optlen)
1320 abi_long ret;
1321 int len, val;
1322 socklen_t lv;
1324 switch(level) {
1325 case TARGET_SOL_SOCKET:
1326 level = SOL_SOCKET;
1327 switch (optname) {
1328 case TARGET_SO_LINGER:
1329 case TARGET_SO_RCVTIMEO:
1330 case TARGET_SO_SNDTIMEO:
1331 case TARGET_SO_PEERCRED:
1332 case TARGET_SO_PEERNAME:
1333 /* These don't just return a single integer */
1334 goto unimplemented;
1335 default:
1336 goto int_case;
1338 break;
1339 case SOL_TCP:
1340 /* TCP options all take an 'int' value. */
1341 int_case:
1342 if (get_user_u32(len, optlen))
1343 return -TARGET_EFAULT;
1344 if (len < 0)
1345 return -TARGET_EINVAL;
1346 lv = sizeof(int);
1347 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1348 if (ret < 0)
1349 return ret;
1350 if (len > lv)
1351 len = lv;
1352 if (len == 4) {
1353 if (put_user_u32(val, optval_addr))
1354 return -TARGET_EFAULT;
1355 } else {
1356 if (put_user_u8(val, optval_addr))
1357 return -TARGET_EFAULT;
1359 if (put_user_u32(len, optlen))
1360 return -TARGET_EFAULT;
1361 break;
1362 case SOL_IP:
1363 switch(optname) {
1364 case IP_TOS:
1365 case IP_TTL:
1366 case IP_HDRINCL:
1367 case IP_ROUTER_ALERT:
1368 case IP_RECVOPTS:
1369 case IP_RETOPTS:
1370 case IP_PKTINFO:
1371 case IP_MTU_DISCOVER:
1372 case IP_RECVERR:
1373 case IP_RECVTOS:
1374 #ifdef IP_FREEBIND
1375 case IP_FREEBIND:
1376 #endif
1377 case IP_MULTICAST_TTL:
1378 case IP_MULTICAST_LOOP:
1379 if (get_user_u32(len, optlen))
1380 return -TARGET_EFAULT;
1381 if (len < 0)
1382 return -TARGET_EINVAL;
1383 lv = sizeof(int);
1384 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1385 if (ret < 0)
1386 return ret;
1387 if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
1388 len = 1;
1389 if (put_user_u32(len, optlen)
1390 || put_user_u8(val, optval_addr))
1391 return -TARGET_EFAULT;
1392 } else {
1393 if (len > sizeof(int))
1394 len = sizeof(int);
1395 if (put_user_u32(len, optlen)
1396 || put_user_u32(val, optval_addr))
1397 return -TARGET_EFAULT;
1399 break;
1400 default:
1401 ret = -TARGET_ENOPROTOOPT;
1402 break;
1404 break;
1405 default:
1406 unimplemented:
1407 gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1408 level, optname);
1409 ret = -TARGET_EOPNOTSUPP;
1410 break;
1412 return ret;
1415 /* FIXME
1416 * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1417 * other lock functions have a return code of 0 for failure.
1419 static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1420 int count, int copy)
1422 struct target_iovec *target_vec;
1423 abi_ulong base;
1424 int i;
1426 target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1427 if (!target_vec)
1428 return -TARGET_EFAULT;
1429 for(i = 0;i < count; i++) {
1430 base = tswapl(target_vec[i].iov_base);
1431 vec[i].iov_len = tswapl(target_vec[i].iov_len);
1432 if (vec[i].iov_len != 0) {
1433 vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
1434 /* Don't check lock_user return value. We must call writev even
1435 if a element has invalid base address. */
1436 } else {
1437 /* zero length pointer is ignored */
1438 vec[i].iov_base = NULL;
1441 unlock_user (target_vec, target_addr, 0);
1442 return 0;
1445 static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1446 int count, int copy)
1448 struct target_iovec *target_vec;
1449 abi_ulong base;
1450 int i;
1452 target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1453 if (!target_vec)
1454 return -TARGET_EFAULT;
1455 for(i = 0;i < count; i++) {
1456 if (target_vec[i].iov_base) {
1457 base = tswapl(target_vec[i].iov_base);
1458 unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1461 unlock_user (target_vec, target_addr, 0);
1463 return 0;
1466 /* do_socket() Must return target values and target errnos. */
1467 static abi_long do_socket(int domain, int type, int protocol)
1469 #if defined(TARGET_MIPS)
1470 switch(type) {
1471 case TARGET_SOCK_DGRAM:
1472 type = SOCK_DGRAM;
1473 break;
1474 case TARGET_SOCK_STREAM:
1475 type = SOCK_STREAM;
1476 break;
1477 case TARGET_SOCK_RAW:
1478 type = SOCK_RAW;
1479 break;
1480 case TARGET_SOCK_RDM:
1481 type = SOCK_RDM;
1482 break;
1483 case TARGET_SOCK_SEQPACKET:
1484 type = SOCK_SEQPACKET;
1485 break;
1486 case TARGET_SOCK_PACKET:
1487 type = SOCK_PACKET;
1488 break;
1490 #endif
1491 if (domain == PF_NETLINK)
1492 return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1493 return get_errno(socket(domain, type, protocol));
1496 /* do_bind() Must return target values and target errnos. */
1497 static abi_long do_bind(int sockfd, abi_ulong target_addr,
1498 socklen_t addrlen)
1500 void *addr;
1501 abi_long ret;
1503 if (addrlen < 0)
1504 return -TARGET_EINVAL;
1506 addr = alloca(addrlen+1);
1508 ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1509 if (ret)
1510 return ret;
1512 return get_errno(bind(sockfd, addr, addrlen));
1515 /* do_connect() Must return target values and target errnos. */
1516 static abi_long do_connect(int sockfd, abi_ulong target_addr,
1517 socklen_t addrlen)
1519 void *addr;
1520 abi_long ret;
1522 if (addrlen < 0)
1523 return -TARGET_EINVAL;
1525 addr = alloca(addrlen);
1527 ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1528 if (ret)
1529 return ret;
1531 return get_errno(connect(sockfd, addr, addrlen));
1534 /* do_sendrecvmsg() Must return target values and target errnos. */
1535 static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1536 int flags, int send)
1538 abi_long ret, len;
1539 struct target_msghdr *msgp;
1540 struct msghdr msg;
1541 int count;
1542 struct iovec *vec;
1543 abi_ulong target_vec;
1545 /* FIXME */
1546 if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1547 msgp,
1548 target_msg,
1549 send ? 1 : 0))
1550 return -TARGET_EFAULT;
1551 if (msgp->msg_name) {
1552 msg.msg_namelen = tswap32(msgp->msg_namelen);
1553 msg.msg_name = alloca(msg.msg_namelen);
1554 ret = target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
1555 msg.msg_namelen);
1556 if (ret) {
1557 unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1558 return ret;
1560 } else {
1561 msg.msg_name = NULL;
1562 msg.msg_namelen = 0;
1564 msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
1565 msg.msg_control = alloca(msg.msg_controllen);
1566 msg.msg_flags = tswap32(msgp->msg_flags);
1568 count = tswapl(msgp->msg_iovlen);
1569 vec = alloca(count * sizeof(struct iovec));
1570 target_vec = tswapl(msgp->msg_iov);
1571 lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1572 msg.msg_iovlen = count;
1573 msg.msg_iov = vec;
1575 if (send) {
1576 ret = target_to_host_cmsg(&msg, msgp);
1577 if (ret == 0)
1578 ret = get_errno(sendmsg(fd, &msg, flags));
1579 } else {
1580 ret = get_errno(recvmsg(fd, &msg, flags));
1581 if (!is_error(ret)) {
1582 len = ret;
1583 ret = host_to_target_cmsg(msgp, &msg);
1584 if (!is_error(ret))
1585 ret = len;
1588 unlock_iovec(vec, target_vec, count, !send);
1589 unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1590 return ret;
1593 /* do_accept() Must return target values and target errnos. */
1594 static abi_long do_accept(int fd, abi_ulong target_addr,
1595 abi_ulong target_addrlen_addr)
1597 socklen_t addrlen;
1598 void *addr;
1599 abi_long ret;
1601 if (target_addr == 0)
1602 return get_errno(accept(fd, NULL, NULL));
1604 /* linux returns EINVAL if addrlen pointer is invalid */
1605 if (get_user_u32(addrlen, target_addrlen_addr))
1606 return -TARGET_EINVAL;
1608 if (addrlen < 0)
1609 return -TARGET_EINVAL;
1611 if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1612 return -TARGET_EINVAL;
1614 addr = alloca(addrlen);
1616 ret = get_errno(accept(fd, addr, &addrlen));
1617 if (!is_error(ret)) {
1618 host_to_target_sockaddr(target_addr, addr, addrlen);
1619 if (put_user_u32(addrlen, target_addrlen_addr))
1620 ret = -TARGET_EFAULT;
1622 return ret;
1625 /* do_getpeername() Must return target values and target errnos. */
1626 static abi_long do_getpeername(int fd, abi_ulong target_addr,
1627 abi_ulong target_addrlen_addr)
1629 socklen_t addrlen;
1630 void *addr;
1631 abi_long ret;
1633 if (get_user_u32(addrlen, target_addrlen_addr))
1634 return -TARGET_EFAULT;
1636 if (addrlen < 0)
1637 return -TARGET_EINVAL;
1639 if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1640 return -TARGET_EFAULT;
1642 addr = alloca(addrlen);
1644 ret = get_errno(getpeername(fd, addr, &addrlen));
1645 if (!is_error(ret)) {
1646 host_to_target_sockaddr(target_addr, addr, addrlen);
1647 if (put_user_u32(addrlen, target_addrlen_addr))
1648 ret = -TARGET_EFAULT;
1650 return ret;
1653 /* do_getsockname() Must return target values and target errnos. */
1654 static abi_long do_getsockname(int fd, abi_ulong target_addr,
1655 abi_ulong target_addrlen_addr)
1657 socklen_t addrlen;
1658 void *addr;
1659 abi_long ret;
1661 if (get_user_u32(addrlen, target_addrlen_addr))
1662 return -TARGET_EFAULT;
1664 if (addrlen < 0)
1665 return -TARGET_EINVAL;
1667 if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1668 return -TARGET_EFAULT;
1670 addr = alloca(addrlen);
1672 ret = get_errno(getsockname(fd, addr, &addrlen));
1673 if (!is_error(ret)) {
1674 host_to_target_sockaddr(target_addr, addr, addrlen);
1675 if (put_user_u32(addrlen, target_addrlen_addr))
1676 ret = -TARGET_EFAULT;
1678 return ret;
1681 /* do_socketpair() Must return target values and target errnos. */
1682 static abi_long do_socketpair(int domain, int type, int protocol,
1683 abi_ulong target_tab_addr)
1685 int tab[2];
1686 abi_long ret;
1688 ret = get_errno(socketpair(domain, type, protocol, tab));
1689 if (!is_error(ret)) {
1690 if (put_user_s32(tab[0], target_tab_addr)
1691 || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1692 ret = -TARGET_EFAULT;
1694 return ret;
1697 /* do_sendto() Must return target values and target errnos. */
1698 static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
1699 abi_ulong target_addr, socklen_t addrlen)
1701 void *addr;
1702 void *host_msg;
1703 abi_long ret;
1705 if (addrlen < 0)
1706 return -TARGET_EINVAL;
1708 host_msg = lock_user(VERIFY_READ, msg, len, 1);
1709 if (!host_msg)
1710 return -TARGET_EFAULT;
1711 if (target_addr) {
1712 addr = alloca(addrlen);
1713 ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1714 if (ret) {
1715 unlock_user(host_msg, msg, 0);
1716 return ret;
1718 ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
1719 } else {
1720 ret = get_errno(send(fd, host_msg, len, flags));
1722 unlock_user(host_msg, msg, 0);
1723 return ret;
1726 /* do_recvfrom() Must return target values and target errnos. */
1727 static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
1728 abi_ulong target_addr,
1729 abi_ulong target_addrlen)
1731 socklen_t addrlen;
1732 void *addr;
1733 void *host_msg;
1734 abi_long ret;
1736 host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
1737 if (!host_msg)
1738 return -TARGET_EFAULT;
1739 if (target_addr) {
1740 if (get_user_u32(addrlen, target_addrlen)) {
1741 ret = -TARGET_EFAULT;
1742 goto fail;
1744 if (addrlen < 0) {
1745 ret = -TARGET_EINVAL;
1746 goto fail;
1748 addr = alloca(addrlen);
1749 ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
1750 } else {
1751 addr = NULL; /* To keep compiler quiet. */
1752 ret = get_errno(recv(fd, host_msg, len, flags));
1754 if (!is_error(ret)) {
1755 if (target_addr) {
1756 host_to_target_sockaddr(target_addr, addr, addrlen);
1757 if (put_user_u32(addrlen, target_addrlen)) {
1758 ret = -TARGET_EFAULT;
1759 goto fail;
1762 unlock_user(host_msg, msg, len);
1763 } else {
1764 fail:
1765 unlock_user(host_msg, msg, 0);
1767 return ret;
1770 #ifdef TARGET_NR_socketcall
1771 /* do_socketcall() Must return target values and target errnos. */
1772 static abi_long do_socketcall(int num, abi_ulong vptr)
1774 abi_long ret;
1775 const int n = sizeof(abi_ulong);
1777 switch(num) {
1778 case SOCKOP_socket:
1780 abi_ulong domain, type, protocol;
1782 if (get_user_ual(domain, vptr)
1783 || get_user_ual(type, vptr + n)
1784 || get_user_ual(protocol, vptr + 2 * n))
1785 return -TARGET_EFAULT;
1787 ret = do_socket(domain, type, protocol);
1789 break;
1790 case SOCKOP_bind:
1792 abi_ulong sockfd;
1793 abi_ulong target_addr;
1794 socklen_t addrlen;
1796 if (get_user_ual(sockfd, vptr)
1797 || get_user_ual(target_addr, vptr + n)
1798 || get_user_ual(addrlen, vptr + 2 * n))
1799 return -TARGET_EFAULT;
1801 ret = do_bind(sockfd, target_addr, addrlen);
1803 break;
1804 case SOCKOP_connect:
1806 abi_ulong sockfd;
1807 abi_ulong target_addr;
1808 socklen_t addrlen;
1810 if (get_user_ual(sockfd, vptr)
1811 || get_user_ual(target_addr, vptr + n)
1812 || get_user_ual(addrlen, vptr + 2 * n))
1813 return -TARGET_EFAULT;
1815 ret = do_connect(sockfd, target_addr, addrlen);
1817 break;
1818 case SOCKOP_listen:
1820 abi_ulong sockfd, backlog;
1822 if (get_user_ual(sockfd, vptr)
1823 || get_user_ual(backlog, vptr + n))
1824 return -TARGET_EFAULT;
1826 ret = get_errno(listen(sockfd, backlog));
1828 break;
1829 case SOCKOP_accept:
1831 abi_ulong sockfd;
1832 abi_ulong target_addr, target_addrlen;
1834 if (get_user_ual(sockfd, vptr)
1835 || get_user_ual(target_addr, vptr + n)
1836 || get_user_ual(target_addrlen, vptr + 2 * n))
1837 return -TARGET_EFAULT;
1839 ret = do_accept(sockfd, target_addr, target_addrlen);
1841 break;
1842 case SOCKOP_getsockname:
1844 abi_ulong sockfd;
1845 abi_ulong target_addr, target_addrlen;
1847 if (get_user_ual(sockfd, vptr)
1848 || get_user_ual(target_addr, vptr + n)
1849 || get_user_ual(target_addrlen, vptr + 2 * n))
1850 return -TARGET_EFAULT;
1852 ret = do_getsockname(sockfd, target_addr, target_addrlen);
1854 break;
1855 case SOCKOP_getpeername:
1857 abi_ulong sockfd;
1858 abi_ulong target_addr, target_addrlen;
1860 if (get_user_ual(sockfd, vptr)
1861 || get_user_ual(target_addr, vptr + n)
1862 || get_user_ual(target_addrlen, vptr + 2 * n))
1863 return -TARGET_EFAULT;
1865 ret = do_getpeername(sockfd, target_addr, target_addrlen);
1867 break;
1868 case SOCKOP_socketpair:
1870 abi_ulong domain, type, protocol;
1871 abi_ulong tab;
1873 if (get_user_ual(domain, vptr)
1874 || get_user_ual(type, vptr + n)
1875 || get_user_ual(protocol, vptr + 2 * n)
1876 || get_user_ual(tab, vptr + 3 * n))
1877 return -TARGET_EFAULT;
1879 ret = do_socketpair(domain, type, protocol, tab);
1881 break;
1882 case SOCKOP_send:
1884 abi_ulong sockfd;
1885 abi_ulong msg;
1886 size_t len;
1887 abi_ulong flags;
1889 if (get_user_ual(sockfd, vptr)
1890 || get_user_ual(msg, vptr + n)
1891 || get_user_ual(len, vptr + 2 * n)
1892 || get_user_ual(flags, vptr + 3 * n))
1893 return -TARGET_EFAULT;
1895 ret = do_sendto(sockfd, msg, len, flags, 0, 0);
1897 break;
1898 case SOCKOP_recv:
1900 abi_ulong sockfd;
1901 abi_ulong msg;
1902 size_t len;
1903 abi_ulong flags;
1905 if (get_user_ual(sockfd, vptr)
1906 || get_user_ual(msg, vptr + n)
1907 || get_user_ual(len, vptr + 2 * n)
1908 || get_user_ual(flags, vptr + 3 * n))
1909 return -TARGET_EFAULT;
1911 ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
1913 break;
1914 case SOCKOP_sendto:
1916 abi_ulong sockfd;
1917 abi_ulong msg;
1918 size_t len;
1919 abi_ulong flags;
1920 abi_ulong addr;
1921 socklen_t addrlen;
1923 if (get_user_ual(sockfd, vptr)
1924 || get_user_ual(msg, vptr + n)
1925 || get_user_ual(len, vptr + 2 * n)
1926 || get_user_ual(flags, vptr + 3 * n)
1927 || get_user_ual(addr, vptr + 4 * n)
1928 || get_user_ual(addrlen, vptr + 5 * n))
1929 return -TARGET_EFAULT;
1931 ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
1933 break;
1934 case SOCKOP_recvfrom:
1936 abi_ulong sockfd;
1937 abi_ulong msg;
1938 size_t len;
1939 abi_ulong flags;
1940 abi_ulong addr;
1941 socklen_t addrlen;
1943 if (get_user_ual(sockfd, vptr)
1944 || get_user_ual(msg, vptr + n)
1945 || get_user_ual(len, vptr + 2 * n)
1946 || get_user_ual(flags, vptr + 3 * n)
1947 || get_user_ual(addr, vptr + 4 * n)
1948 || get_user_ual(addrlen, vptr + 5 * n))
1949 return -TARGET_EFAULT;
1951 ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
1953 break;
1954 case SOCKOP_shutdown:
1956 abi_ulong sockfd, how;
1958 if (get_user_ual(sockfd, vptr)
1959 || get_user_ual(how, vptr + n))
1960 return -TARGET_EFAULT;
1962 ret = get_errno(shutdown(sockfd, how));
1964 break;
1965 case SOCKOP_sendmsg:
1966 case SOCKOP_recvmsg:
1968 abi_ulong fd;
1969 abi_ulong target_msg;
1970 abi_ulong flags;
1972 if (get_user_ual(fd, vptr)
1973 || get_user_ual(target_msg, vptr + n)
1974 || get_user_ual(flags, vptr + 2 * n))
1975 return -TARGET_EFAULT;
1977 ret = do_sendrecvmsg(fd, target_msg, flags,
1978 (num == SOCKOP_sendmsg));
1980 break;
1981 case SOCKOP_setsockopt:
1983 abi_ulong sockfd;
1984 abi_ulong level;
1985 abi_ulong optname;
1986 abi_ulong optval;
1987 socklen_t optlen;
1989 if (get_user_ual(sockfd, vptr)
1990 || get_user_ual(level, vptr + n)
1991 || get_user_ual(optname, vptr + 2 * n)
1992 || get_user_ual(optval, vptr + 3 * n)
1993 || get_user_ual(optlen, vptr + 4 * n))
1994 return -TARGET_EFAULT;
1996 ret = do_setsockopt(sockfd, level, optname, optval, optlen);
1998 break;
1999 case SOCKOP_getsockopt:
2001 abi_ulong sockfd;
2002 abi_ulong level;
2003 abi_ulong optname;
2004 abi_ulong optval;
2005 socklen_t optlen;
2007 if (get_user_ual(sockfd, vptr)
2008 || get_user_ual(level, vptr + n)
2009 || get_user_ual(optname, vptr + 2 * n)
2010 || get_user_ual(optval, vptr + 3 * n)
2011 || get_user_ual(optlen, vptr + 4 * n))
2012 return -TARGET_EFAULT;
2014 ret = do_getsockopt(sockfd, level, optname, optval, optlen);
2016 break;
2017 default:
2018 gemu_log("Unsupported socketcall: %d\n", num);
2019 ret = -TARGET_ENOSYS;
2020 break;
2022 return ret;
2024 #endif
2026 #define N_SHM_REGIONS 32
2028 static struct shm_region {
2029 abi_ulong start;
2030 abi_ulong size;
2031 } shm_regions[N_SHM_REGIONS];
2033 struct target_ipc_perm
2035 abi_long __key;
2036 abi_ulong uid;
2037 abi_ulong gid;
2038 abi_ulong cuid;
2039 abi_ulong cgid;
2040 unsigned short int mode;
2041 unsigned short int __pad1;
2042 unsigned short int __seq;
2043 unsigned short int __pad2;
2044 abi_ulong __unused1;
2045 abi_ulong __unused2;
2048 struct target_semid_ds
2050 struct target_ipc_perm sem_perm;
2051 abi_ulong sem_otime;
2052 abi_ulong __unused1;
2053 abi_ulong sem_ctime;
2054 abi_ulong __unused2;
2055 abi_ulong sem_nsems;
2056 abi_ulong __unused3;
2057 abi_ulong __unused4;
2060 static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
2061 abi_ulong target_addr)
2063 struct target_ipc_perm *target_ip;
2064 struct target_semid_ds *target_sd;
2066 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2067 return -TARGET_EFAULT;
2068 target_ip=&(target_sd->sem_perm);
2069 host_ip->__key = tswapl(target_ip->__key);
2070 host_ip->uid = tswapl(target_ip->uid);
2071 host_ip->gid = tswapl(target_ip->gid);
2072 host_ip->cuid = tswapl(target_ip->cuid);
2073 host_ip->cgid = tswapl(target_ip->cgid);
2074 host_ip->mode = tswapl(target_ip->mode);
2075 unlock_user_struct(target_sd, target_addr, 0);
2076 return 0;
2079 static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
2080 struct ipc_perm *host_ip)
2082 struct target_ipc_perm *target_ip;
2083 struct target_semid_ds *target_sd;
2085 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2086 return -TARGET_EFAULT;
2087 target_ip = &(target_sd->sem_perm);
2088 target_ip->__key = tswapl(host_ip->__key);
2089 target_ip->uid = tswapl(host_ip->uid);
2090 target_ip->gid = tswapl(host_ip->gid);
2091 target_ip->cuid = tswapl(host_ip->cuid);
2092 target_ip->cgid = tswapl(host_ip->cgid);
2093 target_ip->mode = tswapl(host_ip->mode);
2094 unlock_user_struct(target_sd, target_addr, 1);
2095 return 0;
2098 static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
2099 abi_ulong target_addr)
2101 struct target_semid_ds *target_sd;
2103 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2104 return -TARGET_EFAULT;
2105 if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr))
2106 return -TARGET_EFAULT;
2107 host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
2108 host_sd->sem_otime = tswapl(target_sd->sem_otime);
2109 host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
2110 unlock_user_struct(target_sd, target_addr, 0);
2111 return 0;
2114 static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
2115 struct semid_ds *host_sd)
2117 struct target_semid_ds *target_sd;
2119 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2120 return -TARGET_EFAULT;
2121 if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
2122 return -TARGET_EFAULT;;
2123 target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
2124 target_sd->sem_otime = tswapl(host_sd->sem_otime);
2125 target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
2126 unlock_user_struct(target_sd, target_addr, 1);
2127 return 0;
2130 struct target_seminfo {
2131 int semmap;
2132 int semmni;
2133 int semmns;
2134 int semmnu;
2135 int semmsl;
2136 int semopm;
2137 int semume;
2138 int semusz;
2139 int semvmx;
2140 int semaem;
2143 static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
2144 struct seminfo *host_seminfo)
2146 struct target_seminfo *target_seminfo;
2147 if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
2148 return -TARGET_EFAULT;
2149 __put_user(host_seminfo->semmap, &target_seminfo->semmap);
2150 __put_user(host_seminfo->semmni, &target_seminfo->semmni);
2151 __put_user(host_seminfo->semmns, &target_seminfo->semmns);
2152 __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
2153 __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
2154 __put_user(host_seminfo->semopm, &target_seminfo->semopm);
2155 __put_user(host_seminfo->semume, &target_seminfo->semume);
2156 __put_user(host_seminfo->semusz, &target_seminfo->semusz);
2157 __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
2158 __put_user(host_seminfo->semaem, &target_seminfo->semaem);
2159 unlock_user_struct(target_seminfo, target_addr, 1);
2160 return 0;
2163 union semun {
2164 int val;
2165 struct semid_ds *buf;
2166 unsigned short *array;
2167 struct seminfo *__buf;
2170 union target_semun {
2171 int val;
2172 abi_ulong buf;
2173 abi_ulong array;
2174 abi_ulong __buf;
2177 static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
2178 abi_ulong target_addr)
2180 int nsems;
2181 unsigned short *array;
2182 union semun semun;
2183 struct semid_ds semid_ds;
2184 int i, ret;
2186 semun.buf = &semid_ds;
2188 ret = semctl(semid, 0, IPC_STAT, semun);
2189 if (ret == -1)
2190 return get_errno(ret);
2192 nsems = semid_ds.sem_nsems;
2194 *host_array = malloc(nsems*sizeof(unsigned short));
2195 array = lock_user(VERIFY_READ, target_addr,
2196 nsems*sizeof(unsigned short), 1);
2197 if (!array)
2198 return -TARGET_EFAULT;
2200 for(i=0; i<nsems; i++) {
2201 __get_user((*host_array)[i], &array[i]);
2203 unlock_user(array, target_addr, 0);
2205 return 0;
2208 static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
2209 unsigned short **host_array)
2211 int nsems;
2212 unsigned short *array;
2213 union semun semun;
2214 struct semid_ds semid_ds;
2215 int i, ret;
2217 semun.buf = &semid_ds;
2219 ret = semctl(semid, 0, IPC_STAT, semun);
2220 if (ret == -1)
2221 return get_errno(ret);
2223 nsems = semid_ds.sem_nsems;
2225 array = lock_user(VERIFY_WRITE, target_addr,
2226 nsems*sizeof(unsigned short), 0);
2227 if (!array)
2228 return -TARGET_EFAULT;
2230 for(i=0; i<nsems; i++) {
2231 __put_user((*host_array)[i], &array[i]);
2233 free(*host_array);
2234 unlock_user(array, target_addr, 1);
2236 return 0;
2239 static inline abi_long do_semctl(int semid, int semnum, int cmd,
2240 union target_semun target_su)
2242 union semun arg;
2243 struct semid_ds dsarg;
2244 unsigned short *array = NULL;
2245 struct seminfo seminfo;
2246 abi_long ret = -TARGET_EINVAL;
2247 abi_long err;
2248 cmd &= 0xff;
2250 switch( cmd ) {
2251 case GETVAL:
2252 case SETVAL:
2253 arg.val = tswapl(target_su.val);
2254 ret = get_errno(semctl(semid, semnum, cmd, arg));
2255 target_su.val = tswapl(arg.val);
2256 break;
2257 case GETALL:
2258 case SETALL:
2259 err = target_to_host_semarray(semid, &array, target_su.array);
2260 if (err)
2261 return err;
2262 arg.array = array;
2263 ret = get_errno(semctl(semid, semnum, cmd, arg));
2264 err = host_to_target_semarray(semid, target_su.array, &array);
2265 if (err)
2266 return err;
2267 break;
2268 case IPC_STAT:
2269 case IPC_SET:
2270 case SEM_STAT:
2271 err = target_to_host_semid_ds(&dsarg, target_su.buf);
2272 if (err)
2273 return err;
2274 arg.buf = &dsarg;
2275 ret = get_errno(semctl(semid, semnum, cmd, arg));
2276 err = host_to_target_semid_ds(target_su.buf, &dsarg);
2277 if (err)
2278 return err;
2279 break;
2280 case IPC_INFO:
2281 case SEM_INFO:
2282 arg.__buf = &seminfo;
2283 ret = get_errno(semctl(semid, semnum, cmd, arg));
2284 err = host_to_target_seminfo(target_su.__buf, &seminfo);
2285 if (err)
2286 return err;
2287 break;
2288 case IPC_RMID:
2289 case GETPID:
2290 case GETNCNT:
2291 case GETZCNT:
2292 ret = get_errno(semctl(semid, semnum, cmd, NULL));
2293 break;
2296 return ret;
2299 struct target_sembuf {
2300 unsigned short sem_num;
2301 short sem_op;
2302 short sem_flg;
2305 static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
2306 abi_ulong target_addr,
2307 unsigned nsops)
2309 struct target_sembuf *target_sembuf;
2310 int i;
2312 target_sembuf = lock_user(VERIFY_READ, target_addr,
2313 nsops*sizeof(struct target_sembuf), 1);
2314 if (!target_sembuf)
2315 return -TARGET_EFAULT;
2317 for(i=0; i<nsops; i++) {
2318 __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
2319 __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
2320 __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
2323 unlock_user(target_sembuf, target_addr, 0);
2325 return 0;
2328 static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
2330 struct sembuf sops[nsops];
2332 if (target_to_host_sembuf(sops, ptr, nsops))
2333 return -TARGET_EFAULT;
2335 return semop(semid, sops, nsops);
2338 struct target_msqid_ds
2340 struct target_ipc_perm msg_perm;
2341 abi_ulong msg_stime;
2342 #if TARGET_ABI_BITS == 32
2343 abi_ulong __unused1;
2344 #endif
2345 abi_ulong msg_rtime;
2346 #if TARGET_ABI_BITS == 32
2347 abi_ulong __unused2;
2348 #endif
2349 abi_ulong msg_ctime;
2350 #if TARGET_ABI_BITS == 32
2351 abi_ulong __unused3;
2352 #endif
2353 abi_ulong __msg_cbytes;
2354 abi_ulong msg_qnum;
2355 abi_ulong msg_qbytes;
2356 abi_ulong msg_lspid;
2357 abi_ulong msg_lrpid;
2358 abi_ulong __unused4;
2359 abi_ulong __unused5;
2362 static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
2363 abi_ulong target_addr)
2365 struct target_msqid_ds *target_md;
2367 if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
2368 return -TARGET_EFAULT;
2369 if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
2370 return -TARGET_EFAULT;
2371 host_md->msg_stime = tswapl(target_md->msg_stime);
2372 host_md->msg_rtime = tswapl(target_md->msg_rtime);
2373 host_md->msg_ctime = tswapl(target_md->msg_ctime);
2374 host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
2375 host_md->msg_qnum = tswapl(target_md->msg_qnum);
2376 host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
2377 host_md->msg_lspid = tswapl(target_md->msg_lspid);
2378 host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
2379 unlock_user_struct(target_md, target_addr, 0);
2380 return 0;
2383 static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
2384 struct msqid_ds *host_md)
2386 struct target_msqid_ds *target_md;
2388 if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
2389 return -TARGET_EFAULT;
2390 if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
2391 return -TARGET_EFAULT;
2392 target_md->msg_stime = tswapl(host_md->msg_stime);
2393 target_md->msg_rtime = tswapl(host_md->msg_rtime);
2394 target_md->msg_ctime = tswapl(host_md->msg_ctime);
2395 target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
2396 target_md->msg_qnum = tswapl(host_md->msg_qnum);
2397 target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
2398 target_md->msg_lspid = tswapl(host_md->msg_lspid);
2399 target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
2400 unlock_user_struct(target_md, target_addr, 1);
2401 return 0;
2404 struct target_msginfo {
2405 int msgpool;
2406 int msgmap;
2407 int msgmax;
2408 int msgmnb;
2409 int msgmni;
2410 int msgssz;
2411 int msgtql;
2412 unsigned short int msgseg;
2415 static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
2416 struct msginfo *host_msginfo)
2418 struct target_msginfo *target_msginfo;
2419 if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
2420 return -TARGET_EFAULT;
2421 __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
2422 __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
2423 __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
2424 __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
2425 __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
2426 __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
2427 __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
2428 __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
2429 unlock_user_struct(target_msginfo, target_addr, 1);
2430 return 0;
2433 static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
2435 struct msqid_ds dsarg;
2436 struct msginfo msginfo;
2437 abi_long ret = -TARGET_EINVAL;
2439 cmd &= 0xff;
2441 switch (cmd) {
2442 case IPC_STAT:
2443 case IPC_SET:
2444 case MSG_STAT:
2445 if (target_to_host_msqid_ds(&dsarg,ptr))
2446 return -TARGET_EFAULT;
2447 ret = get_errno(msgctl(msgid, cmd, &dsarg));
2448 if (host_to_target_msqid_ds(ptr,&dsarg))
2449 return -TARGET_EFAULT;
2450 break;
2451 case IPC_RMID:
2452 ret = get_errno(msgctl(msgid, cmd, NULL));
2453 break;
2454 case IPC_INFO:
2455 case MSG_INFO:
2456 ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
2457 if (host_to_target_msginfo(ptr, &msginfo))
2458 return -TARGET_EFAULT;
2459 break;
2462 return ret;
2465 struct target_msgbuf {
2466 abi_long mtype;
2467 char mtext[1];
2470 static inline abi_long do_msgsnd(int msqid, abi_long msgp,
2471 unsigned int msgsz, int msgflg)
2473 struct target_msgbuf *target_mb;
2474 struct msgbuf *host_mb;
2475 abi_long ret = 0;
2477 if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
2478 return -TARGET_EFAULT;
2479 host_mb = malloc(msgsz+sizeof(long));
2480 host_mb->mtype = (abi_long) tswapl(target_mb->mtype);
2481 memcpy(host_mb->mtext, target_mb->mtext, msgsz);
2482 ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
2483 free(host_mb);
2484 unlock_user_struct(target_mb, msgp, 0);
2486 return ret;
2489 static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2490 unsigned int msgsz, abi_long msgtyp,
2491 int msgflg)
2493 struct target_msgbuf *target_mb;
2494 char *target_mtext;
2495 struct msgbuf *host_mb;
2496 abi_long ret = 0;
2498 if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2499 return -TARGET_EFAULT;
2501 host_mb = malloc(msgsz+sizeof(long));
2502 ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapl(msgtyp), msgflg));
2504 if (ret > 0) {
2505 abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2506 target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2507 if (!target_mtext) {
2508 ret = -TARGET_EFAULT;
2509 goto end;
2511 memcpy(target_mb->mtext, host_mb->mtext, ret);
2512 unlock_user(target_mtext, target_mtext_addr, ret);
2515 target_mb->mtype = tswapl(host_mb->mtype);
2516 free(host_mb);
2518 end:
2519 if (target_mb)
2520 unlock_user_struct(target_mb, msgp, 1);
2521 return ret;
2524 struct target_shmid_ds
2526 struct target_ipc_perm shm_perm;
2527 abi_ulong shm_segsz;
2528 abi_ulong shm_atime;
2529 #if TARGET_ABI_BITS == 32
2530 abi_ulong __unused1;
2531 #endif
2532 abi_ulong shm_dtime;
2533 #if TARGET_ABI_BITS == 32
2534 abi_ulong __unused2;
2535 #endif
2536 abi_ulong shm_ctime;
2537 #if TARGET_ABI_BITS == 32
2538 abi_ulong __unused3;
2539 #endif
2540 int shm_cpid;
2541 int shm_lpid;
2542 abi_ulong shm_nattch;
2543 unsigned long int __unused4;
2544 unsigned long int __unused5;
2547 static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
2548 abi_ulong target_addr)
2550 struct target_shmid_ds *target_sd;
2552 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2553 return -TARGET_EFAULT;
2554 if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr))
2555 return -TARGET_EFAULT;
2556 __get_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2557 __get_user(host_sd->shm_atime, &target_sd->shm_atime);
2558 __get_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2559 __get_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2560 __get_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2561 __get_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2562 __get_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2563 unlock_user_struct(target_sd, target_addr, 0);
2564 return 0;
2567 static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
2568 struct shmid_ds *host_sd)
2570 struct target_shmid_ds *target_sd;
2572 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2573 return -TARGET_EFAULT;
2574 if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm)))
2575 return -TARGET_EFAULT;
2576 __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2577 __put_user(host_sd->shm_atime, &target_sd->shm_atime);
2578 __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2579 __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2580 __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2581 __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2582 __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2583 unlock_user_struct(target_sd, target_addr, 1);
2584 return 0;
2587 struct target_shminfo {
2588 abi_ulong shmmax;
2589 abi_ulong shmmin;
2590 abi_ulong shmmni;
2591 abi_ulong shmseg;
2592 abi_ulong shmall;
2595 static inline abi_long host_to_target_shminfo(abi_ulong target_addr,
2596 struct shminfo *host_shminfo)
2598 struct target_shminfo *target_shminfo;
2599 if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0))
2600 return -TARGET_EFAULT;
2601 __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
2602 __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
2603 __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
2604 __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
2605 __put_user(host_shminfo->shmall, &target_shminfo->shmall);
2606 unlock_user_struct(target_shminfo, target_addr, 1);
2607 return 0;
2610 struct target_shm_info {
2611 int used_ids;
2612 abi_ulong shm_tot;
2613 abi_ulong shm_rss;
2614 abi_ulong shm_swp;
2615 abi_ulong swap_attempts;
2616 abi_ulong swap_successes;
2619 static inline abi_long host_to_target_shm_info(abi_ulong target_addr,
2620 struct shm_info *host_shm_info)
2622 struct target_shm_info *target_shm_info;
2623 if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0))
2624 return -TARGET_EFAULT;
2625 __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
2626 __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
2627 __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
2628 __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
2629 __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts);
2630 __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes);
2631 unlock_user_struct(target_shm_info, target_addr, 1);
2632 return 0;
2635 static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
2637 struct shmid_ds dsarg;
2638 struct shminfo shminfo;
2639 struct shm_info shm_info;
2640 abi_long ret = -TARGET_EINVAL;
2642 cmd &= 0xff;
2644 switch(cmd) {
2645 case IPC_STAT:
2646 case IPC_SET:
2647 case SHM_STAT:
2648 if (target_to_host_shmid_ds(&dsarg, buf))
2649 return -TARGET_EFAULT;
2650 ret = get_errno(shmctl(shmid, cmd, &dsarg));
2651 if (host_to_target_shmid_ds(buf, &dsarg))
2652 return -TARGET_EFAULT;
2653 break;
2654 case IPC_INFO:
2655 ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
2656 if (host_to_target_shminfo(buf, &shminfo))
2657 return -TARGET_EFAULT;
2658 break;
2659 case SHM_INFO:
2660 ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
2661 if (host_to_target_shm_info(buf, &shm_info))
2662 return -TARGET_EFAULT;
2663 break;
2664 case IPC_RMID:
2665 case SHM_LOCK:
2666 case SHM_UNLOCK:
2667 ret = get_errno(shmctl(shmid, cmd, NULL));
2668 break;
2671 return ret;
2674 static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
2676 abi_long raddr;
2677 void *host_raddr;
2678 struct shmid_ds shm_info;
2679 int i,ret;
2681 /* find out the length of the shared memory segment */
2682 ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
2683 if (is_error(ret)) {
2684 /* can't get length, bail out */
2685 return ret;
2688 mmap_lock();
2690 if (shmaddr)
2691 host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
2692 else {
2693 abi_ulong mmap_start;
2695 mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
2697 if (mmap_start == -1) {
2698 errno = ENOMEM;
2699 host_raddr = (void *)-1;
2700 } else
2701 host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);
2704 if (host_raddr == (void *)-1) {
2705 mmap_unlock();
2706 return get_errno((long)host_raddr);
2708 raddr=h2g((unsigned long)host_raddr);
2710 page_set_flags(raddr, raddr + shm_info.shm_segsz,
2711 PAGE_VALID | PAGE_READ |
2712 ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
2714 for (i = 0; i < N_SHM_REGIONS; i++) {
2715 if (shm_regions[i].start == 0) {
2716 shm_regions[i].start = raddr;
2717 shm_regions[i].size = shm_info.shm_segsz;
2718 break;
2722 mmap_unlock();
2723 return raddr;
2727 static inline abi_long do_shmdt(abi_ulong shmaddr)
2729 int i;
2731 for (i = 0; i < N_SHM_REGIONS; ++i) {
2732 if (shm_regions[i].start == shmaddr) {
2733 shm_regions[i].start = 0;
2734 page_set_flags(shmaddr, shm_regions[i].size, 0);
2735 break;
2739 return get_errno(shmdt(g2h(shmaddr)));
2742 #ifdef TARGET_NR_ipc
2743 /* ??? This only works with linear mappings. */
2744 /* do_ipc() must return target values and target errnos. */
2745 static abi_long do_ipc(unsigned int call, int first,
2746 int second, int third,
2747 abi_long ptr, abi_long fifth)
2749 int version;
2750 abi_long ret = 0;
2752 version = call >> 16;
2753 call &= 0xffff;
2755 switch (call) {
2756 case IPCOP_semop:
2757 ret = do_semop(first, ptr, second);
2758 break;
2760 case IPCOP_semget:
2761 ret = get_errno(semget(first, second, third));
2762 break;
2764 case IPCOP_semctl:
2765 ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr);
2766 break;
2768 case IPCOP_msgget:
2769 ret = get_errno(msgget(first, second));
2770 break;
2772 case IPCOP_msgsnd:
2773 ret = do_msgsnd(first, ptr, second, third);
2774 break;
2776 case IPCOP_msgctl:
2777 ret = do_msgctl(first, second, ptr);
2778 break;
2780 case IPCOP_msgrcv:
2781 switch (version) {
2782 case 0:
2784 struct target_ipc_kludge {
2785 abi_long msgp;
2786 abi_long msgtyp;
2787 } *tmp;
2789 if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
2790 ret = -TARGET_EFAULT;
2791 break;
2794 ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
2796 unlock_user_struct(tmp, ptr, 0);
2797 break;
2799 default:
2800 ret = do_msgrcv(first, ptr, second, fifth, third);
2802 break;
2804 case IPCOP_shmat:
2805 switch (version) {
2806 default:
2808 abi_ulong raddr;
2809 raddr = do_shmat(first, ptr, second);
2810 if (is_error(raddr))
2811 return get_errno(raddr);
2812 if (put_user_ual(raddr, third))
2813 return -TARGET_EFAULT;
2814 break;
2816 case 1:
2817 ret = -TARGET_EINVAL;
2818 break;
2820 break;
2821 case IPCOP_shmdt:
2822 ret = do_shmdt(ptr);
2823 break;
2825 case IPCOP_shmget:
2826 /* IPC_* flag values are the same on all linux platforms */
2827 ret = get_errno(shmget(first, second, third));
2828 break;
2830 /* IPC_* and SHM_* command values are the same on all linux platforms */
2831 case IPCOP_shmctl:
2832 ret = do_shmctl(first, second, third);
2833 break;
2834 default:
2835 gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2836 ret = -TARGET_ENOSYS;
2837 break;
2839 return ret;
2841 #endif
2843 /* kernel structure types definitions */
2844 #define IFNAMSIZ 16
2846 #define STRUCT(name, ...) STRUCT_ ## name,
2847 #define STRUCT_SPECIAL(name) STRUCT_ ## name,
2848 enum {
2849 #include "syscall_types.h"
2851 #undef STRUCT
2852 #undef STRUCT_SPECIAL
2854 #define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = { __VA_ARGS__, TYPE_NULL };
2855 #define STRUCT_SPECIAL(name)
2856 #include "syscall_types.h"
2857 #undef STRUCT
2858 #undef STRUCT_SPECIAL
2860 typedef struct IOCTLEntry {
2861 unsigned int target_cmd;
2862 unsigned int host_cmd;
2863 const char *name;
2864 int access;
2865 const argtype arg_type[5];
2866 } IOCTLEntry;
2868 #define IOC_R 0x0001
2869 #define IOC_W 0x0002
2870 #define IOC_RW (IOC_R | IOC_W)
2872 #define MAX_STRUCT_SIZE 4096
2874 static IOCTLEntry ioctl_entries[] = {
2875 #define IOCTL(cmd, access, ...) \
2876 { TARGET_ ## cmd, cmd, #cmd, access, { __VA_ARGS__ } },
2877 #include "ioctls.h"
2878 { 0, 0, },
2881 /* ??? Implement proper locking for ioctls. */
2882 /* do_ioctl() Must return target values and target errnos. */
2883 static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
2885 const IOCTLEntry *ie;
2886 const argtype *arg_type;
2887 abi_long ret;
2888 uint8_t buf_temp[MAX_STRUCT_SIZE];
2889 int target_size;
2890 void *argptr;
2892 ie = ioctl_entries;
2893 for(;;) {
2894 if (ie->target_cmd == 0) {
2895 gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
2896 return -TARGET_ENOSYS;
2898 if (ie->target_cmd == cmd)
2899 break;
2900 ie++;
2902 arg_type = ie->arg_type;
2903 #if defined(DEBUG)
2904 gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
2905 #endif
2906 switch(arg_type[0]) {
2907 case TYPE_NULL:
2908 /* no argument */
2909 ret = get_errno(ioctl(fd, ie->host_cmd));
2910 break;
2911 case TYPE_PTRVOID:
2912 case TYPE_INT:
2913 /* int argment */
2914 ret = get_errno(ioctl(fd, ie->host_cmd, arg));
2915 break;
2916 case TYPE_PTR:
2917 arg_type++;
2918 target_size = thunk_type_size(arg_type, 0);
2919 switch(ie->access) {
2920 case IOC_R:
2921 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2922 if (!is_error(ret)) {
2923 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2924 if (!argptr)
2925 return -TARGET_EFAULT;
2926 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2927 unlock_user(argptr, arg, target_size);
2929 break;
2930 case IOC_W:
2931 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2932 if (!argptr)
2933 return -TARGET_EFAULT;
2934 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2935 unlock_user(argptr, arg, 0);
2936 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2937 break;
2938 default:
2939 case IOC_RW:
2940 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2941 if (!argptr)
2942 return -TARGET_EFAULT;
2943 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2944 unlock_user(argptr, arg, 0);
2945 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2946 if (!is_error(ret)) {
2947 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2948 if (!argptr)
2949 return -TARGET_EFAULT;
2950 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2951 unlock_user(argptr, arg, target_size);
2953 break;
2955 break;
2956 default:
2957 gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
2958 (long)cmd, arg_type[0]);
2959 ret = -TARGET_ENOSYS;
2960 break;
2962 return ret;
2965 static const bitmask_transtbl iflag_tbl[] = {
2966 { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
2967 { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
2968 { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
2969 { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
2970 { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
2971 { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
2972 { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
2973 { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
2974 { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
2975 { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
2976 { TARGET_IXON, TARGET_IXON, IXON, IXON },
2977 { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
2978 { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
2979 { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
2980 { 0, 0, 0, 0 }
2983 static const bitmask_transtbl oflag_tbl[] = {
2984 { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
2985 { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
2986 { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
2987 { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
2988 { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
2989 { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
2990 { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
2991 { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
2992 { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
2993 { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
2994 { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
2995 { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
2996 { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
2997 { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
2998 { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
2999 { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
3000 { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
3001 { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
3002 { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
3003 { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
3004 { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
3005 { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
3006 { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
3007 { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
3008 { 0, 0, 0, 0 }
3011 static const bitmask_transtbl cflag_tbl[] = {
3012 { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
3013 { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
3014 { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
3015 { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
3016 { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
3017 { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
3018 { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
3019 { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
3020 { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
3021 { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
3022 { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
3023 { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
3024 { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
3025 { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
3026 { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
3027 { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
3028 { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
3029 { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
3030 { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
3031 { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
3032 { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
3033 { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
3034 { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
3035 { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
3036 { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
3037 { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
3038 { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
3039 { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
3040 { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
3041 { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
3042 { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
3043 { 0, 0, 0, 0 }
3046 static const bitmask_transtbl lflag_tbl[] = {
3047 { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
3048 { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
3049 { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
3050 { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
3051 { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
3052 { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
3053 { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
3054 { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
3055 { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
3056 { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
3057 { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
3058 { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
3059 { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
3060 { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
3061 { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
3062 { 0, 0, 0, 0 }
3065 static void target_to_host_termios (void *dst, const void *src)
3067 struct host_termios *host = dst;
3068 const struct target_termios *target = src;
3070 host->c_iflag =
3071 target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
3072 host->c_oflag =
3073 target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
3074 host->c_cflag =
3075 target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
3076 host->c_lflag =
3077 target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
3078 host->c_line = target->c_line;
3080 memset(host->c_cc, 0, sizeof(host->c_cc));
3081 host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
3082 host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
3083 host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
3084 host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
3085 host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
3086 host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
3087 host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
3088 host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
3089 host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
3090 host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
3091 host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
3092 host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
3093 host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
3094 host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
3095 host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
3096 host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
3097 host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
3100 static void host_to_target_termios (void *dst, const void *src)
3102 struct target_termios *target = dst;
3103 const struct host_termios *host = src;
3105 target->c_iflag =
3106 tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
3107 target->c_oflag =
3108 tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
3109 target->c_cflag =
3110 tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
3111 target->c_lflag =
3112 tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
3113 target->c_line = host->c_line;
3115 memset(target->c_cc, 0, sizeof(target->c_cc));
3116 target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
3117 target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
3118 target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
3119 target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
3120 target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
3121 target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
3122 target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
3123 target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
3124 target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
3125 target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
3126 target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
3127 target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
3128 target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
3129 target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
3130 target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
3131 target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
3132 target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
3135 static const StructEntry struct_termios_def = {
3136 .convert = { host_to_target_termios, target_to_host_termios },
3137 .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
3138 .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
3141 static bitmask_transtbl mmap_flags_tbl[] = {
3142 { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
3143 { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
3144 { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
3145 { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
3146 { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
3147 { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
3148 { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
3149 { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
3150 { 0, 0, 0, 0 }
3153 #if defined(TARGET_I386)
3155 /* NOTE: there is really one LDT for all the threads */
3156 static uint8_t *ldt_table;
3158 static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
3160 int size;
3161 void *p;
3163 if (!ldt_table)
3164 return 0;
3165 size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
3166 if (size > bytecount)
3167 size = bytecount;
3168 p = lock_user(VERIFY_WRITE, ptr, size, 0);
3169 if (!p)
3170 return -TARGET_EFAULT;
3171 /* ??? Should this by byteswapped? */
3172 memcpy(p, ldt_table, size);
3173 unlock_user(p, ptr, size);
3174 return size;
3177 /* XXX: add locking support */
3178 static abi_long write_ldt(CPUX86State *env,
3179 abi_ulong ptr, unsigned long bytecount, int oldmode)
3181 struct target_modify_ldt_ldt_s ldt_info;
3182 struct target_modify_ldt_ldt_s *target_ldt_info;
3183 int seg_32bit, contents, read_exec_only, limit_in_pages;
3184 int seg_not_present, useable, lm;
3185 uint32_t *lp, entry_1, entry_2;
3187 if (bytecount != sizeof(ldt_info))
3188 return -TARGET_EINVAL;
3189 if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
3190 return -TARGET_EFAULT;
3191 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3192 ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
3193 ldt_info.limit = tswap32(target_ldt_info->limit);
3194 ldt_info.flags = tswap32(target_ldt_info->flags);
3195 unlock_user_struct(target_ldt_info, ptr, 0);
3197 if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
3198 return -TARGET_EINVAL;
3199 seg_32bit = ldt_info.flags & 1;
3200 contents = (ldt_info.flags >> 1) & 3;
3201 read_exec_only = (ldt_info.flags >> 3) & 1;
3202 limit_in_pages = (ldt_info.flags >> 4) & 1;
3203 seg_not_present = (ldt_info.flags >> 5) & 1;
3204 useable = (ldt_info.flags >> 6) & 1;
3205 #ifdef TARGET_ABI32
3206 lm = 0;
3207 #else
3208 lm = (ldt_info.flags >> 7) & 1;
3209 #endif
3210 if (contents == 3) {
3211 if (oldmode)
3212 return -TARGET_EINVAL;
3213 if (seg_not_present == 0)
3214 return -TARGET_EINVAL;
3216 /* allocate the LDT */
3217 if (!ldt_table) {
3218 env->ldt.base = target_mmap(0,
3219 TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
3220 PROT_READ|PROT_WRITE,
3221 MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
3222 if (env->ldt.base == -1)
3223 return -TARGET_ENOMEM;
3224 memset(g2h(env->ldt.base), 0,
3225 TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
3226 env->ldt.limit = 0xffff;
3227 ldt_table = g2h(env->ldt.base);
3230 /* NOTE: same code as Linux kernel */
3231 /* Allow LDTs to be cleared by the user. */
3232 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3233 if (oldmode ||
3234 (contents == 0 &&
3235 read_exec_only == 1 &&
3236 seg_32bit == 0 &&
3237 limit_in_pages == 0 &&
3238 seg_not_present == 1 &&
3239 useable == 0 )) {
3240 entry_1 = 0;
3241 entry_2 = 0;
3242 goto install;
3246 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
3247 (ldt_info.limit & 0x0ffff);
3248 entry_2 = (ldt_info.base_addr & 0xff000000) |
3249 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3250 (ldt_info.limit & 0xf0000) |
3251 ((read_exec_only ^ 1) << 9) |
3252 (contents << 10) |
3253 ((seg_not_present ^ 1) << 15) |
3254 (seg_32bit << 22) |
3255 (limit_in_pages << 23) |
3256 (lm << 21) |
3257 0x7000;
3258 if (!oldmode)
3259 entry_2 |= (useable << 20);
3261 /* Install the new entry ... */
3262 install:
3263 lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
3264 lp[0] = tswap32(entry_1);
3265 lp[1] = tswap32(entry_2);
3266 return 0;
3269 /* specific and weird i386 syscalls */
3270 static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
3271 unsigned long bytecount)
3273 abi_long ret;
3275 switch (func) {
3276 case 0:
3277 ret = read_ldt(ptr, bytecount);
3278 break;
3279 case 1:
3280 ret = write_ldt(env, ptr, bytecount, 1);
3281 break;
3282 case 0x11:
3283 ret = write_ldt(env, ptr, bytecount, 0);
3284 break;
3285 default:
3286 ret = -TARGET_ENOSYS;
3287 break;
3289 return ret;
3292 #if defined(TARGET_I386) && defined(TARGET_ABI32)
3293 static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
3295 uint64_t *gdt_table = g2h(env->gdt.base);
3296 struct target_modify_ldt_ldt_s ldt_info;
3297 struct target_modify_ldt_ldt_s *target_ldt_info;
3298 int seg_32bit, contents, read_exec_only, limit_in_pages;
3299 int seg_not_present, useable, lm;
3300 uint32_t *lp, entry_1, entry_2;
3301 int i;
3303 lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3304 if (!target_ldt_info)
3305 return -TARGET_EFAULT;
3306 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3307 ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
3308 ldt_info.limit = tswap32(target_ldt_info->limit);
3309 ldt_info.flags = tswap32(target_ldt_info->flags);
3310 if (ldt_info.entry_number == -1) {
3311 for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
3312 if (gdt_table[i] == 0) {
3313 ldt_info.entry_number = i;
3314 target_ldt_info->entry_number = tswap32(i);
3315 break;
3319 unlock_user_struct(target_ldt_info, ptr, 1);
3321 if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN ||
3322 ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
3323 return -TARGET_EINVAL;
3324 seg_32bit = ldt_info.flags & 1;
3325 contents = (ldt_info.flags >> 1) & 3;
3326 read_exec_only = (ldt_info.flags >> 3) & 1;
3327 limit_in_pages = (ldt_info.flags >> 4) & 1;
3328 seg_not_present = (ldt_info.flags >> 5) & 1;
3329 useable = (ldt_info.flags >> 6) & 1;
3330 #ifdef TARGET_ABI32
3331 lm = 0;
3332 #else
3333 lm = (ldt_info.flags >> 7) & 1;
3334 #endif
3336 if (contents == 3) {
3337 if (seg_not_present == 0)
3338 return -TARGET_EINVAL;
3341 /* NOTE: same code as Linux kernel */
3342 /* Allow LDTs to be cleared by the user. */
3343 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3344 if ((contents == 0 &&
3345 read_exec_only == 1 &&
3346 seg_32bit == 0 &&
3347 limit_in_pages == 0 &&
3348 seg_not_present == 1 &&
3349 useable == 0 )) {
3350 entry_1 = 0;
3351 entry_2 = 0;
3352 goto install;
3356 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
3357 (ldt_info.limit & 0x0ffff);
3358 entry_2 = (ldt_info.base_addr & 0xff000000) |
3359 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3360 (ldt_info.limit & 0xf0000) |
3361 ((read_exec_only ^ 1) << 9) |
3362 (contents << 10) |
3363 ((seg_not_present ^ 1) << 15) |
3364 (seg_32bit << 22) |
3365 (limit_in_pages << 23) |
3366 (useable << 20) |
3367 (lm << 21) |
3368 0x7000;
3370 /* Install the new entry ... */
3371 install:
3372 lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
3373 lp[0] = tswap32(entry_1);
3374 lp[1] = tswap32(entry_2);
3375 return 0;
3378 static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
3380 struct target_modify_ldt_ldt_s *target_ldt_info;
3381 uint64_t *gdt_table = g2h(env->gdt.base);
3382 uint32_t base_addr, limit, flags;
3383 int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
3384 int seg_not_present, useable, lm;
3385 uint32_t *lp, entry_1, entry_2;
3387 lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3388 if (!target_ldt_info)
3389 return -TARGET_EFAULT;
3390 idx = tswap32(target_ldt_info->entry_number);
3391 if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
3392 idx > TARGET_GDT_ENTRY_TLS_MAX) {
3393 unlock_user_struct(target_ldt_info, ptr, 1);
3394 return -TARGET_EINVAL;
3396 lp = (uint32_t *)(gdt_table + idx);
3397 entry_1 = tswap32(lp[0]);
3398 entry_2 = tswap32(lp[1]);
3400 read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
3401 contents = (entry_2 >> 10) & 3;
3402 seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
3403 seg_32bit = (entry_2 >> 22) & 1;
3404 limit_in_pages = (entry_2 >> 23) & 1;
3405 useable = (entry_2 >> 20) & 1;
3406 #ifdef TARGET_ABI32
3407 lm = 0;
3408 #else
3409 lm = (entry_2 >> 21) & 1;
3410 #endif
3411 flags = (seg_32bit << 0) | (contents << 1) |
3412 (read_exec_only << 3) | (limit_in_pages << 4) |
3413 (seg_not_present << 5) | (useable << 6) | (lm << 7);
3414 limit = (entry_1 & 0xffff) | (entry_2 & 0xf0000);
3415 base_addr = (entry_1 >> 16) |
3416 (entry_2 & 0xff000000) |
3417 ((entry_2 & 0xff) << 16);
3418 target_ldt_info->base_addr = tswapl(base_addr);
3419 target_ldt_info->limit = tswap32(limit);
3420 target_ldt_info->flags = tswap32(flags);
3421 unlock_user_struct(target_ldt_info, ptr, 1);
3422 return 0;
3424 #endif /* TARGET_I386 && TARGET_ABI32 */
3426 #ifndef TARGET_ABI32
3427 static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
3429 abi_long ret;
3430 abi_ulong val;
3431 int idx;
3433 switch(code) {
3434 case TARGET_ARCH_SET_GS:
3435 case TARGET_ARCH_SET_FS:
3436 if (code == TARGET_ARCH_SET_GS)
3437 idx = R_GS;
3438 else
3439 idx = R_FS;
3440 cpu_x86_load_seg(env, idx, 0);
3441 env->segs[idx].base = addr;
3442 break;
3443 case TARGET_ARCH_GET_GS:
3444 case TARGET_ARCH_GET_FS:
3445 if (code == TARGET_ARCH_GET_GS)
3446 idx = R_GS;
3447 else
3448 idx = R_FS;
3449 val = env->segs[idx].base;
3450 if (put_user(val, addr, abi_ulong))
3451 return -TARGET_EFAULT;
3452 break;
3453 default:
3454 ret = -TARGET_EINVAL;
3455 break;
3457 return 0;
3459 #endif
3461 #endif /* defined(TARGET_I386) */
3463 #if defined(USE_NPTL)
3465 #define NEW_STACK_SIZE PTHREAD_STACK_MIN
3467 static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
3468 typedef struct {
3469 CPUState *env;
3470 pthread_mutex_t mutex;
3471 pthread_cond_t cond;
3472 pthread_t thread;
3473 uint32_t tid;
3474 abi_ulong child_tidptr;
3475 abi_ulong parent_tidptr;
3476 sigset_t sigmask;
3477 } new_thread_info;
3479 static void *clone_func(void *arg)
3481 new_thread_info *info = arg;
3482 CPUState *env;
3483 TaskState *ts;
3485 env = info->env;
3486 thread_env = env;
3487 ts = (TaskState *)thread_env->opaque;
3488 info->tid = gettid();
3489 env->host_tid = info->tid;
3490 task_settid(ts);
3491 if (info->child_tidptr)
3492 put_user_u32(info->tid, info->child_tidptr);
3493 if (info->parent_tidptr)
3494 put_user_u32(info->tid, info->parent_tidptr);
3495 /* Enable signals. */
3496 sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
3497 /* Signal to the parent that we're ready. */
3498 pthread_mutex_lock(&info->mutex);
3499 pthread_cond_broadcast(&info->cond);
3500 pthread_mutex_unlock(&info->mutex);
3501 /* Wait until the parent has finshed initializing the tls state. */
3502 pthread_mutex_lock(&clone_lock);
3503 pthread_mutex_unlock(&clone_lock);
3504 cpu_loop(env);
3505 /* never exits */
3506 return NULL;
3508 #else
3509 /* this stack is the equivalent of the kernel stack associated with a
3510 thread/process */
3511 #define NEW_STACK_SIZE 8192
3513 static int clone_func(void *arg)
3515 CPUState *env = arg;
3516 cpu_loop(env);
3517 /* never exits */
3518 return 0;
3520 #endif
3522 /* do_fork() Must return host values and target errnos (unlike most
3523 do_*() functions). */
3524 static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
3525 abi_ulong parent_tidptr, target_ulong newtls,
3526 abi_ulong child_tidptr)
3528 int ret;
3529 TaskState *ts;
3530 uint8_t *new_stack;
3531 CPUState *new_env;
3532 #if defined(USE_NPTL)
3533 unsigned int nptl_flags;
3534 sigset_t sigmask;
3535 #endif
3537 /* Emulate vfork() with fork() */
3538 if (flags & CLONE_VFORK)
3539 flags &= ~(CLONE_VFORK | CLONE_VM);
3541 if (flags & CLONE_VM) {
3542 TaskState *parent_ts = (TaskState *)env->opaque;
3543 #if defined(USE_NPTL)
3544 new_thread_info info;
3545 pthread_attr_t attr;
3546 #endif
3547 ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
3548 init_task_state(ts);
3549 new_stack = ts->stack;
3550 /* we create a new CPU instance. */
3551 new_env = cpu_copy(env);
3552 /* Init regs that differ from the parent. */
3553 cpu_clone_regs(new_env, newsp);
3554 new_env->opaque = ts;
3555 ts->bprm = parent_ts->bprm;
3556 ts->info = parent_ts->info;
3557 #if defined(USE_NPTL)
3558 nptl_flags = flags;
3559 flags &= ~CLONE_NPTL_FLAGS2;
3561 if (nptl_flags & CLONE_CHILD_CLEARTID) {
3562 ts->child_tidptr = child_tidptr;
3565 if (nptl_flags & CLONE_SETTLS)
3566 cpu_set_tls (new_env, newtls);
3568 /* Grab a mutex so that thread setup appears atomic. */
3569 pthread_mutex_lock(&clone_lock);
3571 memset(&info, 0, sizeof(info));
3572 pthread_mutex_init(&info.mutex, NULL);
3573 pthread_mutex_lock(&info.mutex);
3574 pthread_cond_init(&info.cond, NULL);
3575 info.env = new_env;
3576 if (nptl_flags & CLONE_CHILD_SETTID)
3577 info.child_tidptr = child_tidptr;
3578 if (nptl_flags & CLONE_PARENT_SETTID)
3579 info.parent_tidptr = parent_tidptr;
3581 ret = pthread_attr_init(&attr);
3582 ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE);
3583 /* It is not safe to deliver signals until the child has finished
3584 initializing, so temporarily block all signals. */
3585 sigfillset(&sigmask);
3586 sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
3588 ret = pthread_create(&info.thread, &attr, clone_func, &info);
3589 /* TODO: Free new CPU state if thread creation failed. */
3591 sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
3592 pthread_attr_destroy(&attr);
3593 if (ret == 0) {
3594 /* Wait for the child to initialize. */
3595 pthread_cond_wait(&info.cond, &info.mutex);
3596 ret = info.tid;
3597 if (flags & CLONE_PARENT_SETTID)
3598 put_user_u32(ret, parent_tidptr);
3599 } else {
3600 ret = -1;
3602 pthread_mutex_unlock(&info.mutex);
3603 pthread_cond_destroy(&info.cond);
3604 pthread_mutex_destroy(&info.mutex);
3605 pthread_mutex_unlock(&clone_lock);
3606 #else
3607 if (flags & CLONE_NPTL_FLAGS2)
3608 return -EINVAL;
3609 /* This is probably going to die very quickly, but do it anyway. */
3610 #ifdef __ia64__
3611 ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
3612 #else
3613 ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
3614 #endif
3615 #endif
3616 } else {
3617 /* if no CLONE_VM, we consider it is a fork */
3618 if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
3619 return -EINVAL;
3620 fork_start();
3621 ret = fork();
3622 if (ret == 0) {
3623 /* Child Process. */
3624 cpu_clone_regs(env, newsp);
3625 fork_end(1);
3626 #if defined(USE_NPTL)
3627 /* There is a race condition here. The parent process could
3628 theoretically read the TID in the child process before the child
3629 tid is set. This would require using either ptrace
3630 (not implemented) or having *_tidptr to point at a shared memory
3631 mapping. We can't repeat the spinlock hack used above because
3632 the child process gets its own copy of the lock. */
3633 if (flags & CLONE_CHILD_SETTID)
3634 put_user_u32(gettid(), child_tidptr);
3635 if (flags & CLONE_PARENT_SETTID)
3636 put_user_u32(gettid(), parent_tidptr);
3637 ts = (TaskState *)env->opaque;
3638 if (flags & CLONE_SETTLS)
3639 cpu_set_tls (env, newtls);
3640 if (flags & CLONE_CHILD_CLEARTID)
3641 ts->child_tidptr = child_tidptr;
3642 #endif
3643 } else {
3644 fork_end(0);
3647 return ret;
3650 /* warning : doesn't handle linux specific flags... */
3651 static int target_to_host_fcntl_cmd(int cmd)
3653 switch(cmd) {
3654 case TARGET_F_DUPFD:
3655 case TARGET_F_GETFD:
3656 case TARGET_F_SETFD:
3657 case TARGET_F_GETFL:
3658 case TARGET_F_SETFL:
3659 return cmd;
3660 case TARGET_F_GETLK:
3661 return F_GETLK;
3662 case TARGET_F_SETLK:
3663 return F_SETLK;
3664 case TARGET_F_SETLKW:
3665 return F_SETLKW;
3666 case TARGET_F_GETOWN:
3667 return F_GETOWN;
3668 case TARGET_F_SETOWN:
3669 return F_SETOWN;
3670 case TARGET_F_GETSIG:
3671 return F_GETSIG;
3672 case TARGET_F_SETSIG:
3673 return F_SETSIG;
3674 #if TARGET_ABI_BITS == 32
3675 case TARGET_F_GETLK64:
3676 return F_GETLK64;
3677 case TARGET_F_SETLK64:
3678 return F_SETLK64;
3679 case TARGET_F_SETLKW64:
3680 return F_SETLKW64;
3681 #endif
3682 default:
3683 return -TARGET_EINVAL;
3685 return -TARGET_EINVAL;
3688 static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
3690 struct flock fl;
3691 struct target_flock *target_fl;
3692 struct flock64 fl64;
3693 struct target_flock64 *target_fl64;
3694 abi_long ret;
3695 int host_cmd = target_to_host_fcntl_cmd(cmd);
3697 if (host_cmd == -TARGET_EINVAL)
3698 return host_cmd;
3700 switch(cmd) {
3701 case TARGET_F_GETLK:
3702 if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3703 return -TARGET_EFAULT;
3704 fl.l_type = tswap16(target_fl->l_type);
3705 fl.l_whence = tswap16(target_fl->l_whence);
3706 fl.l_start = tswapl(target_fl->l_start);
3707 fl.l_len = tswapl(target_fl->l_len);
3708 fl.l_pid = tswapl(target_fl->l_pid);
3709 unlock_user_struct(target_fl, arg, 0);
3710 ret = get_errno(fcntl(fd, host_cmd, &fl));
3711 if (ret == 0) {
3712 if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
3713 return -TARGET_EFAULT;
3714 target_fl->l_type = tswap16(fl.l_type);
3715 target_fl->l_whence = tswap16(fl.l_whence);
3716 target_fl->l_start = tswapl(fl.l_start);
3717 target_fl->l_len = tswapl(fl.l_len);
3718 target_fl->l_pid = tswapl(fl.l_pid);
3719 unlock_user_struct(target_fl, arg, 1);
3721 break;
3723 case TARGET_F_SETLK:
3724 case TARGET_F_SETLKW:
3725 if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3726 return -TARGET_EFAULT;
3727 fl.l_type = tswap16(target_fl->l_type);
3728 fl.l_whence = tswap16(target_fl->l_whence);
3729 fl.l_start = tswapl(target_fl->l_start);
3730 fl.l_len = tswapl(target_fl->l_len);
3731 fl.l_pid = tswapl(target_fl->l_pid);
3732 unlock_user_struct(target_fl, arg, 0);
3733 ret = get_errno(fcntl(fd, host_cmd, &fl));
3734 break;
3736 case TARGET_F_GETLK64:
3737 if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3738 return -TARGET_EFAULT;
3739 fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3740 fl64.l_whence = tswap16(target_fl64->l_whence);
3741 fl64.l_start = tswapl(target_fl64->l_start);
3742 fl64.l_len = tswapl(target_fl64->l_len);
3743 fl64.l_pid = tswap16(target_fl64->l_pid);
3744 unlock_user_struct(target_fl64, arg, 0);
3745 ret = get_errno(fcntl(fd, host_cmd, &fl64));
3746 if (ret == 0) {
3747 if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
3748 return -TARGET_EFAULT;
3749 target_fl64->l_type = tswap16(fl64.l_type) >> 1;
3750 target_fl64->l_whence = tswap16(fl64.l_whence);
3751 target_fl64->l_start = tswapl(fl64.l_start);
3752 target_fl64->l_len = tswapl(fl64.l_len);
3753 target_fl64->l_pid = tswapl(fl64.l_pid);
3754 unlock_user_struct(target_fl64, arg, 1);
3756 break;
3757 case TARGET_F_SETLK64:
3758 case TARGET_F_SETLKW64:
3759 if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3760 return -TARGET_EFAULT;
3761 fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3762 fl64.l_whence = tswap16(target_fl64->l_whence);
3763 fl64.l_start = tswapl(target_fl64->l_start);
3764 fl64.l_len = tswapl(target_fl64->l_len);
3765 fl64.l_pid = tswap16(target_fl64->l_pid);
3766 unlock_user_struct(target_fl64, arg, 0);
3767 ret = get_errno(fcntl(fd, host_cmd, &fl64));
3768 break;
3770 case TARGET_F_GETFL:
3771 ret = get_errno(fcntl(fd, host_cmd, arg));
3772 if (ret >= 0) {
3773 ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
3775 break;
3777 case TARGET_F_SETFL:
3778 ret = get_errno(fcntl(fd, host_cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
3779 break;
3781 case TARGET_F_SETOWN:
3782 case TARGET_F_GETOWN:
3783 case TARGET_F_SETSIG:
3784 case TARGET_F_GETSIG:
3785 ret = get_errno(fcntl(fd, host_cmd, arg));
3786 break;
3788 default:
3789 ret = get_errno(fcntl(fd, cmd, arg));
3790 break;
3792 return ret;
3795 #ifdef USE_UID16
3797 static inline int high2lowuid(int uid)
3799 if (uid > 65535)
3800 return 65534;
3801 else
3802 return uid;
3805 static inline int high2lowgid(int gid)
3807 if (gid > 65535)
3808 return 65534;
3809 else
3810 return gid;
3813 static inline int low2highuid(int uid)
3815 if ((int16_t)uid == -1)
3816 return -1;
3817 else
3818 return uid;
3821 static inline int low2highgid(int gid)
3823 if ((int16_t)gid == -1)
3824 return -1;
3825 else
3826 return gid;
3829 #endif /* USE_UID16 */
3831 void syscall_init(void)
3833 IOCTLEntry *ie;
3834 const argtype *arg_type;
3835 int size;
3836 int i;
3838 #define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3839 #define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3840 #include "syscall_types.h"
3841 #undef STRUCT
3842 #undef STRUCT_SPECIAL
3844 /* we patch the ioctl size if necessary. We rely on the fact that
3845 no ioctl has all the bits at '1' in the size field */
3846 ie = ioctl_entries;
3847 while (ie->target_cmd != 0) {
3848 if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
3849 TARGET_IOC_SIZEMASK) {
3850 arg_type = ie->arg_type;
3851 if (arg_type[0] != TYPE_PTR) {
3852 fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
3853 ie->target_cmd);
3854 exit(1);
3856 arg_type++;
3857 size = thunk_type_size(arg_type, 0);
3858 ie->target_cmd = (ie->target_cmd &
3859 ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
3860 (size << TARGET_IOC_SIZESHIFT);
3863 /* Build target_to_host_errno_table[] table from
3864 * host_to_target_errno_table[]. */
3865 for (i=0; i < ERRNO_TABLE_SIZE; i++)
3866 target_to_host_errno_table[host_to_target_errno_table[i]] = i;
3868 /* automatic consistency check if same arch */
3869 #if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
3870 (defined(__x86_64__) && defined(TARGET_X86_64))
3871 if (unlikely(ie->target_cmd != ie->host_cmd)) {
3872 fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
3873 ie->name, ie->target_cmd, ie->host_cmd);
3875 #endif
3876 ie++;
3880 #if TARGET_ABI_BITS == 32
3881 static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
3883 #ifdef TARGET_WORDS_BIGENDIAN
3884 return ((uint64_t)word0 << 32) | word1;
3885 #else
3886 return ((uint64_t)word1 << 32) | word0;
3887 #endif
3889 #else /* TARGET_ABI_BITS == 32 */
3890 static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
3892 return word0;
3894 #endif /* TARGET_ABI_BITS != 32 */
3896 #ifdef TARGET_NR_truncate64
3897 static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
3898 abi_long arg2,
3899 abi_long arg3,
3900 abi_long arg4)
3902 #ifdef TARGET_ARM
3903 if (((CPUARMState *)cpu_env)->eabi)
3905 arg2 = arg3;
3906 arg3 = arg4;
3908 #endif
3909 return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
3911 #endif
3913 #ifdef TARGET_NR_ftruncate64
3914 static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
3915 abi_long arg2,
3916 abi_long arg3,
3917 abi_long arg4)
3919 #ifdef TARGET_ARM
3920 if (((CPUARMState *)cpu_env)->eabi)
3922 arg2 = arg3;
3923 arg3 = arg4;
3925 #endif
3926 return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
3928 #endif
3930 static inline abi_long target_to_host_timespec(struct timespec *host_ts,
3931 abi_ulong target_addr)
3933 struct target_timespec *target_ts;
3935 if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
3936 return -TARGET_EFAULT;
3937 host_ts->tv_sec = tswapl(target_ts->tv_sec);
3938 host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
3939 unlock_user_struct(target_ts, target_addr, 0);
3940 return 0;
3943 static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3944 struct timespec *host_ts)
3946 struct target_timespec *target_ts;
3948 if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
3949 return -TARGET_EFAULT;
3950 target_ts->tv_sec = tswapl(host_ts->tv_sec);
3951 target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
3952 unlock_user_struct(target_ts, target_addr, 1);
3953 return 0;
3956 #if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
3957 static inline abi_long host_to_target_stat64(void *cpu_env,
3958 abi_ulong target_addr,
3959 struct stat *host_st)
3961 #ifdef TARGET_ARM
3962 if (((CPUARMState *)cpu_env)->eabi) {
3963 struct target_eabi_stat64 *target_st;
3965 if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3966 return -TARGET_EFAULT;
3967 memset(target_st, 0, sizeof(struct target_eabi_stat64));
3968 __put_user(host_st->st_dev, &target_st->st_dev);
3969 __put_user(host_st->st_ino, &target_st->st_ino);
3970 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3971 __put_user(host_st->st_ino, &target_st->__st_ino);
3972 #endif
3973 __put_user(host_st->st_mode, &target_st->st_mode);
3974 __put_user(host_st->st_nlink, &target_st->st_nlink);
3975 __put_user(host_st->st_uid, &target_st->st_uid);
3976 __put_user(host_st->st_gid, &target_st->st_gid);
3977 __put_user(host_st->st_rdev, &target_st->st_rdev);
3978 __put_user(host_st->st_size, &target_st->st_size);
3979 __put_user(host_st->st_blksize, &target_st->st_blksize);
3980 __put_user(host_st->st_blocks, &target_st->st_blocks);
3981 __put_user(host_st->st_atime, &target_st->target_st_atime);
3982 __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3983 __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3984 unlock_user_struct(target_st, target_addr, 1);
3985 } else
3986 #endif
3988 #if TARGET_LONG_BITS == 64
3989 struct target_stat *target_st;
3990 #else
3991 struct target_stat64 *target_st;
3992 #endif
3994 if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3995 return -TARGET_EFAULT;
3996 memset(target_st, 0, sizeof(*target_st));
3997 __put_user(host_st->st_dev, &target_st->st_dev);
3998 __put_user(host_st->st_ino, &target_st->st_ino);
3999 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4000 __put_user(host_st->st_ino, &target_st->__st_ino);
4001 #endif
4002 __put_user(host_st->st_mode, &target_st->st_mode);
4003 __put_user(host_st->st_nlink, &target_st->st_nlink);
4004 __put_user(host_st->st_uid, &target_st->st_uid);
4005 __put_user(host_st->st_gid, &target_st->st_gid);
4006 __put_user(host_st->st_rdev, &target_st->st_rdev);
4007 /* XXX: better use of kernel struct */
4008 __put_user(host_st->st_size, &target_st->st_size);
4009 __put_user(host_st->st_blksize, &target_st->st_blksize);
4010 __put_user(host_st->st_blocks, &target_st->st_blocks);
4011 __put_user(host_st->st_atime, &target_st->target_st_atime);
4012 __put_user(host_st->st_mtime, &target_st->target_st_mtime);
4013 __put_user(host_st->st_ctime, &target_st->target_st_ctime);
4014 unlock_user_struct(target_st, target_addr, 1);
4017 return 0;
4019 #endif
4021 #if defined(USE_NPTL)
4022 /* ??? Using host futex calls even when target atomic operations
4023 are not really atomic probably breaks things. However implementing
4024 futexes locally would make futexes shared between multiple processes
4025 tricky. However they're probably useless because guest atomic
4026 operations won't work either. */
4027 static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
4028 target_ulong uaddr2, int val3)
4030 struct timespec ts, *pts;
4032 /* ??? We assume FUTEX_* constants are the same on both host
4033 and target. */
4034 #ifdef FUTEX_CMD_MASK
4035 switch ((op&FUTEX_CMD_MASK)) {
4036 #else
4037 switch (op) {
4038 #endif
4039 case FUTEX_WAIT:
4040 if (timeout) {
4041 pts = &ts;
4042 target_to_host_timespec(pts, timeout);
4043 } else {
4044 pts = NULL;
4046 return get_errno(sys_futex(g2h(uaddr), op, tswap32(val),
4047 pts, NULL, 0));
4048 case FUTEX_WAKE:
4049 return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4050 case FUTEX_WAKE_OP:
4051 return get_errno(sys_futex(g2h(uaddr), op, val, NULL, g2h(uaddr2), val3 ));
4052 case FUTEX_FD:
4053 return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4054 case FUTEX_REQUEUE:
4055 return get_errno(sys_futex(g2h(uaddr), op, val,
4056 NULL, g2h(uaddr2), 0));
4057 case FUTEX_CMP_REQUEUE:
4058 return get_errno(sys_futex(g2h(uaddr), op, val,
4059 NULL, g2h(uaddr2), tswap32(val3)));
4060 default:
4061 return -TARGET_ENOSYS;
4064 #endif
4066 /* Map host to target signal numbers for the wait family of syscalls.
4067 Assume all other status bits are the same. */
4068 static int host_to_target_waitstatus(int status)
4070 if (WIFSIGNALED(status)) {
4071 return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f);
4073 if (WIFSTOPPED(status)) {
4074 return (host_to_target_signal(WSTOPSIG(status)) << 8)
4075 | (status & 0xff);
4077 return status;
4080 int get_osversion(void)
4082 static int osversion;
4083 struct new_utsname buf;
4084 const char *s;
4085 int i, n, tmp;
4086 if (osversion)
4087 return osversion;
4088 if (qemu_uname_release && *qemu_uname_release) {
4089 s = qemu_uname_release;
4090 } else {
4091 if (sys_uname(&buf))
4092 return 0;
4093 s = buf.release;
4095 tmp = 0;
4096 for (i = 0; i < 3; i++) {
4097 n = 0;
4098 while (*s >= '0' && *s <= '9') {
4099 n *= 10;
4100 n += *s - '0';
4101 s++;
4103 tmp = (tmp << 8) + n;
4104 if (*s == '.')
4105 s++;
4107 osversion = tmp;
4108 return osversion;
4111 /* do_syscall() should always have a single exit point at the end so
4112 that actions, such as logging of syscall results, can be performed.
4113 All errnos that do_syscall() returns must be -TARGET_<errcode>. */
4114 abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4115 abi_long arg2, abi_long arg3, abi_long arg4,
4116 abi_long arg5, abi_long arg6)
4118 abi_long ret;
4119 struct stat st;
4120 struct statfs stfs;
4121 void *p;
4123 #ifdef DEBUG
4124 gemu_log("syscall %d", num);
4125 #endif
4126 if(do_strace)
4127 print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
4129 switch(num) {
4130 case TARGET_NR_exit:
4131 #ifdef USE_NPTL
4132 /* In old applications this may be used to implement _exit(2).
4133 However in threaded applictions it is used for thread termination,
4134 and _exit_group is used for application termination.
4135 Do thread termination if we have more then one thread. */
4136 /* FIXME: This probably breaks if a signal arrives. We should probably
4137 be disabling signals. */
4138 if (first_cpu->next_cpu) {
4139 TaskState *ts;
4140 CPUState **lastp;
4141 CPUState *p;
4143 cpu_list_lock();
4144 lastp = &first_cpu;
4145 p = first_cpu;
4146 while (p && p != (CPUState *)cpu_env) {
4147 lastp = &p->next_cpu;
4148 p = p->next_cpu;
4150 /* If we didn't find the CPU for this thread then something is
4151 horribly wrong. */
4152 if (!p)
4153 abort();
4154 /* Remove the CPU from the list. */
4155 *lastp = p->next_cpu;
4156 cpu_list_unlock();
4157 ts = ((CPUState *)cpu_env)->opaque;
4158 if (ts->child_tidptr) {
4159 put_user_u32(0, ts->child_tidptr);
4160 sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
4161 NULL, NULL, 0);
4163 /* TODO: Free CPU state. */
4164 pthread_exit(NULL);
4166 #endif
4167 #ifdef HAVE_GPROF
4168 _mcleanup();
4169 #endif
4170 gdb_exit(cpu_env, arg1);
4171 _exit(arg1);
4172 ret = 0; /* avoid warning */
4173 break;
4174 case TARGET_NR_read:
4175 if (arg3 == 0)
4176 ret = 0;
4177 else {
4178 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
4179 goto efault;
4180 ret = get_errno(read(arg1, p, arg3));
4181 unlock_user(p, arg2, ret);
4183 break;
4184 case TARGET_NR_write:
4185 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
4186 goto efault;
4187 ret = get_errno(write(arg1, p, arg3));
4188 unlock_user(p, arg2, 0);
4189 break;
4190 case TARGET_NR_open:
4191 if (!(p = lock_user_string(arg1)))
4192 goto efault;
4193 ret = get_errno(open(path(p),
4194 target_to_host_bitmask(arg2, fcntl_flags_tbl),
4195 arg3));
4196 unlock_user(p, arg1, 0);
4197 break;
4198 #if defined(TARGET_NR_openat) && defined(__NR_openat)
4199 case TARGET_NR_openat:
4200 if (!(p = lock_user_string(arg2)))
4201 goto efault;
4202 ret = get_errno(sys_openat(arg1,
4203 path(p),
4204 target_to_host_bitmask(arg3, fcntl_flags_tbl),
4205 arg4));
4206 unlock_user(p, arg2, 0);
4207 break;
4208 #endif
4209 case TARGET_NR_close:
4210 ret = get_errno(close(arg1));
4211 break;
4212 case TARGET_NR_brk:
4213 ret = do_brk(arg1);
4214 break;
4215 case TARGET_NR_fork:
4216 ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
4217 break;
4218 #ifdef TARGET_NR_waitpid
4219 case TARGET_NR_waitpid:
4221 int status;
4222 ret = get_errno(waitpid(arg1, &status, arg3));
4223 if (!is_error(ret) && arg2
4224 && put_user_s32(host_to_target_waitstatus(status), arg2))
4225 goto efault;
4227 break;
4228 #endif
4229 #ifdef TARGET_NR_waitid
4230 case TARGET_NR_waitid:
4232 siginfo_t info;
4233 info.si_pid = 0;
4234 ret = get_errno(waitid(arg1, arg2, &info, arg4));
4235 if (!is_error(ret) && arg3 && info.si_pid != 0) {
4236 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
4237 goto efault;
4238 host_to_target_siginfo(p, &info);
4239 unlock_user(p, arg3, sizeof(target_siginfo_t));
4242 break;
4243 #endif
4244 #ifdef TARGET_NR_creat /* not on alpha */
4245 case TARGET_NR_creat:
4246 if (!(p = lock_user_string(arg1)))
4247 goto efault;
4248 ret = get_errno(creat(p, arg2));
4249 unlock_user(p, arg1, 0);
4250 break;
4251 #endif
4252 case TARGET_NR_link:
4254 void * p2;
4255 p = lock_user_string(arg1);
4256 p2 = lock_user_string(arg2);
4257 if (!p || !p2)
4258 ret = -TARGET_EFAULT;
4259 else
4260 ret = get_errno(link(p, p2));
4261 unlock_user(p2, arg2, 0);
4262 unlock_user(p, arg1, 0);
4264 break;
4265 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
4266 case TARGET_NR_linkat:
4268 void * p2 = NULL;
4269 if (!arg2 || !arg4)
4270 goto efault;
4271 p = lock_user_string(arg2);
4272 p2 = lock_user_string(arg4);
4273 if (!p || !p2)
4274 ret = -TARGET_EFAULT;
4275 else
4276 ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
4277 unlock_user(p, arg2, 0);
4278 unlock_user(p2, arg4, 0);
4280 break;
4281 #endif
4282 case TARGET_NR_unlink:
4283 if (!(p = lock_user_string(arg1)))
4284 goto efault;
4285 ret = get_errno(unlink(p));
4286 unlock_user(p, arg1, 0);
4287 break;
4288 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
4289 case TARGET_NR_unlinkat:
4290 if (!(p = lock_user_string(arg2)))
4291 goto efault;
4292 ret = get_errno(sys_unlinkat(arg1, p, arg3));
4293 unlock_user(p, arg2, 0);
4294 break;
4295 #endif
4296 case TARGET_NR_execve:
4298 char **argp, **envp;
4299 int argc, envc;
4300 abi_ulong gp;
4301 abi_ulong guest_argp;
4302 abi_ulong guest_envp;
4303 abi_ulong addr;
4304 char **q;
4306 argc = 0;
4307 guest_argp = arg2;
4308 for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
4309 if (get_user_ual(addr, gp))
4310 goto efault;
4311 if (!addr)
4312 break;
4313 argc++;
4315 envc = 0;
4316 guest_envp = arg3;
4317 for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
4318 if (get_user_ual(addr, gp))
4319 goto efault;
4320 if (!addr)
4321 break;
4322 envc++;
4325 argp = alloca((argc + 1) * sizeof(void *));
4326 envp = alloca((envc + 1) * sizeof(void *));
4328 for (gp = guest_argp, q = argp; gp;
4329 gp += sizeof(abi_ulong), q++) {
4330 if (get_user_ual(addr, gp))
4331 goto execve_efault;
4332 if (!addr)
4333 break;
4334 if (!(*q = lock_user_string(addr)))
4335 goto execve_efault;
4337 *q = NULL;
4339 for (gp = guest_envp, q = envp; gp;
4340 gp += sizeof(abi_ulong), q++) {
4341 if (get_user_ual(addr, gp))
4342 goto execve_efault;
4343 if (!addr)
4344 break;
4345 if (!(*q = lock_user_string(addr)))
4346 goto execve_efault;
4348 *q = NULL;
4350 if (!(p = lock_user_string(arg1)))
4351 goto execve_efault;
4352 ret = get_errno(execve(p, argp, envp));
4353 unlock_user(p, arg1, 0);
4355 goto execve_end;
4357 execve_efault:
4358 ret = -TARGET_EFAULT;
4360 execve_end:
4361 for (gp = guest_argp, q = argp; *q;
4362 gp += sizeof(abi_ulong), q++) {
4363 if (get_user_ual(addr, gp)
4364 || !addr)
4365 break;
4366 unlock_user(*q, addr, 0);
4368 for (gp = guest_envp, q = envp; *q;
4369 gp += sizeof(abi_ulong), q++) {
4370 if (get_user_ual(addr, gp)
4371 || !addr)
4372 break;
4373 unlock_user(*q, addr, 0);
4376 break;
4377 case TARGET_NR_chdir:
4378 if (!(p = lock_user_string(arg1)))
4379 goto efault;
4380 ret = get_errno(chdir(p));
4381 unlock_user(p, arg1, 0);
4382 break;
4383 #ifdef TARGET_NR_time
4384 case TARGET_NR_time:
4386 time_t host_time;
4387 ret = get_errno(time(&host_time));
4388 if (!is_error(ret)
4389 && arg1
4390 && put_user_sal(host_time, arg1))
4391 goto efault;
4393 break;
4394 #endif
4395 case TARGET_NR_mknod:
4396 if (!(p = lock_user_string(arg1)))
4397 goto efault;
4398 ret = get_errno(mknod(p, arg2, arg3));
4399 unlock_user(p, arg1, 0);
4400 break;
4401 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
4402 case TARGET_NR_mknodat:
4403 if (!(p = lock_user_string(arg2)))
4404 goto efault;
4405 ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
4406 unlock_user(p, arg2, 0);
4407 break;
4408 #endif
4409 case TARGET_NR_chmod:
4410 if (!(p = lock_user_string(arg1)))
4411 goto efault;
4412 ret = get_errno(chmod(p, arg2));
4413 unlock_user(p, arg1, 0);
4414 break;
4415 #ifdef TARGET_NR_break
4416 case TARGET_NR_break:
4417 goto unimplemented;
4418 #endif
4419 #ifdef TARGET_NR_oldstat
4420 case TARGET_NR_oldstat:
4421 goto unimplemented;
4422 #endif
4423 case TARGET_NR_lseek:
4424 ret = get_errno(lseek(arg1, arg2, arg3));
4425 break;
4426 #ifdef TARGET_NR_getxpid
4427 case TARGET_NR_getxpid:
4428 #else
4429 case TARGET_NR_getpid:
4430 #endif
4431 ret = get_errno(getpid());
4432 break;
4433 case TARGET_NR_mount:
4435 /* need to look at the data field */
4436 void *p2, *p3;
4437 p = lock_user_string(arg1);
4438 p2 = lock_user_string(arg2);
4439 p3 = lock_user_string(arg3);
4440 if (!p || !p2 || !p3)
4441 ret = -TARGET_EFAULT;
4442 else
4443 /* FIXME - arg5 should be locked, but it isn't clear how to
4444 * do that since it's not guaranteed to be a NULL-terminated
4445 * string.
4447 ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
4448 unlock_user(p, arg1, 0);
4449 unlock_user(p2, arg2, 0);
4450 unlock_user(p3, arg3, 0);
4451 break;
4453 #ifdef TARGET_NR_umount
4454 case TARGET_NR_umount:
4455 if (!(p = lock_user_string(arg1)))
4456 goto efault;
4457 ret = get_errno(umount(p));
4458 unlock_user(p, arg1, 0);
4459 break;
4460 #endif
4461 #ifdef TARGET_NR_stime /* not on alpha */
4462 case TARGET_NR_stime:
4464 time_t host_time;
4465 if (get_user_sal(host_time, arg1))
4466 goto efault;
4467 ret = get_errno(stime(&host_time));
4469 break;
4470 #endif
4471 case TARGET_NR_ptrace:
4472 goto unimplemented;
4473 #ifdef TARGET_NR_alarm /* not on alpha */
4474 case TARGET_NR_alarm:
4475 ret = alarm(arg1);
4476 break;
4477 #endif
4478 #ifdef TARGET_NR_oldfstat
4479 case TARGET_NR_oldfstat:
4480 goto unimplemented;
4481 #endif
4482 #ifdef TARGET_NR_pause /* not on alpha */
4483 case TARGET_NR_pause:
4484 ret = get_errno(pause());
4485 break;
4486 #endif
4487 #ifdef TARGET_NR_utime
4488 case TARGET_NR_utime:
4490 struct utimbuf tbuf, *host_tbuf;
4491 struct target_utimbuf *target_tbuf;
4492 if (arg2) {
4493 if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
4494 goto efault;
4495 tbuf.actime = tswapl(target_tbuf->actime);
4496 tbuf.modtime = tswapl(target_tbuf->modtime);
4497 unlock_user_struct(target_tbuf, arg2, 0);
4498 host_tbuf = &tbuf;
4499 } else {
4500 host_tbuf = NULL;
4502 if (!(p = lock_user_string(arg1)))
4503 goto efault;
4504 ret = get_errno(utime(p, host_tbuf));
4505 unlock_user(p, arg1, 0);
4507 break;
4508 #endif
4509 case TARGET_NR_utimes:
4511 struct timeval *tvp, tv[2];
4512 if (arg2) {
4513 if (copy_from_user_timeval(&tv[0], arg2)
4514 || copy_from_user_timeval(&tv[1],
4515 arg2 + sizeof(struct target_timeval)))
4516 goto efault;
4517 tvp = tv;
4518 } else {
4519 tvp = NULL;
4521 if (!(p = lock_user_string(arg1)))
4522 goto efault;
4523 ret = get_errno(utimes(p, tvp));
4524 unlock_user(p, arg1, 0);
4526 break;
4527 #if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
4528 case TARGET_NR_futimesat:
4530 struct timeval *tvp, tv[2];
4531 if (arg3) {
4532 if (copy_from_user_timeval(&tv[0], arg3)
4533 || copy_from_user_timeval(&tv[1],
4534 arg3 + sizeof(struct target_timeval)))
4535 goto efault;
4536 tvp = tv;
4537 } else {
4538 tvp = NULL;
4540 if (!(p = lock_user_string(arg2)))
4541 goto efault;
4542 ret = get_errno(sys_futimesat(arg1, path(p), tvp));
4543 unlock_user(p, arg2, 0);
4545 break;
4546 #endif
4547 #ifdef TARGET_NR_stty
4548 case TARGET_NR_stty:
4549 goto unimplemented;
4550 #endif
4551 #ifdef TARGET_NR_gtty
4552 case TARGET_NR_gtty:
4553 goto unimplemented;
4554 #endif
4555 case TARGET_NR_access:
4556 if (!(p = lock_user_string(arg1)))
4557 goto efault;
4558 ret = get_errno(access(path(p), arg2));
4559 unlock_user(p, arg1, 0);
4560 break;
4561 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
4562 case TARGET_NR_faccessat:
4563 if (!(p = lock_user_string(arg2)))
4564 goto efault;
4565 ret = get_errno(sys_faccessat(arg1, p, arg3));
4566 unlock_user(p, arg2, 0);
4567 break;
4568 #endif
4569 #ifdef TARGET_NR_nice /* not on alpha */
4570 case TARGET_NR_nice:
4571 ret = get_errno(nice(arg1));
4572 break;
4573 #endif
4574 #ifdef TARGET_NR_ftime
4575 case TARGET_NR_ftime:
4576 goto unimplemented;
4577 #endif
4578 case TARGET_NR_sync:
4579 sync();
4580 ret = 0;
4581 break;
4582 case TARGET_NR_kill:
4583 ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
4584 break;
4585 case TARGET_NR_rename:
4587 void *p2;
4588 p = lock_user_string(arg1);
4589 p2 = lock_user_string(arg2);
4590 if (!p || !p2)
4591 ret = -TARGET_EFAULT;
4592 else
4593 ret = get_errno(rename(p, p2));
4594 unlock_user(p2, arg2, 0);
4595 unlock_user(p, arg1, 0);
4597 break;
4598 #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
4599 case TARGET_NR_renameat:
4601 void *p2;
4602 p = lock_user_string(arg2);
4603 p2 = lock_user_string(arg4);
4604 if (!p || !p2)
4605 ret = -TARGET_EFAULT;
4606 else
4607 ret = get_errno(sys_renameat(arg1, p, arg3, p2));
4608 unlock_user(p2, arg4, 0);
4609 unlock_user(p, arg2, 0);
4611 break;
4612 #endif
4613 case TARGET_NR_mkdir:
4614 if (!(p = lock_user_string(arg1)))
4615 goto efault;
4616 ret = get_errno(mkdir(p, arg2));
4617 unlock_user(p, arg1, 0);
4618 break;
4619 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
4620 case TARGET_NR_mkdirat:
4621 if (!(p = lock_user_string(arg2)))
4622 goto efault;
4623 ret = get_errno(sys_mkdirat(arg1, p, arg3));
4624 unlock_user(p, arg2, 0);
4625 break;
4626 #endif
4627 case TARGET_NR_rmdir:
4628 if (!(p = lock_user_string(arg1)))
4629 goto efault;
4630 ret = get_errno(rmdir(p));
4631 unlock_user(p, arg1, 0);
4632 break;
4633 case TARGET_NR_dup:
4634 ret = get_errno(dup(arg1));
4635 break;
4636 case TARGET_NR_pipe:
4637 ret = do_pipe(cpu_env, arg1, 0);
4638 break;
4639 #ifdef TARGET_NR_pipe2
4640 case TARGET_NR_pipe2:
4641 ret = do_pipe(cpu_env, arg1, arg2);
4642 break;
4643 #endif
4644 case TARGET_NR_times:
4646 struct target_tms *tmsp;
4647 struct tms tms;
4648 ret = get_errno(times(&tms));
4649 if (arg1) {
4650 tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
4651 if (!tmsp)
4652 goto efault;
4653 tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
4654 tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
4655 tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
4656 tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime));
4658 if (!is_error(ret))
4659 ret = host_to_target_clock_t(ret);
4661 break;
4662 #ifdef TARGET_NR_prof
4663 case TARGET_NR_prof:
4664 goto unimplemented;
4665 #endif
4666 #ifdef TARGET_NR_signal
4667 case TARGET_NR_signal:
4668 goto unimplemented;
4669 #endif
4670 case TARGET_NR_acct:
4671 if (arg1 == 0) {
4672 ret = get_errno(acct(NULL));
4673 } else {
4674 if (!(p = lock_user_string(arg1)))
4675 goto efault;
4676 ret = get_errno(acct(path(p)));
4677 unlock_user(p, arg1, 0);
4679 break;
4680 #ifdef TARGET_NR_umount2 /* not on alpha */
4681 case TARGET_NR_umount2:
4682 if (!(p = lock_user_string(arg1)))
4683 goto efault;
4684 ret = get_errno(umount2(p, arg2));
4685 unlock_user(p, arg1, 0);
4686 break;
4687 #endif
4688 #ifdef TARGET_NR_lock
4689 case TARGET_NR_lock:
4690 goto unimplemented;
4691 #endif
4692 case TARGET_NR_ioctl:
4693 ret = do_ioctl(arg1, arg2, arg3);
4694 break;
4695 case TARGET_NR_fcntl:
4696 ret = do_fcntl(arg1, arg2, arg3);
4697 break;
4698 #ifdef TARGET_NR_mpx
4699 case TARGET_NR_mpx:
4700 goto unimplemented;
4701 #endif
4702 case TARGET_NR_setpgid:
4703 ret = get_errno(setpgid(arg1, arg2));
4704 break;
4705 #ifdef TARGET_NR_ulimit
4706 case TARGET_NR_ulimit:
4707 goto unimplemented;
4708 #endif
4709 #ifdef TARGET_NR_oldolduname
4710 case TARGET_NR_oldolduname:
4711 goto unimplemented;
4712 #endif
4713 case TARGET_NR_umask:
4714 ret = get_errno(umask(arg1));
4715 break;
4716 case TARGET_NR_chroot:
4717 if (!(p = lock_user_string(arg1)))
4718 goto efault;
4719 ret = get_errno(chroot(p));
4720 unlock_user(p, arg1, 0);
4721 break;
4722 case TARGET_NR_ustat:
4723 goto unimplemented;
4724 case TARGET_NR_dup2:
4725 ret = get_errno(dup2(arg1, arg2));
4726 break;
4727 #ifdef TARGET_NR_getppid /* not on alpha */
4728 case TARGET_NR_getppid:
4729 ret = get_errno(getppid());
4730 break;
4731 #endif
4732 case TARGET_NR_getpgrp:
4733 ret = get_errno(getpgrp());
4734 break;
4735 case TARGET_NR_setsid:
4736 ret = get_errno(setsid());
4737 break;
4738 #ifdef TARGET_NR_sigaction
4739 case TARGET_NR_sigaction:
4741 #if !defined(TARGET_MIPS)
4742 struct target_old_sigaction *old_act;
4743 struct target_sigaction act, oact, *pact;
4744 if (arg2) {
4745 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4746 goto efault;
4747 act._sa_handler = old_act->_sa_handler;
4748 target_siginitset(&act.sa_mask, old_act->sa_mask);
4749 act.sa_flags = old_act->sa_flags;
4750 act.sa_restorer = old_act->sa_restorer;
4751 unlock_user_struct(old_act, arg2, 0);
4752 pact = &act;
4753 } else {
4754 pact = NULL;
4756 ret = get_errno(do_sigaction(arg1, pact, &oact));
4757 if (!is_error(ret) && arg3) {
4758 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4759 goto efault;
4760 old_act->_sa_handler = oact._sa_handler;
4761 old_act->sa_mask = oact.sa_mask.sig[0];
4762 old_act->sa_flags = oact.sa_flags;
4763 old_act->sa_restorer = oact.sa_restorer;
4764 unlock_user_struct(old_act, arg3, 1);
4766 #else
4767 struct target_sigaction act, oact, *pact, *old_act;
4769 if (arg2) {
4770 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4771 goto efault;
4772 act._sa_handler = old_act->_sa_handler;
4773 target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
4774 act.sa_flags = old_act->sa_flags;
4775 unlock_user_struct(old_act, arg2, 0);
4776 pact = &act;
4777 } else {
4778 pact = NULL;
4781 ret = get_errno(do_sigaction(arg1, pact, &oact));
4783 if (!is_error(ret) && arg3) {
4784 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4785 goto efault;
4786 old_act->_sa_handler = oact._sa_handler;
4787 old_act->sa_flags = oact.sa_flags;
4788 old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
4789 old_act->sa_mask.sig[1] = 0;
4790 old_act->sa_mask.sig[2] = 0;
4791 old_act->sa_mask.sig[3] = 0;
4792 unlock_user_struct(old_act, arg3, 1);
4794 #endif
4796 break;
4797 #endif
4798 case TARGET_NR_rt_sigaction:
4800 struct target_sigaction *act;
4801 struct target_sigaction *oact;
4803 if (arg2) {
4804 if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
4805 goto efault;
4806 } else
4807 act = NULL;
4808 if (arg3) {
4809 if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
4810 ret = -TARGET_EFAULT;
4811 goto rt_sigaction_fail;
4813 } else
4814 oact = NULL;
4815 ret = get_errno(do_sigaction(arg1, act, oact));
4816 rt_sigaction_fail:
4817 if (act)
4818 unlock_user_struct(act, arg2, 0);
4819 if (oact)
4820 unlock_user_struct(oact, arg3, 1);
4822 break;
4823 #ifdef TARGET_NR_sgetmask /* not on alpha */
4824 case TARGET_NR_sgetmask:
4826 sigset_t cur_set;
4827 abi_ulong target_set;
4828 sigprocmask(0, NULL, &cur_set);
4829 host_to_target_old_sigset(&target_set, &cur_set);
4830 ret = target_set;
4832 break;
4833 #endif
4834 #ifdef TARGET_NR_ssetmask /* not on alpha */
4835 case TARGET_NR_ssetmask:
4837 sigset_t set, oset, cur_set;
4838 abi_ulong target_set = arg1;
4839 sigprocmask(0, NULL, &cur_set);
4840 target_to_host_old_sigset(&set, &target_set);
4841 sigorset(&set, &set, &cur_set);
4842 sigprocmask(SIG_SETMASK, &set, &oset);
4843 host_to_target_old_sigset(&target_set, &oset);
4844 ret = target_set;
4846 break;
4847 #endif
4848 #ifdef TARGET_NR_sigprocmask
4849 case TARGET_NR_sigprocmask:
4851 int how = arg1;
4852 sigset_t set, oldset, *set_ptr;
4854 if (arg2) {
4855 switch(how) {
4856 case TARGET_SIG_BLOCK:
4857 how = SIG_BLOCK;
4858 break;
4859 case TARGET_SIG_UNBLOCK:
4860 how = SIG_UNBLOCK;
4861 break;
4862 case TARGET_SIG_SETMASK:
4863 how = SIG_SETMASK;
4864 break;
4865 default:
4866 ret = -TARGET_EINVAL;
4867 goto fail;
4869 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4870 goto efault;
4871 target_to_host_old_sigset(&set, p);
4872 unlock_user(p, arg2, 0);
4873 set_ptr = &set;
4874 } else {
4875 how = 0;
4876 set_ptr = NULL;
4878 ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
4879 if (!is_error(ret) && arg3) {
4880 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4881 goto efault;
4882 host_to_target_old_sigset(p, &oldset);
4883 unlock_user(p, arg3, sizeof(target_sigset_t));
4886 break;
4887 #endif
4888 case TARGET_NR_rt_sigprocmask:
4890 int how = arg1;
4891 sigset_t set, oldset, *set_ptr;
4893 if (arg2) {
4894 switch(how) {
4895 case TARGET_SIG_BLOCK:
4896 how = SIG_BLOCK;
4897 break;
4898 case TARGET_SIG_UNBLOCK:
4899 how = SIG_UNBLOCK;
4900 break;
4901 case TARGET_SIG_SETMASK:
4902 how = SIG_SETMASK;
4903 break;
4904 default:
4905 ret = -TARGET_EINVAL;
4906 goto fail;
4908 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4909 goto efault;
4910 target_to_host_sigset(&set, p);
4911 unlock_user(p, arg2, 0);
4912 set_ptr = &set;
4913 } else {
4914 how = 0;
4915 set_ptr = NULL;
4917 ret = get_errno(sigprocmask(how, set_ptr, &oldset));
4918 if (!is_error(ret) && arg3) {
4919 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4920 goto efault;
4921 host_to_target_sigset(p, &oldset);
4922 unlock_user(p, arg3, sizeof(target_sigset_t));
4925 break;
4926 #ifdef TARGET_NR_sigpending
4927 case TARGET_NR_sigpending:
4929 sigset_t set;
4930 ret = get_errno(sigpending(&set));
4931 if (!is_error(ret)) {
4932 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4933 goto efault;
4934 host_to_target_old_sigset(p, &set);
4935 unlock_user(p, arg1, sizeof(target_sigset_t));
4938 break;
4939 #endif
4940 case TARGET_NR_rt_sigpending:
4942 sigset_t set;
4943 ret = get_errno(sigpending(&set));
4944 if (!is_error(ret)) {
4945 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4946 goto efault;
4947 host_to_target_sigset(p, &set);
4948 unlock_user(p, arg1, sizeof(target_sigset_t));
4951 break;
4952 #ifdef TARGET_NR_sigsuspend
4953 case TARGET_NR_sigsuspend:
4955 sigset_t set;
4956 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4957 goto efault;
4958 target_to_host_old_sigset(&set, p);
4959 unlock_user(p, arg1, 0);
4960 ret = get_errno(sigsuspend(&set));
4962 break;
4963 #endif
4964 case TARGET_NR_rt_sigsuspend:
4966 sigset_t set;
4967 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4968 goto efault;
4969 target_to_host_sigset(&set, p);
4970 unlock_user(p, arg1, 0);
4971 ret = get_errno(sigsuspend(&set));
4973 break;
4974 case TARGET_NR_rt_sigtimedwait:
4976 sigset_t set;
4977 struct timespec uts, *puts;
4978 siginfo_t uinfo;
4980 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4981 goto efault;
4982 target_to_host_sigset(&set, p);
4983 unlock_user(p, arg1, 0);
4984 if (arg3) {
4985 puts = &uts;
4986 target_to_host_timespec(puts, arg3);
4987 } else {
4988 puts = NULL;
4990 ret = get_errno(sigtimedwait(&set, &uinfo, puts));
4991 if (!is_error(ret) && arg2) {
4992 if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
4993 goto efault;
4994 host_to_target_siginfo(p, &uinfo);
4995 unlock_user(p, arg2, sizeof(target_siginfo_t));
4998 break;
4999 case TARGET_NR_rt_sigqueueinfo:
5001 siginfo_t uinfo;
5002 if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
5003 goto efault;
5004 target_to_host_siginfo(&uinfo, p);
5005 unlock_user(p, arg1, 0);
5006 ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
5008 break;
5009 #ifdef TARGET_NR_sigreturn
5010 case TARGET_NR_sigreturn:
5011 /* NOTE: ret is eax, so not transcoding must be done */
5012 ret = do_sigreturn(cpu_env);
5013 break;
5014 #endif
5015 case TARGET_NR_rt_sigreturn:
5016 /* NOTE: ret is eax, so not transcoding must be done */
5017 ret = do_rt_sigreturn(cpu_env);
5018 break;
5019 case TARGET_NR_sethostname:
5020 if (!(p = lock_user_string(arg1)))
5021 goto efault;
5022 ret = get_errno(sethostname(p, arg2));
5023 unlock_user(p, arg1, 0);
5024 break;
5025 case TARGET_NR_setrlimit:
5027 /* XXX: convert resource ? */
5028 int resource = arg1;
5029 struct target_rlimit *target_rlim;
5030 struct rlimit rlim;
5031 if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
5032 goto efault;
5033 rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
5034 rlim.rlim_max = tswapl(target_rlim->rlim_max);
5035 unlock_user_struct(target_rlim, arg2, 0);
5036 ret = get_errno(setrlimit(resource, &rlim));
5038 break;
5039 case TARGET_NR_getrlimit:
5041 /* XXX: convert resource ? */
5042 int resource = arg1;
5043 struct target_rlimit *target_rlim;
5044 struct rlimit rlim;
5046 ret = get_errno(getrlimit(resource, &rlim));
5047 if (!is_error(ret)) {
5048 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
5049 goto efault;
5050 target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
5051 target_rlim->rlim_max = tswapl(rlim.rlim_max);
5052 unlock_user_struct(target_rlim, arg2, 1);
5055 break;
5056 case TARGET_NR_getrusage:
5058 struct rusage rusage;
5059 ret = get_errno(getrusage(arg1, &rusage));
5060 if (!is_error(ret)) {
5061 host_to_target_rusage(arg2, &rusage);
5064 break;
5065 case TARGET_NR_gettimeofday:
5067 struct timeval tv;
5068 ret = get_errno(gettimeofday(&tv, NULL));
5069 if (!is_error(ret)) {
5070 if (copy_to_user_timeval(arg1, &tv))
5071 goto efault;
5074 break;
5075 case TARGET_NR_settimeofday:
5077 struct timeval tv;
5078 if (copy_from_user_timeval(&tv, arg1))
5079 goto efault;
5080 ret = get_errno(settimeofday(&tv, NULL));
5082 break;
5083 #ifdef TARGET_NR_select
5084 case TARGET_NR_select:
5086 struct target_sel_arg_struct *sel;
5087 abi_ulong inp, outp, exp, tvp;
5088 long nsel;
5090 if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
5091 goto efault;
5092 nsel = tswapl(sel->n);
5093 inp = tswapl(sel->inp);
5094 outp = tswapl(sel->outp);
5095 exp = tswapl(sel->exp);
5096 tvp = tswapl(sel->tvp);
5097 unlock_user_struct(sel, arg1, 0);
5098 ret = do_select(nsel, inp, outp, exp, tvp);
5100 break;
5101 #endif
5102 case TARGET_NR_symlink:
5104 void *p2;
5105 p = lock_user_string(arg1);
5106 p2 = lock_user_string(arg2);
5107 if (!p || !p2)
5108 ret = -TARGET_EFAULT;
5109 else
5110 ret = get_errno(symlink(p, p2));
5111 unlock_user(p2, arg2, 0);
5112 unlock_user(p, arg1, 0);
5114 break;
5115 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
5116 case TARGET_NR_symlinkat:
5118 void *p2;
5119 p = lock_user_string(arg1);
5120 p2 = lock_user_string(arg3);
5121 if (!p || !p2)
5122 ret = -TARGET_EFAULT;
5123 else
5124 ret = get_errno(sys_symlinkat(p, arg2, p2));
5125 unlock_user(p2, arg3, 0);
5126 unlock_user(p, arg1, 0);
5128 break;
5129 #endif
5130 #ifdef TARGET_NR_oldlstat
5131 case TARGET_NR_oldlstat:
5132 goto unimplemented;
5133 #endif
5134 case TARGET_NR_readlink:
5136 void *p2, *temp;
5137 p = lock_user_string(arg1);
5138 p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
5139 if (!p || !p2)
5140 ret = -TARGET_EFAULT;
5141 else {
5142 if (strncmp((const char *)p, "/proc/self/exe", 14) == 0) {
5143 char real[PATH_MAX];
5144 temp = realpath(exec_path,real);
5145 ret = (temp==NULL) ? get_errno(-1) : strlen(real) ;
5146 snprintf((char *)p2, arg3, "%s", real);
5148 else
5149 ret = get_errno(readlink(path(p), p2, arg3));
5151 unlock_user(p2, arg2, ret);
5152 unlock_user(p, arg1, 0);
5154 break;
5155 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
5156 case TARGET_NR_readlinkat:
5158 void *p2;
5159 p = lock_user_string(arg2);
5160 p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
5161 if (!p || !p2)
5162 ret = -TARGET_EFAULT;
5163 else
5164 ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
5165 unlock_user(p2, arg3, ret);
5166 unlock_user(p, arg2, 0);
5168 break;
5169 #endif
5170 #ifdef TARGET_NR_uselib
5171 case TARGET_NR_uselib:
5172 goto unimplemented;
5173 #endif
5174 #ifdef TARGET_NR_swapon
5175 case TARGET_NR_swapon:
5176 if (!(p = lock_user_string(arg1)))
5177 goto efault;
5178 ret = get_errno(swapon(p, arg2));
5179 unlock_user(p, arg1, 0);
5180 break;
5181 #endif
5182 case TARGET_NR_reboot:
5183 goto unimplemented;
5184 #ifdef TARGET_NR_readdir
5185 case TARGET_NR_readdir:
5186 goto unimplemented;
5187 #endif
5188 #ifdef TARGET_NR_mmap
5189 case TARGET_NR_mmap:
5190 #if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE)
5192 abi_ulong *v;
5193 abi_ulong v1, v2, v3, v4, v5, v6;
5194 if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
5195 goto efault;
5196 v1 = tswapl(v[0]);
5197 v2 = tswapl(v[1]);
5198 v3 = tswapl(v[2]);
5199 v4 = tswapl(v[3]);
5200 v5 = tswapl(v[4]);
5201 v6 = tswapl(v[5]);
5202 unlock_user(v, arg1, 0);
5203 ret = get_errno(target_mmap(v1, v2, v3,
5204 target_to_host_bitmask(v4, mmap_flags_tbl),
5205 v5, v6));
5207 #else
5208 ret = get_errno(target_mmap(arg1, arg2, arg3,
5209 target_to_host_bitmask(arg4, mmap_flags_tbl),
5210 arg5,
5211 arg6));
5212 #endif
5213 break;
5214 #endif
5215 #ifdef TARGET_NR_mmap2
5216 case TARGET_NR_mmap2:
5217 #ifndef MMAP_SHIFT
5218 #define MMAP_SHIFT 12
5219 #endif
5220 ret = get_errno(target_mmap(arg1, arg2, arg3,
5221 target_to_host_bitmask(arg4, mmap_flags_tbl),
5222 arg5,
5223 arg6 << MMAP_SHIFT));
5224 break;
5225 #endif
5226 case TARGET_NR_munmap:
5227 ret = get_errno(target_munmap(arg1, arg2));
5228 break;
5229 case TARGET_NR_mprotect:
5230 ret = get_errno(target_mprotect(arg1, arg2, arg3));
5231 break;
5232 #ifdef TARGET_NR_mremap
5233 case TARGET_NR_mremap:
5234 ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
5235 break;
5236 #endif
5237 /* ??? msync/mlock/munlock are broken for softmmu. */
5238 #ifdef TARGET_NR_msync
5239 case TARGET_NR_msync:
5240 ret = get_errno(msync(g2h(arg1), arg2, arg3));
5241 break;
5242 #endif
5243 #ifdef TARGET_NR_mlock
5244 case TARGET_NR_mlock:
5245 ret = get_errno(mlock(g2h(arg1), arg2));
5246 break;
5247 #endif
5248 #ifdef TARGET_NR_munlock
5249 case TARGET_NR_munlock:
5250 ret = get_errno(munlock(g2h(arg1), arg2));
5251 break;
5252 #endif
5253 #ifdef TARGET_NR_mlockall
5254 case TARGET_NR_mlockall:
5255 ret = get_errno(mlockall(arg1));
5256 break;
5257 #endif
5258 #ifdef TARGET_NR_munlockall
5259 case TARGET_NR_munlockall:
5260 ret = get_errno(munlockall());
5261 break;
5262 #endif
5263 case TARGET_NR_truncate:
5264 if (!(p = lock_user_string(arg1)))
5265 goto efault;
5266 ret = get_errno(truncate(p, arg2));
5267 unlock_user(p, arg1, 0);
5268 break;
5269 case TARGET_NR_ftruncate:
5270 ret = get_errno(ftruncate(arg1, arg2));
5271 break;
5272 case TARGET_NR_fchmod:
5273 ret = get_errno(fchmod(arg1, arg2));
5274 break;
5275 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
5276 case TARGET_NR_fchmodat:
5277 if (!(p = lock_user_string(arg2)))
5278 goto efault;
5279 ret = get_errno(sys_fchmodat(arg1, p, arg3));
5280 unlock_user(p, arg2, 0);
5281 break;
5282 #endif
5283 case TARGET_NR_getpriority:
5284 /* libc does special remapping of the return value of
5285 * sys_getpriority() so it's just easiest to call
5286 * sys_getpriority() directly rather than through libc. */
5287 ret = sys_getpriority(arg1, arg2);
5288 break;
5289 case TARGET_NR_setpriority:
5290 ret = get_errno(setpriority(arg1, arg2, arg3));
5291 break;
5292 #ifdef TARGET_NR_profil
5293 case TARGET_NR_profil:
5294 goto unimplemented;
5295 #endif
5296 case TARGET_NR_statfs:
5297 if (!(p = lock_user_string(arg1)))
5298 goto efault;
5299 ret = get_errno(statfs(path(p), &stfs));
5300 unlock_user(p, arg1, 0);
5301 convert_statfs:
5302 if (!is_error(ret)) {
5303 struct target_statfs *target_stfs;
5305 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
5306 goto efault;
5307 __put_user(stfs.f_type, &target_stfs->f_type);
5308 __put_user(stfs.f_bsize, &target_stfs->f_bsize);
5309 __put_user(stfs.f_blocks, &target_stfs->f_blocks);
5310 __put_user(stfs.f_bfree, &target_stfs->f_bfree);
5311 __put_user(stfs.f_bavail, &target_stfs->f_bavail);
5312 __put_user(stfs.f_files, &target_stfs->f_files);
5313 __put_user(stfs.f_ffree, &target_stfs->f_ffree);
5314 __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
5315 __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
5316 __put_user(stfs.f_namelen, &target_stfs->f_namelen);
5317 unlock_user_struct(target_stfs, arg2, 1);
5319 break;
5320 case TARGET_NR_fstatfs:
5321 ret = get_errno(fstatfs(arg1, &stfs));
5322 goto convert_statfs;
5323 #ifdef TARGET_NR_statfs64
5324 case TARGET_NR_statfs64:
5325 if (!(p = lock_user_string(arg1)))
5326 goto efault;
5327 ret = get_errno(statfs(path(p), &stfs));
5328 unlock_user(p, arg1, 0);
5329 convert_statfs64:
5330 if (!is_error(ret)) {
5331 struct target_statfs64 *target_stfs;
5333 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
5334 goto efault;
5335 __put_user(stfs.f_type, &target_stfs->f_type);
5336 __put_user(stfs.f_bsize, &target_stfs->f_bsize);
5337 __put_user(stfs.f_blocks, &target_stfs->f_blocks);
5338 __put_user(stfs.f_bfree, &target_stfs->f_bfree);
5339 __put_user(stfs.f_bavail, &target_stfs->f_bavail);
5340 __put_user(stfs.f_files, &target_stfs->f_files);
5341 __put_user(stfs.f_ffree, &target_stfs->f_ffree);
5342 __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
5343 __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
5344 __put_user(stfs.f_namelen, &target_stfs->f_namelen);
5345 unlock_user_struct(target_stfs, arg3, 1);
5347 break;
5348 case TARGET_NR_fstatfs64:
5349 ret = get_errno(fstatfs(arg1, &stfs));
5350 goto convert_statfs64;
5351 #endif
5352 #ifdef TARGET_NR_ioperm
5353 case TARGET_NR_ioperm:
5354 goto unimplemented;
5355 #endif
5356 #ifdef TARGET_NR_socketcall
5357 case TARGET_NR_socketcall:
5358 ret = do_socketcall(arg1, arg2);
5359 break;
5360 #endif
5361 #ifdef TARGET_NR_accept
5362 case TARGET_NR_accept:
5363 ret = do_accept(arg1, arg2, arg3);
5364 break;
5365 #endif
5366 #ifdef TARGET_NR_bind
5367 case TARGET_NR_bind:
5368 ret = do_bind(arg1, arg2, arg3);
5369 break;
5370 #endif
5371 #ifdef TARGET_NR_connect
5372 case TARGET_NR_connect:
5373 ret = do_connect(arg1, arg2, arg3);
5374 break;
5375 #endif
5376 #ifdef TARGET_NR_getpeername
5377 case TARGET_NR_getpeername:
5378 ret = do_getpeername(arg1, arg2, arg3);
5379 break;
5380 #endif
5381 #ifdef TARGET_NR_getsockname
5382 case TARGET_NR_getsockname:
5383 ret = do_getsockname(arg1, arg2, arg3);
5384 break;
5385 #endif
5386 #ifdef TARGET_NR_getsockopt
5387 case TARGET_NR_getsockopt:
5388 ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
5389 break;
5390 #endif
5391 #ifdef TARGET_NR_listen
5392 case TARGET_NR_listen:
5393 ret = get_errno(listen(arg1, arg2));
5394 break;
5395 #endif
5396 #ifdef TARGET_NR_recv
5397 case TARGET_NR_recv:
5398 ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
5399 break;
5400 #endif
5401 #ifdef TARGET_NR_recvfrom
5402 case TARGET_NR_recvfrom:
5403 ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
5404 break;
5405 #endif
5406 #ifdef TARGET_NR_recvmsg
5407 case TARGET_NR_recvmsg:
5408 ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
5409 break;
5410 #endif
5411 #ifdef TARGET_NR_send
5412 case TARGET_NR_send:
5413 ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
5414 break;
5415 #endif
5416 #ifdef TARGET_NR_sendmsg
5417 case TARGET_NR_sendmsg:
5418 ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
5419 break;
5420 #endif
5421 #ifdef TARGET_NR_sendto
5422 case TARGET_NR_sendto:
5423 ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
5424 break;
5425 #endif
5426 #ifdef TARGET_NR_shutdown
5427 case TARGET_NR_shutdown:
5428 ret = get_errno(shutdown(arg1, arg2));
5429 break;
5430 #endif
5431 #ifdef TARGET_NR_socket
5432 case TARGET_NR_socket:
5433 ret = do_socket(arg1, arg2, arg3);
5434 break;
5435 #endif
5436 #ifdef TARGET_NR_socketpair
5437 case TARGET_NR_socketpair:
5438 ret = do_socketpair(arg1, arg2, arg3, arg4);
5439 break;
5440 #endif
5441 #ifdef TARGET_NR_setsockopt
5442 case TARGET_NR_setsockopt:
5443 ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
5444 break;
5445 #endif
5447 case TARGET_NR_syslog:
5448 if (!(p = lock_user_string(arg2)))
5449 goto efault;
5450 ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
5451 unlock_user(p, arg2, 0);
5452 break;
5454 case TARGET_NR_setitimer:
5456 struct itimerval value, ovalue, *pvalue;
5458 if (arg2) {
5459 pvalue = &value;
5460 if (copy_from_user_timeval(&pvalue->it_interval, arg2)
5461 || copy_from_user_timeval(&pvalue->it_value,
5462 arg2 + sizeof(struct target_timeval)))
5463 goto efault;
5464 } else {
5465 pvalue = NULL;
5467 ret = get_errno(setitimer(arg1, pvalue, &ovalue));
5468 if (!is_error(ret) && arg3) {
5469 if (copy_to_user_timeval(arg3,
5470 &ovalue.it_interval)
5471 || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
5472 &ovalue.it_value))
5473 goto efault;
5476 break;
5477 case TARGET_NR_getitimer:
5479 struct itimerval value;
5481 ret = get_errno(getitimer(arg1, &value));
5482 if (!is_error(ret) && arg2) {
5483 if (copy_to_user_timeval(arg2,
5484 &value.it_interval)
5485 || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
5486 &value.it_value))
5487 goto efault;
5490 break;
5491 case TARGET_NR_stat:
5492 if (!(p = lock_user_string(arg1)))
5493 goto efault;
5494 ret = get_errno(stat(path(p), &st));
5495 unlock_user(p, arg1, 0);
5496 goto do_stat;
5497 case TARGET_NR_lstat:
5498 if (!(p = lock_user_string(arg1)))
5499 goto efault;
5500 ret = get_errno(lstat(path(p), &st));
5501 unlock_user(p, arg1, 0);
5502 goto do_stat;
5503 case TARGET_NR_fstat:
5505 ret = get_errno(fstat(arg1, &st));
5506 do_stat:
5507 if (!is_error(ret)) {
5508 struct target_stat *target_st;
5510 if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
5511 goto efault;
5512 __put_user(st.st_dev, &target_st->st_dev);
5513 __put_user(st.st_ino, &target_st->st_ino);
5514 __put_user(st.st_mode, &target_st->st_mode);
5515 __put_user(st.st_uid, &target_st->st_uid);
5516 __put_user(st.st_gid, &target_st->st_gid);
5517 __put_user(st.st_nlink, &target_st->st_nlink);
5518 __put_user(st.st_rdev, &target_st->st_rdev);
5519 __put_user(st.st_size, &target_st->st_size);
5520 __put_user(st.st_blksize, &target_st->st_blksize);
5521 __put_user(st.st_blocks, &target_st->st_blocks);
5522 __put_user(st.st_atime, &target_st->target_st_atime);
5523 __put_user(st.st_mtime, &target_st->target_st_mtime);
5524 __put_user(st.st_ctime, &target_st->target_st_ctime);
5525 unlock_user_struct(target_st, arg2, 1);
5528 break;
5529 #ifdef TARGET_NR_olduname
5530 case TARGET_NR_olduname:
5531 goto unimplemented;
5532 #endif
5533 #ifdef TARGET_NR_iopl
5534 case TARGET_NR_iopl:
5535 goto unimplemented;
5536 #endif
5537 case TARGET_NR_vhangup:
5538 ret = get_errno(vhangup());
5539 break;
5540 #ifdef TARGET_NR_idle
5541 case TARGET_NR_idle:
5542 goto unimplemented;
5543 #endif
5544 #ifdef TARGET_NR_syscall
5545 case TARGET_NR_syscall:
5546 ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
5547 break;
5548 #endif
5549 case TARGET_NR_wait4:
5551 int status;
5552 abi_long status_ptr = arg2;
5553 struct rusage rusage, *rusage_ptr;
5554 abi_ulong target_rusage = arg4;
5555 if (target_rusage)
5556 rusage_ptr = &rusage;
5557 else
5558 rusage_ptr = NULL;
5559 ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
5560 if (!is_error(ret)) {
5561 if (status_ptr) {
5562 status = host_to_target_waitstatus(status);
5563 if (put_user_s32(status, status_ptr))
5564 goto efault;
5566 if (target_rusage)
5567 host_to_target_rusage(target_rusage, &rusage);
5570 break;
5571 #ifdef TARGET_NR_swapoff
5572 case TARGET_NR_swapoff:
5573 if (!(p = lock_user_string(arg1)))
5574 goto efault;
5575 ret = get_errno(swapoff(p));
5576 unlock_user(p, arg1, 0);
5577 break;
5578 #endif
5579 case TARGET_NR_sysinfo:
5581 struct target_sysinfo *target_value;
5582 struct sysinfo value;
5583 ret = get_errno(sysinfo(&value));
5584 if (!is_error(ret) && arg1)
5586 if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
5587 goto efault;
5588 __put_user(value.uptime, &target_value->uptime);
5589 __put_user(value.loads[0], &target_value->loads[0]);
5590 __put_user(value.loads[1], &target_value->loads[1]);
5591 __put_user(value.loads[2], &target_value->loads[2]);
5592 __put_user(value.totalram, &target_value->totalram);
5593 __put_user(value.freeram, &target_value->freeram);
5594 __put_user(value.sharedram, &target_value->sharedram);
5595 __put_user(value.bufferram, &target_value->bufferram);
5596 __put_user(value.totalswap, &target_value->totalswap);
5597 __put_user(value.freeswap, &target_value->freeswap);
5598 __put_user(value.procs, &target_value->procs);
5599 __put_user(value.totalhigh, &target_value->totalhigh);
5600 __put_user(value.freehigh, &target_value->freehigh);
5601 __put_user(value.mem_unit, &target_value->mem_unit);
5602 unlock_user_struct(target_value, arg1, 1);
5605 break;
5606 #ifdef TARGET_NR_ipc
5607 case TARGET_NR_ipc:
5608 ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
5609 break;
5610 #endif
5611 #ifdef TARGET_NR_semget
5612 case TARGET_NR_semget:
5613 ret = get_errno(semget(arg1, arg2, arg3));
5614 break;
5615 #endif
5616 #ifdef TARGET_NR_semop
5617 case TARGET_NR_semop:
5618 ret = get_errno(do_semop(arg1, arg2, arg3));
5619 break;
5620 #endif
5621 #ifdef TARGET_NR_semctl
5622 case TARGET_NR_semctl:
5623 ret = do_semctl(arg1, arg2, arg3, (union target_semun)(abi_ulong)arg4);
5624 break;
5625 #endif
5626 #ifdef TARGET_NR_msgctl
5627 case TARGET_NR_msgctl:
5628 ret = do_msgctl(arg1, arg2, arg3);
5629 break;
5630 #endif
5631 #ifdef TARGET_NR_msgget
5632 case TARGET_NR_msgget:
5633 ret = get_errno(msgget(arg1, arg2));
5634 break;
5635 #endif
5636 #ifdef TARGET_NR_msgrcv
5637 case TARGET_NR_msgrcv:
5638 ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
5639 break;
5640 #endif
5641 #ifdef TARGET_NR_msgsnd
5642 case TARGET_NR_msgsnd:
5643 ret = do_msgsnd(arg1, arg2, arg3, arg4);
5644 break;
5645 #endif
5646 #ifdef TARGET_NR_shmget
5647 case TARGET_NR_shmget:
5648 ret = get_errno(shmget(arg1, arg2, arg3));
5649 break;
5650 #endif
5651 #ifdef TARGET_NR_shmctl
5652 case TARGET_NR_shmctl:
5653 ret = do_shmctl(arg1, arg2, arg3);
5654 break;
5655 #endif
5656 #ifdef TARGET_NR_shmat
5657 case TARGET_NR_shmat:
5658 ret = do_shmat(arg1, arg2, arg3);
5659 break;
5660 #endif
5661 #ifdef TARGET_NR_shmdt
5662 case TARGET_NR_shmdt:
5663 ret = do_shmdt(arg1);
5664 break;
5665 #endif
5666 case TARGET_NR_fsync:
5667 ret = get_errno(fsync(arg1));
5668 break;
5669 case TARGET_NR_clone:
5670 #if defined(TARGET_SH4)
5671 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
5672 #elif defined(TARGET_CRIS)
5673 ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg4, arg5));
5674 #else
5675 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
5676 #endif
5677 break;
5678 #ifdef __NR_exit_group
5679 /* new thread calls */
5680 case TARGET_NR_exit_group:
5681 #ifdef HAVE_GPROF
5682 _mcleanup();
5683 #endif
5684 gdb_exit(cpu_env, arg1);
5685 ret = get_errno(exit_group(arg1));
5686 break;
5687 #endif
5688 case TARGET_NR_setdomainname:
5689 if (!(p = lock_user_string(arg1)))
5690 goto efault;
5691 ret = get_errno(setdomainname(p, arg2));
5692 unlock_user(p, arg1, 0);
5693 break;
5694 case TARGET_NR_uname:
5695 /* no need to transcode because we use the linux syscall */
5697 struct new_utsname * buf;
5699 if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
5700 goto efault;
5701 ret = get_errno(sys_uname(buf));
5702 if (!is_error(ret)) {
5703 /* Overrite the native machine name with whatever is being
5704 emulated. */
5705 strcpy (buf->machine, UNAME_MACHINE);
5706 /* Allow the user to override the reported release. */
5707 if (qemu_uname_release && *qemu_uname_release)
5708 strcpy (buf->release, qemu_uname_release);
5710 unlock_user_struct(buf, arg1, 1);
5712 break;
5713 #ifdef TARGET_I386
5714 case TARGET_NR_modify_ldt:
5715 ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
5716 break;
5717 #if !defined(TARGET_X86_64)
5718 case TARGET_NR_vm86old:
5719 goto unimplemented;
5720 case TARGET_NR_vm86:
5721 ret = do_vm86(cpu_env, arg1, arg2);
5722 break;
5723 #endif
5724 #endif
5725 case TARGET_NR_adjtimex:
5726 goto unimplemented;
5727 #ifdef TARGET_NR_create_module
5728 case TARGET_NR_create_module:
5729 #endif
5730 case TARGET_NR_init_module:
5731 case TARGET_NR_delete_module:
5732 #ifdef TARGET_NR_get_kernel_syms
5733 case TARGET_NR_get_kernel_syms:
5734 #endif
5735 goto unimplemented;
5736 case TARGET_NR_quotactl:
5737 goto unimplemented;
5738 case TARGET_NR_getpgid:
5739 ret = get_errno(getpgid(arg1));
5740 break;
5741 case TARGET_NR_fchdir:
5742 ret = get_errno(fchdir(arg1));
5743 break;
5744 #ifdef TARGET_NR_bdflush /* not on x86_64 */
5745 case TARGET_NR_bdflush:
5746 goto unimplemented;
5747 #endif
5748 #ifdef TARGET_NR_sysfs
5749 case TARGET_NR_sysfs:
5750 goto unimplemented;
5751 #endif
5752 case TARGET_NR_personality:
5753 ret = get_errno(personality(arg1));
5754 break;
5755 #ifdef TARGET_NR_afs_syscall
5756 case TARGET_NR_afs_syscall:
5757 goto unimplemented;
5758 #endif
5759 #ifdef TARGET_NR__llseek /* Not on alpha */
5760 case TARGET_NR__llseek:
5762 #if defined (__x86_64__)
5763 ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
5764 if (put_user_s64(ret, arg4))
5765 goto efault;
5766 #else
5767 int64_t res;
5768 ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
5769 if (put_user_s64(res, arg4))
5770 goto efault;
5771 #endif
5773 break;
5774 #endif
5775 case TARGET_NR_getdents:
5776 #if TARGET_ABI_BITS != 32
5777 goto unimplemented;
5778 #elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
5780 struct target_dirent *target_dirp;
5781 struct linux_dirent *dirp;
5782 abi_long count = arg3;
5784 dirp = malloc(count);
5785 if (!dirp) {
5786 ret = -TARGET_ENOMEM;
5787 goto fail;
5790 ret = get_errno(sys_getdents(arg1, dirp, count));
5791 if (!is_error(ret)) {
5792 struct linux_dirent *de;
5793 struct target_dirent *tde;
5794 int len = ret;
5795 int reclen, treclen;
5796 int count1, tnamelen;
5798 count1 = 0;
5799 de = dirp;
5800 if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5801 goto efault;
5802 tde = target_dirp;
5803 while (len > 0) {
5804 reclen = de->d_reclen;
5805 treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
5806 tde->d_reclen = tswap16(treclen);
5807 tde->d_ino = tswapl(de->d_ino);
5808 tde->d_off = tswapl(de->d_off);
5809 tnamelen = treclen - (2 * sizeof(abi_long) + 2);
5810 if (tnamelen > 256)
5811 tnamelen = 256;
5812 /* XXX: may not be correct */
5813 pstrcpy(tde->d_name, tnamelen, de->d_name);
5814 de = (struct linux_dirent *)((char *)de + reclen);
5815 len -= reclen;
5816 tde = (struct target_dirent *)((char *)tde + treclen);
5817 count1 += treclen;
5819 ret = count1;
5820 unlock_user(target_dirp, arg2, ret);
5822 free(dirp);
5824 #else
5826 struct linux_dirent *dirp;
5827 abi_long count = arg3;
5829 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5830 goto efault;
5831 ret = get_errno(sys_getdents(arg1, dirp, count));
5832 if (!is_error(ret)) {
5833 struct linux_dirent *de;
5834 int len = ret;
5835 int reclen;
5836 de = dirp;
5837 while (len > 0) {
5838 reclen = de->d_reclen;
5839 if (reclen > len)
5840 break;
5841 de->d_reclen = tswap16(reclen);
5842 tswapls(&de->d_ino);
5843 tswapls(&de->d_off);
5844 de = (struct linux_dirent *)((char *)de + reclen);
5845 len -= reclen;
5848 unlock_user(dirp, arg2, ret);
5850 #endif
5851 break;
5852 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
5853 case TARGET_NR_getdents64:
5855 struct linux_dirent64 *dirp;
5856 abi_long count = arg3;
5857 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5858 goto efault;
5859 ret = get_errno(sys_getdents64(arg1, dirp, count));
5860 if (!is_error(ret)) {
5861 struct linux_dirent64 *de;
5862 int len = ret;
5863 int reclen;
5864 de = dirp;
5865 while (len > 0) {
5866 reclen = de->d_reclen;
5867 if (reclen > len)
5868 break;
5869 de->d_reclen = tswap16(reclen);
5870 tswap64s((uint64_t *)&de->d_ino);
5871 tswap64s((uint64_t *)&de->d_off);
5872 de = (struct linux_dirent64 *)((char *)de + reclen);
5873 len -= reclen;
5876 unlock_user(dirp, arg2, ret);
5878 break;
5879 #endif /* TARGET_NR_getdents64 */
5880 #ifdef TARGET_NR__newselect
5881 case TARGET_NR__newselect:
5882 ret = do_select(arg1, arg2, arg3, arg4, arg5);
5883 break;
5884 #endif
5885 #ifdef TARGET_NR_poll
5886 case TARGET_NR_poll:
5888 struct target_pollfd *target_pfd;
5889 unsigned int nfds = arg2;
5890 int timeout = arg3;
5891 struct pollfd *pfd;
5892 unsigned int i;
5894 target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
5895 if (!target_pfd)
5896 goto efault;
5897 pfd = alloca(sizeof(struct pollfd) * nfds);
5898 for(i = 0; i < nfds; i++) {
5899 pfd[i].fd = tswap32(target_pfd[i].fd);
5900 pfd[i].events = tswap16(target_pfd[i].events);
5902 ret = get_errno(poll(pfd, nfds, timeout));
5903 if (!is_error(ret)) {
5904 for(i = 0; i < nfds; i++) {
5905 target_pfd[i].revents = tswap16(pfd[i].revents);
5907 ret += nfds * (sizeof(struct target_pollfd)
5908 - sizeof(struct pollfd));
5910 unlock_user(target_pfd, arg1, ret);
5912 break;
5913 #endif
5914 case TARGET_NR_flock:
5915 /* NOTE: the flock constant seems to be the same for every
5916 Linux platform */
5917 ret = get_errno(flock(arg1, arg2));
5918 break;
5919 case TARGET_NR_readv:
5921 int count = arg3;
5922 struct iovec *vec;
5924 vec = alloca(count * sizeof(struct iovec));
5925 if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
5926 goto efault;
5927 ret = get_errno(readv(arg1, vec, count));
5928 unlock_iovec(vec, arg2, count, 1);
5930 break;
5931 case TARGET_NR_writev:
5933 int count = arg3;
5934 struct iovec *vec;
5936 vec = alloca(count * sizeof(struct iovec));
5937 if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
5938 goto efault;
5939 ret = get_errno(writev(arg1, vec, count));
5940 unlock_iovec(vec, arg2, count, 0);
5942 break;
5943 case TARGET_NR_getsid:
5944 ret = get_errno(getsid(arg1));
5945 break;
5946 #if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
5947 case TARGET_NR_fdatasync:
5948 ret = get_errno(fdatasync(arg1));
5949 break;
5950 #endif
5951 case TARGET_NR__sysctl:
5952 /* We don't implement this, but ENOTDIR is always a safe
5953 return value. */
5954 ret = -TARGET_ENOTDIR;
5955 break;
5956 case TARGET_NR_sched_setparam:
5958 struct sched_param *target_schp;
5959 struct sched_param schp;
5961 if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
5962 goto efault;
5963 schp.sched_priority = tswap32(target_schp->sched_priority);
5964 unlock_user_struct(target_schp, arg2, 0);
5965 ret = get_errno(sched_setparam(arg1, &schp));
5967 break;
5968 case TARGET_NR_sched_getparam:
5970 struct sched_param *target_schp;
5971 struct sched_param schp;
5972 ret = get_errno(sched_getparam(arg1, &schp));
5973 if (!is_error(ret)) {
5974 if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
5975 goto efault;
5976 target_schp->sched_priority = tswap32(schp.sched_priority);
5977 unlock_user_struct(target_schp, arg2, 1);
5980 break;
5981 case TARGET_NR_sched_setscheduler:
5983 struct sched_param *target_schp;
5984 struct sched_param schp;
5985 if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
5986 goto efault;
5987 schp.sched_priority = tswap32(target_schp->sched_priority);
5988 unlock_user_struct(target_schp, arg3, 0);
5989 ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
5991 break;
5992 case TARGET_NR_sched_getscheduler:
5993 ret = get_errno(sched_getscheduler(arg1));
5994 break;
5995 case TARGET_NR_sched_yield:
5996 ret = get_errno(sched_yield());
5997 break;
5998 case TARGET_NR_sched_get_priority_max:
5999 ret = get_errno(sched_get_priority_max(arg1));
6000 break;
6001 case TARGET_NR_sched_get_priority_min:
6002 ret = get_errno(sched_get_priority_min(arg1));
6003 break;
6004 case TARGET_NR_sched_rr_get_interval:
6006 struct timespec ts;
6007 ret = get_errno(sched_rr_get_interval(arg1, &ts));
6008 if (!is_error(ret)) {
6009 host_to_target_timespec(arg2, &ts);
6012 break;
6013 case TARGET_NR_nanosleep:
6015 struct timespec req, rem;
6016 target_to_host_timespec(&req, arg1);
6017 ret = get_errno(nanosleep(&req, &rem));
6018 if (is_error(ret) && arg2) {
6019 host_to_target_timespec(arg2, &rem);
6022 break;
6023 #ifdef TARGET_NR_query_module
6024 case TARGET_NR_query_module:
6025 goto unimplemented;
6026 #endif
6027 #ifdef TARGET_NR_nfsservctl
6028 case TARGET_NR_nfsservctl:
6029 goto unimplemented;
6030 #endif
6031 case TARGET_NR_prctl:
6032 switch (arg1)
6034 case PR_GET_PDEATHSIG:
6036 int deathsig;
6037 ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
6038 if (!is_error(ret) && arg2
6039 && put_user_ual(deathsig, arg2))
6040 goto efault;
6042 break;
6043 default:
6044 ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
6045 break;
6047 break;
6048 #ifdef TARGET_NR_arch_prctl
6049 case TARGET_NR_arch_prctl:
6050 #if defined(TARGET_I386) && !defined(TARGET_ABI32)
6051 ret = do_arch_prctl(cpu_env, arg1, arg2);
6052 break;
6053 #else
6054 goto unimplemented;
6055 #endif
6056 #endif
6057 #ifdef TARGET_NR_pread
6058 case TARGET_NR_pread:
6059 #ifdef TARGET_ARM
6060 if (((CPUARMState *)cpu_env)->eabi)
6061 arg4 = arg5;
6062 #endif
6063 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
6064 goto efault;
6065 ret = get_errno(pread(arg1, p, arg3, arg4));
6066 unlock_user(p, arg2, ret);
6067 break;
6068 case TARGET_NR_pwrite:
6069 #ifdef TARGET_ARM
6070 if (((CPUARMState *)cpu_env)->eabi)
6071 arg4 = arg5;
6072 #endif
6073 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
6074 goto efault;
6075 ret = get_errno(pwrite(arg1, p, arg3, arg4));
6076 unlock_user(p, arg2, 0);
6077 break;
6078 #endif
6079 #ifdef TARGET_NR_pread64
6080 case TARGET_NR_pread64:
6081 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
6082 goto efault;
6083 ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
6084 unlock_user(p, arg2, ret);
6085 break;
6086 case TARGET_NR_pwrite64:
6087 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
6088 goto efault;
6089 ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
6090 unlock_user(p, arg2, 0);
6091 break;
6092 #endif
6093 case TARGET_NR_getcwd:
6094 if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
6095 goto efault;
6096 ret = get_errno(sys_getcwd1(p, arg2));
6097 unlock_user(p, arg1, ret);
6098 break;
6099 case TARGET_NR_capget:
6100 goto unimplemented;
6101 case TARGET_NR_capset:
6102 goto unimplemented;
6103 case TARGET_NR_sigaltstack:
6104 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
6105 defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA)
6106 ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env));
6107 break;
6108 #else
6109 goto unimplemented;
6110 #endif
6111 case TARGET_NR_sendfile:
6112 goto unimplemented;
6113 #ifdef TARGET_NR_getpmsg
6114 case TARGET_NR_getpmsg:
6115 goto unimplemented;
6116 #endif
6117 #ifdef TARGET_NR_putpmsg
6118 case TARGET_NR_putpmsg:
6119 goto unimplemented;
6120 #endif
6121 #ifdef TARGET_NR_vfork
6122 case TARGET_NR_vfork:
6123 ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
6124 0, 0, 0, 0));
6125 break;
6126 #endif
6127 #ifdef TARGET_NR_ugetrlimit
6128 case TARGET_NR_ugetrlimit:
6130 struct rlimit rlim;
6131 ret = get_errno(getrlimit(arg1, &rlim));
6132 if (!is_error(ret)) {
6133 struct target_rlimit *target_rlim;
6134 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
6135 goto efault;
6136 target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
6137 target_rlim->rlim_max = tswapl(rlim.rlim_max);
6138 unlock_user_struct(target_rlim, arg2, 1);
6140 break;
6142 #endif
6143 #ifdef TARGET_NR_truncate64
6144 case TARGET_NR_truncate64:
6145 if (!(p = lock_user_string(arg1)))
6146 goto efault;
6147 ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
6148 unlock_user(p, arg1, 0);
6149 break;
6150 #endif
6151 #ifdef TARGET_NR_ftruncate64
6152 case TARGET_NR_ftruncate64:
6153 ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
6154 break;
6155 #endif
6156 #ifdef TARGET_NR_stat64
6157 case TARGET_NR_stat64:
6158 if (!(p = lock_user_string(arg1)))
6159 goto efault;
6160 ret = get_errno(stat(path(p), &st));
6161 unlock_user(p, arg1, 0);
6162 if (!is_error(ret))
6163 ret = host_to_target_stat64(cpu_env, arg2, &st);
6164 break;
6165 #endif
6166 #ifdef TARGET_NR_lstat64
6167 case TARGET_NR_lstat64:
6168 if (!(p = lock_user_string(arg1)))
6169 goto efault;
6170 ret = get_errno(lstat(path(p), &st));
6171 unlock_user(p, arg1, 0);
6172 if (!is_error(ret))
6173 ret = host_to_target_stat64(cpu_env, arg2, &st);
6174 break;
6175 #endif
6176 #ifdef TARGET_NR_fstat64
6177 case TARGET_NR_fstat64:
6178 ret = get_errno(fstat(arg1, &st));
6179 if (!is_error(ret))
6180 ret = host_to_target_stat64(cpu_env, arg2, &st);
6181 break;
6182 #endif
6183 #if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
6184 (defined(__NR_fstatat64) || defined(__NR_newfstatat))
6185 #ifdef TARGET_NR_fstatat64
6186 case TARGET_NR_fstatat64:
6187 #endif
6188 #ifdef TARGET_NR_newfstatat
6189 case TARGET_NR_newfstatat:
6190 #endif
6191 if (!(p = lock_user_string(arg2)))
6192 goto efault;
6193 #ifdef __NR_fstatat64
6194 ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
6195 #else
6196 ret = get_errno(sys_newfstatat(arg1, path(p), &st, arg4));
6197 #endif
6198 if (!is_error(ret))
6199 ret = host_to_target_stat64(cpu_env, arg3, &st);
6200 break;
6201 #endif
6202 #ifdef USE_UID16
6203 case TARGET_NR_lchown:
6204 if (!(p = lock_user_string(arg1)))
6205 goto efault;
6206 ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
6207 unlock_user(p, arg1, 0);
6208 break;
6209 case TARGET_NR_getuid:
6210 ret = get_errno(high2lowuid(getuid()));
6211 break;
6212 case TARGET_NR_getgid:
6213 ret = get_errno(high2lowgid(getgid()));
6214 break;
6215 case TARGET_NR_geteuid:
6216 ret = get_errno(high2lowuid(geteuid()));
6217 break;
6218 case TARGET_NR_getegid:
6219 ret = get_errno(high2lowgid(getegid()));
6220 break;
6221 case TARGET_NR_setreuid:
6222 ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
6223 break;
6224 case TARGET_NR_setregid:
6225 ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
6226 break;
6227 case TARGET_NR_getgroups:
6229 int gidsetsize = arg1;
6230 uint16_t *target_grouplist;
6231 gid_t *grouplist;
6232 int i;
6234 grouplist = alloca(gidsetsize * sizeof(gid_t));
6235 ret = get_errno(getgroups(gidsetsize, grouplist));
6236 if (gidsetsize == 0)
6237 break;
6238 if (!is_error(ret)) {
6239 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
6240 if (!target_grouplist)
6241 goto efault;
6242 for(i = 0;i < ret; i++)
6243 target_grouplist[i] = tswap16(grouplist[i]);
6244 unlock_user(target_grouplist, arg2, gidsetsize * 2);
6247 break;
6248 case TARGET_NR_setgroups:
6250 int gidsetsize = arg1;
6251 uint16_t *target_grouplist;
6252 gid_t *grouplist;
6253 int i;
6255 grouplist = alloca(gidsetsize * sizeof(gid_t));
6256 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
6257 if (!target_grouplist) {
6258 ret = -TARGET_EFAULT;
6259 goto fail;
6261 for(i = 0;i < gidsetsize; i++)
6262 grouplist[i] = tswap16(target_grouplist[i]);
6263 unlock_user(target_grouplist, arg2, 0);
6264 ret = get_errno(setgroups(gidsetsize, grouplist));
6266 break;
6267 case TARGET_NR_fchown:
6268 ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
6269 break;
6270 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
6271 case TARGET_NR_fchownat:
6272 if (!(p = lock_user_string(arg2)))
6273 goto efault;
6274 ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
6275 unlock_user(p, arg2, 0);
6276 break;
6277 #endif
6278 #ifdef TARGET_NR_setresuid
6279 case TARGET_NR_setresuid:
6280 ret = get_errno(setresuid(low2highuid(arg1),
6281 low2highuid(arg2),
6282 low2highuid(arg3)));
6283 break;
6284 #endif
6285 #ifdef TARGET_NR_getresuid
6286 case TARGET_NR_getresuid:
6288 uid_t ruid, euid, suid;
6289 ret = get_errno(getresuid(&ruid, &euid, &suid));
6290 if (!is_error(ret)) {
6291 if (put_user_u16(high2lowuid(ruid), arg1)
6292 || put_user_u16(high2lowuid(euid), arg2)
6293 || put_user_u16(high2lowuid(suid), arg3))
6294 goto efault;
6297 break;
6298 #endif
6299 #ifdef TARGET_NR_getresgid
6300 case TARGET_NR_setresgid:
6301 ret = get_errno(setresgid(low2highgid(arg1),
6302 low2highgid(arg2),
6303 low2highgid(arg3)));
6304 break;
6305 #endif
6306 #ifdef TARGET_NR_getresgid
6307 case TARGET_NR_getresgid:
6309 gid_t rgid, egid, sgid;
6310 ret = get_errno(getresgid(&rgid, &egid, &sgid));
6311 if (!is_error(ret)) {
6312 if (put_user_u16(high2lowgid(rgid), arg1)
6313 || put_user_u16(high2lowgid(egid), arg2)
6314 || put_user_u16(high2lowgid(sgid), arg3))
6315 goto efault;
6318 break;
6319 #endif
6320 case TARGET_NR_chown:
6321 if (!(p = lock_user_string(arg1)))
6322 goto efault;
6323 ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
6324 unlock_user(p, arg1, 0);
6325 break;
6326 case TARGET_NR_setuid:
6327 ret = get_errno(setuid(low2highuid(arg1)));
6328 break;
6329 case TARGET_NR_setgid:
6330 ret = get_errno(setgid(low2highgid(arg1)));
6331 break;
6332 case TARGET_NR_setfsuid:
6333 ret = get_errno(setfsuid(arg1));
6334 break;
6335 case TARGET_NR_setfsgid:
6336 ret = get_errno(setfsgid(arg1));
6337 break;
6338 #endif /* USE_UID16 */
6340 #ifdef TARGET_NR_lchown32
6341 case TARGET_NR_lchown32:
6342 if (!(p = lock_user_string(arg1)))
6343 goto efault;
6344 ret = get_errno(lchown(p, arg2, arg3));
6345 unlock_user(p, arg1, 0);
6346 break;
6347 #endif
6348 #ifdef TARGET_NR_getuid32
6349 case TARGET_NR_getuid32:
6350 ret = get_errno(getuid());
6351 break;
6352 #endif
6354 #if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
6355 /* Alpha specific */
6356 case TARGET_NR_getxuid:
6358 uid_t euid;
6359 euid=geteuid();
6360 ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
6362 ret = get_errno(getuid());
6363 break;
6364 #endif
6365 #if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
6366 /* Alpha specific */
6367 case TARGET_NR_getxgid:
6369 uid_t egid;
6370 egid=getegid();
6371 ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
6373 ret = get_errno(getgid());
6374 break;
6375 #endif
6377 #ifdef TARGET_NR_getgid32
6378 case TARGET_NR_getgid32:
6379 ret = get_errno(getgid());
6380 break;
6381 #endif
6382 #ifdef TARGET_NR_geteuid32
6383 case TARGET_NR_geteuid32:
6384 ret = get_errno(geteuid());
6385 break;
6386 #endif
6387 #ifdef TARGET_NR_getegid32
6388 case TARGET_NR_getegid32:
6389 ret = get_errno(getegid());
6390 break;
6391 #endif
6392 #ifdef TARGET_NR_setreuid32
6393 case TARGET_NR_setreuid32:
6394 ret = get_errno(setreuid(arg1, arg2));
6395 break;
6396 #endif
6397 #ifdef TARGET_NR_setregid32
6398 case TARGET_NR_setregid32:
6399 ret = get_errno(setregid(arg1, arg2));
6400 break;
6401 #endif
6402 #ifdef TARGET_NR_getgroups32
6403 case TARGET_NR_getgroups32:
6405 int gidsetsize = arg1;
6406 uint32_t *target_grouplist;
6407 gid_t *grouplist;
6408 int i;
6410 grouplist = alloca(gidsetsize * sizeof(gid_t));
6411 ret = get_errno(getgroups(gidsetsize, grouplist));
6412 if (gidsetsize == 0)
6413 break;
6414 if (!is_error(ret)) {
6415 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
6416 if (!target_grouplist) {
6417 ret = -TARGET_EFAULT;
6418 goto fail;
6420 for(i = 0;i < ret; i++)
6421 target_grouplist[i] = tswap32(grouplist[i]);
6422 unlock_user(target_grouplist, arg2, gidsetsize * 4);
6425 break;
6426 #endif
6427 #ifdef TARGET_NR_setgroups32
6428 case TARGET_NR_setgroups32:
6430 int gidsetsize = arg1;
6431 uint32_t *target_grouplist;
6432 gid_t *grouplist;
6433 int i;
6435 grouplist = alloca(gidsetsize * sizeof(gid_t));
6436 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
6437 if (!target_grouplist) {
6438 ret = -TARGET_EFAULT;
6439 goto fail;
6441 for(i = 0;i < gidsetsize; i++)
6442 grouplist[i] = tswap32(target_grouplist[i]);
6443 unlock_user(target_grouplist, arg2, 0);
6444 ret = get_errno(setgroups(gidsetsize, grouplist));
6446 break;
6447 #endif
6448 #ifdef TARGET_NR_fchown32
6449 case TARGET_NR_fchown32:
6450 ret = get_errno(fchown(arg1, arg2, arg3));
6451 break;
6452 #endif
6453 #ifdef TARGET_NR_setresuid32
6454 case TARGET_NR_setresuid32:
6455 ret = get_errno(setresuid(arg1, arg2, arg3));
6456 break;
6457 #endif
6458 #ifdef TARGET_NR_getresuid32
6459 case TARGET_NR_getresuid32:
6461 uid_t ruid, euid, suid;
6462 ret = get_errno(getresuid(&ruid, &euid, &suid));
6463 if (!is_error(ret)) {
6464 if (put_user_u32(ruid, arg1)
6465 || put_user_u32(euid, arg2)
6466 || put_user_u32(suid, arg3))
6467 goto efault;
6470 break;
6471 #endif
6472 #ifdef TARGET_NR_setresgid32
6473 case TARGET_NR_setresgid32:
6474 ret = get_errno(setresgid(arg1, arg2, arg3));
6475 break;
6476 #endif
6477 #ifdef TARGET_NR_getresgid32
6478 case TARGET_NR_getresgid32:
6480 gid_t rgid, egid, sgid;
6481 ret = get_errno(getresgid(&rgid, &egid, &sgid));
6482 if (!is_error(ret)) {
6483 if (put_user_u32(rgid, arg1)
6484 || put_user_u32(egid, arg2)
6485 || put_user_u32(sgid, arg3))
6486 goto efault;
6489 break;
6490 #endif
6491 #ifdef TARGET_NR_chown32
6492 case TARGET_NR_chown32:
6493 if (!(p = lock_user_string(arg1)))
6494 goto efault;
6495 ret = get_errno(chown(p, arg2, arg3));
6496 unlock_user(p, arg1, 0);
6497 break;
6498 #endif
6499 #ifdef TARGET_NR_setuid32
6500 case TARGET_NR_setuid32:
6501 ret = get_errno(setuid(arg1));
6502 break;
6503 #endif
6504 #ifdef TARGET_NR_setgid32
6505 case TARGET_NR_setgid32:
6506 ret = get_errno(setgid(arg1));
6507 break;
6508 #endif
6509 #ifdef TARGET_NR_setfsuid32
6510 case TARGET_NR_setfsuid32:
6511 ret = get_errno(setfsuid(arg1));
6512 break;
6513 #endif
6514 #ifdef TARGET_NR_setfsgid32
6515 case TARGET_NR_setfsgid32:
6516 ret = get_errno(setfsgid(arg1));
6517 break;
6518 #endif
6520 case TARGET_NR_pivot_root:
6521 goto unimplemented;
6522 #ifdef TARGET_NR_mincore
6523 case TARGET_NR_mincore:
6525 void *a;
6526 ret = -TARGET_EFAULT;
6527 if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
6528 goto efault;
6529 if (!(p = lock_user_string(arg3)))
6530 goto mincore_fail;
6531 ret = get_errno(mincore(a, arg2, p));
6532 unlock_user(p, arg3, ret);
6533 mincore_fail:
6534 unlock_user(a, arg1, 0);
6536 break;
6537 #endif
6538 #ifdef TARGET_NR_arm_fadvise64_64
6539 case TARGET_NR_arm_fadvise64_64:
6542 * arm_fadvise64_64 looks like fadvise64_64 but
6543 * with different argument order
6545 abi_long temp;
6546 temp = arg3;
6547 arg3 = arg4;
6548 arg4 = temp;
6550 #endif
6551 #if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64)
6552 #ifdef TARGET_NR_fadvise64_64
6553 case TARGET_NR_fadvise64_64:
6554 #endif
6555 /* This is a hint, so ignoring and returning success is ok. */
6556 ret = get_errno(0);
6557 break;
6558 #endif
6559 #ifdef TARGET_NR_madvise
6560 case TARGET_NR_madvise:
6561 /* A straight passthrough may not be safe because qemu sometimes
6562 turns private flie-backed mappings into anonymous mappings.
6563 This will break MADV_DONTNEED.
6564 This is a hint, so ignoring and returning success is ok. */
6565 ret = get_errno(0);
6566 break;
6567 #endif
6568 #if TARGET_ABI_BITS == 32
6569 case TARGET_NR_fcntl64:
6571 int cmd;
6572 struct flock64 fl;
6573 struct target_flock64 *target_fl;
6574 #ifdef TARGET_ARM
6575 struct target_eabi_flock64 *target_efl;
6576 #endif
6578 cmd = target_to_host_fcntl_cmd(arg2);
6579 if (cmd == -TARGET_EINVAL)
6580 return cmd;
6582 switch(arg2) {
6583 case TARGET_F_GETLK64:
6584 #ifdef TARGET_ARM
6585 if (((CPUARMState *)cpu_env)->eabi) {
6586 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1))
6587 goto efault;
6588 fl.l_type = tswap16(target_efl->l_type);
6589 fl.l_whence = tswap16(target_efl->l_whence);
6590 fl.l_start = tswap64(target_efl->l_start);
6591 fl.l_len = tswap64(target_efl->l_len);
6592 fl.l_pid = tswapl(target_efl->l_pid);
6593 unlock_user_struct(target_efl, arg3, 0);
6594 } else
6595 #endif
6597 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1))
6598 goto efault;
6599 fl.l_type = tswap16(target_fl->l_type);
6600 fl.l_whence = tswap16(target_fl->l_whence);
6601 fl.l_start = tswap64(target_fl->l_start);
6602 fl.l_len = tswap64(target_fl->l_len);
6603 fl.l_pid = tswapl(target_fl->l_pid);
6604 unlock_user_struct(target_fl, arg3, 0);
6606 ret = get_errno(fcntl(arg1, cmd, &fl));
6607 if (ret == 0) {
6608 #ifdef TARGET_ARM
6609 if (((CPUARMState *)cpu_env)->eabi) {
6610 if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0))
6611 goto efault;
6612 target_efl->l_type = tswap16(fl.l_type);
6613 target_efl->l_whence = tswap16(fl.l_whence);
6614 target_efl->l_start = tswap64(fl.l_start);
6615 target_efl->l_len = tswap64(fl.l_len);
6616 target_efl->l_pid = tswapl(fl.l_pid);
6617 unlock_user_struct(target_efl, arg3, 1);
6618 } else
6619 #endif
6621 if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0))
6622 goto efault;
6623 target_fl->l_type = tswap16(fl.l_type);
6624 target_fl->l_whence = tswap16(fl.l_whence);
6625 target_fl->l_start = tswap64(fl.l_start);
6626 target_fl->l_len = tswap64(fl.l_len);
6627 target_fl->l_pid = tswapl(fl.l_pid);
6628 unlock_user_struct(target_fl, arg3, 1);
6631 break;
6633 case TARGET_F_SETLK64:
6634 case TARGET_F_SETLKW64:
6635 #ifdef TARGET_ARM
6636 if (((CPUARMState *)cpu_env)->eabi) {
6637 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1))
6638 goto efault;
6639 fl.l_type = tswap16(target_efl->l_type);
6640 fl.l_whence = tswap16(target_efl->l_whence);
6641 fl.l_start = tswap64(target_efl->l_start);
6642 fl.l_len = tswap64(target_efl->l_len);
6643 fl.l_pid = tswapl(target_efl->l_pid);
6644 unlock_user_struct(target_efl, arg3, 0);
6645 } else
6646 #endif
6648 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1))
6649 goto efault;
6650 fl.l_type = tswap16(target_fl->l_type);
6651 fl.l_whence = tswap16(target_fl->l_whence);
6652 fl.l_start = tswap64(target_fl->l_start);
6653 fl.l_len = tswap64(target_fl->l_len);
6654 fl.l_pid = tswapl(target_fl->l_pid);
6655 unlock_user_struct(target_fl, arg3, 0);
6657 ret = get_errno(fcntl(arg1, cmd, &fl));
6658 break;
6659 default:
6660 ret = do_fcntl(arg1, arg2, arg3);
6661 break;
6663 break;
6665 #endif
6666 #ifdef TARGET_NR_cacheflush
6667 case TARGET_NR_cacheflush:
6668 /* self-modifying code is handled automatically, so nothing needed */
6669 ret = 0;
6670 break;
6671 #endif
6672 #ifdef TARGET_NR_security
6673 case TARGET_NR_security:
6674 goto unimplemented;
6675 #endif
6676 #ifdef TARGET_NR_getpagesize
6677 case TARGET_NR_getpagesize:
6678 ret = TARGET_PAGE_SIZE;
6679 break;
6680 #endif
6681 case TARGET_NR_gettid:
6682 ret = get_errno(gettid());
6683 break;
6684 #ifdef TARGET_NR_readahead
6685 case TARGET_NR_readahead:
6686 #if TARGET_ABI_BITS == 32
6687 #ifdef TARGET_ARM
6688 if (((CPUARMState *)cpu_env)->eabi)
6690 arg2 = arg3;
6691 arg3 = arg4;
6692 arg4 = arg5;
6694 #endif
6695 ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
6696 #else
6697 ret = get_errno(readahead(arg1, arg2, arg3));
6698 #endif
6699 break;
6700 #endif
6701 #ifdef TARGET_NR_setxattr
6702 case TARGET_NR_setxattr:
6703 case TARGET_NR_lsetxattr:
6704 case TARGET_NR_fsetxattr:
6705 case TARGET_NR_getxattr:
6706 case TARGET_NR_lgetxattr:
6707 case TARGET_NR_fgetxattr:
6708 case TARGET_NR_listxattr:
6709 case TARGET_NR_llistxattr:
6710 case TARGET_NR_flistxattr:
6711 case TARGET_NR_removexattr:
6712 case TARGET_NR_lremovexattr:
6713 case TARGET_NR_fremovexattr:
6714 ret = -TARGET_EOPNOTSUPP;
6715 break;
6716 #endif
6717 #ifdef TARGET_NR_set_thread_area
6718 case TARGET_NR_set_thread_area:
6719 #if defined(TARGET_MIPS)
6720 ((CPUMIPSState *) cpu_env)->tls_value = arg1;
6721 ret = 0;
6722 break;
6723 #elif defined(TARGET_CRIS)
6724 if (arg1 & 0xff)
6725 ret = -TARGET_EINVAL;
6726 else {
6727 ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
6728 ret = 0;
6730 break;
6731 #elif defined(TARGET_I386) && defined(TARGET_ABI32)
6732 ret = do_set_thread_area(cpu_env, arg1);
6733 break;
6734 #else
6735 goto unimplemented_nowarn;
6736 #endif
6737 #endif
6738 #ifdef TARGET_NR_get_thread_area
6739 case TARGET_NR_get_thread_area:
6740 #if defined(TARGET_I386) && defined(TARGET_ABI32)
6741 ret = do_get_thread_area(cpu_env, arg1);
6742 #else
6743 goto unimplemented_nowarn;
6744 #endif
6745 #endif
6746 #ifdef TARGET_NR_getdomainname
6747 case TARGET_NR_getdomainname:
6748 goto unimplemented_nowarn;
6749 #endif
6751 #ifdef TARGET_NR_clock_gettime
6752 case TARGET_NR_clock_gettime:
6754 struct timespec ts;
6755 ret = get_errno(clock_gettime(arg1, &ts));
6756 if (!is_error(ret)) {
6757 host_to_target_timespec(arg2, &ts);
6759 break;
6761 #endif
6762 #ifdef TARGET_NR_clock_getres
6763 case TARGET_NR_clock_getres:
6765 struct timespec ts;
6766 ret = get_errno(clock_getres(arg1, &ts));
6767 if (!is_error(ret)) {
6768 host_to_target_timespec(arg2, &ts);
6770 break;
6772 #endif
6773 #ifdef TARGET_NR_clock_nanosleep
6774 case TARGET_NR_clock_nanosleep:
6776 struct timespec ts;
6777 target_to_host_timespec(&ts, arg3);
6778 ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
6779 if (arg4)
6780 host_to_target_timespec(arg4, &ts);
6781 break;
6783 #endif
6785 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
6786 case TARGET_NR_set_tid_address:
6787 ret = get_errno(set_tid_address((int *)g2h(arg1)));
6788 break;
6789 #endif
6791 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
6792 case TARGET_NR_tkill:
6793 ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
6794 break;
6795 #endif
6797 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
6798 case TARGET_NR_tgkill:
6799 ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
6800 target_to_host_signal(arg3)));
6801 break;
6802 #endif
6804 #ifdef TARGET_NR_set_robust_list
6805 case TARGET_NR_set_robust_list:
6806 goto unimplemented_nowarn;
6807 #endif
6809 #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
6810 case TARGET_NR_utimensat:
6812 struct timespec *tsp, ts[2];
6813 if (!arg3) {
6814 tsp = NULL;
6815 } else {
6816 target_to_host_timespec(ts, arg3);
6817 target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
6818 tsp = ts;
6820 if (!arg2)
6821 ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4));
6822 else {
6823 if (!(p = lock_user_string(arg2))) {
6824 ret = -TARGET_EFAULT;
6825 goto fail;
6827 ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4));
6828 unlock_user(p, arg2, 0);
6831 break;
6832 #endif
6833 #if defined(USE_NPTL)
6834 case TARGET_NR_futex:
6835 ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
6836 break;
6837 #endif
6838 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
6839 case TARGET_NR_inotify_init:
6840 ret = get_errno(sys_inotify_init());
6841 break;
6842 #endif
6843 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
6844 case TARGET_NR_inotify_add_watch:
6845 p = lock_user_string(arg2);
6846 ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
6847 unlock_user(p, arg2, 0);
6848 break;
6849 #endif
6850 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
6851 case TARGET_NR_inotify_rm_watch:
6852 ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
6853 break;
6854 #endif
6856 #ifdef TARGET_NR_mq_open
6857 case TARGET_NR_mq_open:
6859 struct mq_attr posix_mq_attr;
6861 p = lock_user_string(arg1 - 1);
6862 if (arg4 != 0)
6863 copy_from_user_mq_attr (&posix_mq_attr, arg4);
6864 ret = get_errno(mq_open(p, arg2, arg3, &posix_mq_attr));
6865 unlock_user (p, arg1, 0);
6867 break;
6869 case TARGET_NR_mq_unlink:
6870 p = lock_user_string(arg1 - 1);
6871 ret = get_errno(mq_unlink(p));
6872 unlock_user (p, arg1, 0);
6873 break;
6875 case TARGET_NR_mq_timedsend:
6877 struct timespec ts;
6879 p = lock_user (VERIFY_READ, arg2, arg3, 1);
6880 if (arg5 != 0) {
6881 target_to_host_timespec(&ts, arg5);
6882 ret = get_errno(mq_timedsend(arg1, p, arg3, arg4, &ts));
6883 host_to_target_timespec(arg5, &ts);
6885 else
6886 ret = get_errno(mq_send(arg1, p, arg3, arg4));
6887 unlock_user (p, arg2, arg3);
6889 break;
6891 case TARGET_NR_mq_timedreceive:
6893 struct timespec ts;
6894 unsigned int prio;
6896 p = lock_user (VERIFY_READ, arg2, arg3, 1);
6897 if (arg5 != 0) {
6898 target_to_host_timespec(&ts, arg5);
6899 ret = get_errno(mq_timedreceive(arg1, p, arg3, &prio, &ts));
6900 host_to_target_timespec(arg5, &ts);
6902 else
6903 ret = get_errno(mq_receive(arg1, p, arg3, &prio));
6904 unlock_user (p, arg2, arg3);
6905 if (arg4 != 0)
6906 put_user_u32(prio, arg4);
6908 break;
6910 /* Not implemented for now... */
6911 /* case TARGET_NR_mq_notify: */
6912 /* break; */
6914 case TARGET_NR_mq_getsetattr:
6916 struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
6917 ret = 0;
6918 if (arg3 != 0) {
6919 ret = mq_getattr(arg1, &posix_mq_attr_out);
6920 copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
6922 if (arg2 != 0) {
6923 copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
6924 ret |= mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_attr_out);
6928 break;
6929 #endif
6931 #ifdef CONFIG_SPLICE
6932 #ifdef TARGET_NR_tee
6933 case TARGET_NR_tee:
6935 ret = get_errno(tee(arg1,arg2,arg3,arg4));
6937 break;
6938 #endif
6939 #ifdef TARGET_NR_splice
6940 case TARGET_NR_splice:
6942 loff_t loff_in, loff_out;
6943 loff_t *ploff_in = NULL, *ploff_out = NULL;
6944 if(arg2) {
6945 get_user_u64(loff_in, arg2);
6946 ploff_in = &loff_in;
6948 if(arg4) {
6949 get_user_u64(loff_out, arg2);
6950 ploff_out = &loff_out;
6952 ret = get_errno(splice(arg1, ploff_in, arg3, ploff_out, arg5, arg6));
6954 break;
6955 #endif
6956 #ifdef TARGET_NR_vmsplice
6957 case TARGET_NR_vmsplice:
6959 int count = arg3;
6960 struct iovec *vec;
6962 vec = alloca(count * sizeof(struct iovec));
6963 if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
6964 goto efault;
6965 ret = get_errno(vmsplice(arg1, vec, count, arg4));
6966 unlock_iovec(vec, arg2, count, 0);
6968 break;
6969 #endif
6970 #endif /* CONFIG_SPLICE */
6971 default:
6972 unimplemented:
6973 gemu_log("qemu: Unsupported syscall: %d\n", num);
6974 #if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
6975 unimplemented_nowarn:
6976 #endif
6977 ret = -TARGET_ENOSYS;
6978 break;
6980 fail:
6981 #ifdef DEBUG
6982 gemu_log(" = %ld\n", ret);
6983 #endif
6984 if(do_strace)
6985 print_syscall_ret(num, ret);
6986 return ret;
6987 efault:
6988 ret = -TARGET_EFAULT;
6989 goto fail;