linux-user: Added IP_(UN)BLOCK_SOURCE/IP_(ADD|DROP)_SOURCE_MEMBERSHIP flags to setsockopt
[qemu/cris-port.git] / linux-user / syscall.c
blob674942cdf4229e85898f73fb624639e7312118dd
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 #include <stdlib.h>
22 #include <stdio.h>
23 #include <stdarg.h>
24 #include <string.h>
25 #include <elf.h>
26 #include <endian.h>
27 #include <errno.h>
28 #include <unistd.h>
29 #include <fcntl.h>
30 #include <time.h>
31 #include <limits.h>
32 #include <mqueue.h>
33 #include <sys/types.h>
34 #include <sys/ipc.h>
35 #include <sys/msg.h>
36 #include <sys/wait.h>
37 #include <sys/time.h>
38 #include <sys/stat.h>
39 #include <sys/mount.h>
40 #include <sys/prctl.h>
41 #include <sys/resource.h>
42 #include <sys/mman.h>
43 #include <sys/swap.h>
44 #include <signal.h>
45 #include <sched.h>
46 #include <sys/socket.h>
47 #include <sys/un.h>
48 #include <sys/uio.h>
49 #include <sys/poll.h>
50 #include <sys/times.h>
51 #include <sys/shm.h>
52 #include <sys/sem.h>
53 #include <sys/statfs.h>
54 #include <utime.h>
55 #include <sys/sysinfo.h>
56 #include <sys/utsname.h>
57 //#include <sys/user.h>
58 #include <netinet/ip.h>
59 #include <netinet/tcp.h>
60 #include <qemu-common.h>
61 #ifdef HAVE_GPROF
62 #include <sys/gmon.h>
63 #endif
65 #define termios host_termios
66 #define winsize host_winsize
67 #define termio host_termio
68 #define sgttyb host_sgttyb /* same as target */
69 #define tchars host_tchars /* same as target */
70 #define ltchars host_ltchars /* same as target */
72 #include <linux/termios.h>
73 #include <linux/unistd.h>
74 #include <linux/utsname.h>
75 #include <linux/cdrom.h>
76 #include <linux/hdreg.h>
77 #include <linux/soundcard.h>
78 #include <linux/kd.h>
79 #include <linux/mtio.h>
80 #include "linux_loop.h"
82 #include "qemu.h"
83 #include "qemu-common.h"
85 #if defined(USE_NPTL)
86 #include <linux/futex.h>
87 #define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
88 CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
89 #else
90 /* XXX: Hardcode the above values. */
91 #define CLONE_NPTL_FLAGS2 0
92 #endif
94 //#define DEBUG
96 //#include <linux/msdos_fs.h>
97 #define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct linux_dirent [2])
98 #define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct linux_dirent [2])
101 #undef _syscall0
102 #undef _syscall1
103 #undef _syscall2
104 #undef _syscall3
105 #undef _syscall4
106 #undef _syscall5
107 #undef _syscall6
109 #define _syscall0(type,name) \
110 static type name (void) \
112 return syscall(__NR_##name); \
115 #define _syscall1(type,name,type1,arg1) \
116 static type name (type1 arg1) \
118 return syscall(__NR_##name, arg1); \
121 #define _syscall2(type,name,type1,arg1,type2,arg2) \
122 static type name (type1 arg1,type2 arg2) \
124 return syscall(__NR_##name, arg1, arg2); \
127 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
128 static type name (type1 arg1,type2 arg2,type3 arg3) \
130 return syscall(__NR_##name, arg1, arg2, arg3); \
133 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
134 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4) \
136 return syscall(__NR_##name, arg1, arg2, arg3, arg4); \
139 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
140 type5,arg5) \
141 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
143 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5); \
147 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
148 type5,arg5,type6,arg6) \
149 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \
150 type6 arg6) \
152 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6); \
156 #define __NR_sys_uname __NR_uname
157 #define __NR_sys_faccessat __NR_faccessat
158 #define __NR_sys_fchmodat __NR_fchmodat
159 #define __NR_sys_fchownat __NR_fchownat
160 #define __NR_sys_fstatat64 __NR_fstatat64
161 #define __NR_sys_futimesat __NR_futimesat
162 #define __NR_sys_getcwd1 __NR_getcwd
163 #define __NR_sys_getdents __NR_getdents
164 #define __NR_sys_getdents64 __NR_getdents64
165 #define __NR_sys_getpriority __NR_getpriority
166 #define __NR_sys_linkat __NR_linkat
167 #define __NR_sys_mkdirat __NR_mkdirat
168 #define __NR_sys_mknodat __NR_mknodat
169 #define __NR_sys_newfstatat __NR_newfstatat
170 #define __NR_sys_openat __NR_openat
171 #define __NR_sys_readlinkat __NR_readlinkat
172 #define __NR_sys_renameat __NR_renameat
173 #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
174 #define __NR_sys_symlinkat __NR_symlinkat
175 #define __NR_sys_syslog __NR_syslog
176 #define __NR_sys_tgkill __NR_tgkill
177 #define __NR_sys_tkill __NR_tkill
178 #define __NR_sys_unlinkat __NR_unlinkat
179 #define __NR_sys_utimensat __NR_utimensat
180 #define __NR_sys_futex __NR_futex
181 #define __NR_sys_inotify_init __NR_inotify_init
182 #define __NR_sys_inotify_add_watch __NR_inotify_add_watch
183 #define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
185 #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
186 #define __NR__llseek __NR_lseek
187 #endif
189 #ifdef __NR_gettid
190 _syscall0(int, gettid)
191 #else
192 /* This is a replacement for the host gettid() and must return a host
193 errno. */
194 static int gettid(void) {
195 return -ENOSYS;
197 #endif
198 #if TARGET_ABI_BITS == 32
199 _syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
200 #endif
201 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
202 _syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
203 #endif
204 _syscall2(int, sys_getpriority, int, which, int, who);
205 #if defined(TARGET_NR__llseek) && !defined (__x86_64__)
206 _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo,
207 loff_t *, res, uint, wh);
208 #endif
209 _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
210 _syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
211 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
212 _syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
213 #endif
214 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
215 _syscall2(int,sys_tkill,int,tid,int,sig)
216 #endif
217 #ifdef __NR_exit_group
218 _syscall1(int,exit_group,int,error_code)
219 #endif
220 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
221 _syscall1(int,set_tid_address,int *,tidptr)
222 #endif
223 #if defined(USE_NPTL)
224 #if defined(TARGET_NR_futex) && defined(__NR_futex)
225 _syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
226 const struct timespec *,timeout,int *,uaddr2,int,val3)
227 #endif
228 #endif
230 static bitmask_transtbl fcntl_flags_tbl[] = {
231 { TARGET_O_ACCMODE, TARGET_O_WRONLY, O_ACCMODE, O_WRONLY, },
232 { TARGET_O_ACCMODE, TARGET_O_RDWR, O_ACCMODE, O_RDWR, },
233 { TARGET_O_CREAT, TARGET_O_CREAT, O_CREAT, O_CREAT, },
234 { TARGET_O_EXCL, TARGET_O_EXCL, O_EXCL, O_EXCL, },
235 { TARGET_O_NOCTTY, TARGET_O_NOCTTY, O_NOCTTY, O_NOCTTY, },
236 { TARGET_O_TRUNC, TARGET_O_TRUNC, O_TRUNC, O_TRUNC, },
237 { TARGET_O_APPEND, TARGET_O_APPEND, O_APPEND, O_APPEND, },
238 { TARGET_O_NONBLOCK, TARGET_O_NONBLOCK, O_NONBLOCK, O_NONBLOCK, },
239 { TARGET_O_SYNC, TARGET_O_SYNC, O_SYNC, O_SYNC, },
240 { TARGET_FASYNC, TARGET_FASYNC, FASYNC, FASYNC, },
241 { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
242 { TARGET_O_NOFOLLOW, TARGET_O_NOFOLLOW, O_NOFOLLOW, O_NOFOLLOW, },
243 { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
244 #if defined(O_DIRECT)
245 { TARGET_O_DIRECT, TARGET_O_DIRECT, O_DIRECT, O_DIRECT, },
246 #endif
247 { 0, 0, 0, 0 }
250 #define COPY_UTSNAME_FIELD(dest, src) \
251 do { \
252 /* __NEW_UTS_LEN doesn't include terminating null */ \
253 (void) strncpy((dest), (src), __NEW_UTS_LEN); \
254 (dest)[__NEW_UTS_LEN] = '\0'; \
255 } while (0)
257 static int sys_uname(struct new_utsname *buf)
259 struct utsname uts_buf;
261 if (uname(&uts_buf) < 0)
262 return (-1);
265 * Just in case these have some differences, we
266 * translate utsname to new_utsname (which is the
267 * struct linux kernel uses).
270 bzero(buf, sizeof (*buf));
271 COPY_UTSNAME_FIELD(buf->sysname, uts_buf.sysname);
272 COPY_UTSNAME_FIELD(buf->nodename, uts_buf.nodename);
273 COPY_UTSNAME_FIELD(buf->release, uts_buf.release);
274 COPY_UTSNAME_FIELD(buf->version, uts_buf.version);
275 COPY_UTSNAME_FIELD(buf->machine, uts_buf.machine);
276 #ifdef _GNU_SOURCE
277 COPY_UTSNAME_FIELD(buf->domainname, uts_buf.domainname);
278 #endif
279 return (0);
281 #undef COPY_UTSNAME_FIELD
284 static int sys_getcwd1(char *buf, size_t size)
286 if (getcwd(buf, size) == NULL) {
287 /* getcwd() sets errno */
288 return (-1);
290 return strlen(buf)+1;
293 #ifdef CONFIG_ATFILE
295 * Host system seems to have atfile syscall stubs available. We
296 * now enable them one by one as specified by target syscall_nr.h.
299 #ifdef TARGET_NR_faccessat
300 static int sys_faccessat(int dirfd, const char *pathname, int mode)
302 return (faccessat(dirfd, pathname, mode, 0));
304 #endif
305 #ifdef TARGET_NR_fchmodat
306 static int sys_fchmodat(int dirfd, const char *pathname, mode_t mode)
308 return (fchmodat(dirfd, pathname, mode, 0));
310 #endif
311 #if defined(TARGET_NR_fchownat) && defined(USE_UID16)
312 static int sys_fchownat(int dirfd, const char *pathname, uid_t owner,
313 gid_t group, int flags)
315 return (fchownat(dirfd, pathname, owner, group, flags));
317 #endif
318 #ifdef __NR_fstatat64
319 static int sys_fstatat64(int dirfd, const char *pathname, struct stat *buf,
320 int flags)
322 return (fstatat(dirfd, pathname, buf, flags));
324 #endif
325 #ifdef __NR_newfstatat
326 static int sys_newfstatat(int dirfd, const char *pathname, struct stat *buf,
327 int flags)
329 return (fstatat(dirfd, pathname, buf, flags));
331 #endif
332 #ifdef TARGET_NR_futimesat
333 static int sys_futimesat(int dirfd, const char *pathname,
334 const struct timeval times[2])
336 return (futimesat(dirfd, pathname, times));
338 #endif
339 #ifdef TARGET_NR_linkat
340 static int sys_linkat(int olddirfd, const char *oldpath,
341 int newdirfd, const char *newpath, int flags)
343 return (linkat(olddirfd, oldpath, newdirfd, newpath, flags));
345 #endif
346 #ifdef TARGET_NR_mkdirat
347 static int sys_mkdirat(int dirfd, const char *pathname, mode_t mode)
349 return (mkdirat(dirfd, pathname, mode));
351 #endif
352 #ifdef TARGET_NR_mknodat
353 static int sys_mknodat(int dirfd, const char *pathname, mode_t mode,
354 dev_t dev)
356 return (mknodat(dirfd, pathname, mode, dev));
358 #endif
359 #ifdef TARGET_NR_openat
360 static int sys_openat(int dirfd, const char *pathname, int flags, ...)
363 * open(2) has extra parameter 'mode' when called with
364 * flag O_CREAT.
366 if ((flags & O_CREAT) != 0) {
367 va_list ap;
368 mode_t mode;
371 * Get the 'mode' parameter and translate it to
372 * host bits.
374 va_start(ap, flags);
375 mode = va_arg(ap, mode_t);
376 mode = target_to_host_bitmask(mode, fcntl_flags_tbl);
377 va_end(ap);
379 return (openat(dirfd, pathname, flags, mode));
381 return (openat(dirfd, pathname, flags));
383 #endif
384 #ifdef TARGET_NR_readlinkat
385 static int sys_readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz)
387 return (readlinkat(dirfd, pathname, buf, bufsiz));
389 #endif
390 #ifdef TARGET_NR_renameat
391 static int sys_renameat(int olddirfd, const char *oldpath,
392 int newdirfd, const char *newpath)
394 return (renameat(olddirfd, oldpath, newdirfd, newpath));
396 #endif
397 #ifdef TARGET_NR_symlinkat
398 static int sys_symlinkat(const char *oldpath, int newdirfd, const char *newpath)
400 return (symlinkat(oldpath, newdirfd, newpath));
402 #endif
403 #ifdef TARGET_NR_unlinkat
404 static int sys_unlinkat(int dirfd, const char *pathname, int flags)
406 return (unlinkat(dirfd, pathname, flags));
408 #endif
409 #else /* !CONFIG_ATFILE */
412 * Try direct syscalls instead
414 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
415 _syscall3(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode)
416 #endif
417 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
418 _syscall3(int,sys_fchmodat,int,dirfd,const char *,pathname, mode_t,mode)
419 #endif
420 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) && defined(USE_UID16)
421 _syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
422 uid_t,owner,gid_t,group,int,flags)
423 #endif
424 #if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
425 defined(__NR_fstatat64)
426 _syscall4(int,sys_fstatat64,int,dirfd,const char *,pathname,
427 struct stat *,buf,int,flags)
428 #endif
429 #if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
430 _syscall3(int,sys_futimesat,int,dirfd,const char *,pathname,
431 const struct timeval *,times)
432 #endif
433 #if (defined(TARGET_NR_newfstatat) || defined(TARGET_NR_fstatat64) ) && \
434 defined(__NR_newfstatat)
435 _syscall4(int,sys_newfstatat,int,dirfd,const char *,pathname,
436 struct stat *,buf,int,flags)
437 #endif
438 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
439 _syscall5(int,sys_linkat,int,olddirfd,const char *,oldpath,
440 int,newdirfd,const char *,newpath,int,flags)
441 #endif
442 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
443 _syscall3(int,sys_mkdirat,int,dirfd,const char *,pathname,mode_t,mode)
444 #endif
445 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
446 _syscall4(int,sys_mknodat,int,dirfd,const char *,pathname,
447 mode_t,mode,dev_t,dev)
448 #endif
449 #if defined(TARGET_NR_openat) && defined(__NR_openat)
450 _syscall4(int,sys_openat,int,dirfd,const char *,pathname,int,flags,mode_t,mode)
451 #endif
452 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
453 _syscall4(int,sys_readlinkat,int,dirfd,const char *,pathname,
454 char *,buf,size_t,bufsize)
455 #endif
456 #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
457 _syscall4(int,sys_renameat,int,olddirfd,const char *,oldpath,
458 int,newdirfd,const char *,newpath)
459 #endif
460 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
461 _syscall3(int,sys_symlinkat,const char *,oldpath,
462 int,newdirfd,const char *,newpath)
463 #endif
464 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
465 _syscall3(int,sys_unlinkat,int,dirfd,const char *,pathname,int,flags)
466 #endif
468 #endif /* CONFIG_ATFILE */
470 #ifdef CONFIG_UTIMENSAT
471 static int sys_utimensat(int dirfd, const char *pathname,
472 const struct timespec times[2], int flags)
474 if (pathname == NULL)
475 return futimens(dirfd, times);
476 else
477 return utimensat(dirfd, pathname, times, flags);
479 #else
480 #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
481 _syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
482 const struct timespec *,tsp,int,flags)
483 #endif
484 #endif /* CONFIG_UTIMENSAT */
486 #ifdef CONFIG_INOTIFY
487 #include <sys/inotify.h>
489 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
490 static int sys_inotify_init(void)
492 return (inotify_init());
494 #endif
495 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
496 static int sys_inotify_add_watch(int fd,const char *pathname, int32_t mask)
498 return (inotify_add_watch(fd, pathname, mask));
500 #endif
501 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
502 static int sys_inotify_rm_watch(int fd, int32_t wd)
504 return (inotify_rm_watch(fd, wd));
506 #endif
507 #else
508 /* Userspace can usually survive runtime without inotify */
509 #undef TARGET_NR_inotify_init
510 #undef TARGET_NR_inotify_add_watch
511 #undef TARGET_NR_inotify_rm_watch
512 #endif /* CONFIG_INOTIFY */
515 extern int personality(int);
516 extern int flock(int, int);
517 extern int setfsuid(int);
518 extern int setfsgid(int);
519 extern int setgroups(int, gid_t *);
521 #define ERRNO_TABLE_SIZE 1200
523 /* target_to_host_errno_table[] is initialized from
524 * host_to_target_errno_table[] in syscall_init(). */
525 static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
529 * This list is the union of errno values overridden in asm-<arch>/errno.h
530 * minus the errnos that are not actually generic to all archs.
532 static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
533 [EIDRM] = TARGET_EIDRM,
534 [ECHRNG] = TARGET_ECHRNG,
535 [EL2NSYNC] = TARGET_EL2NSYNC,
536 [EL3HLT] = TARGET_EL3HLT,
537 [EL3RST] = TARGET_EL3RST,
538 [ELNRNG] = TARGET_ELNRNG,
539 [EUNATCH] = TARGET_EUNATCH,
540 [ENOCSI] = TARGET_ENOCSI,
541 [EL2HLT] = TARGET_EL2HLT,
542 [EDEADLK] = TARGET_EDEADLK,
543 [ENOLCK] = TARGET_ENOLCK,
544 [EBADE] = TARGET_EBADE,
545 [EBADR] = TARGET_EBADR,
546 [EXFULL] = TARGET_EXFULL,
547 [ENOANO] = TARGET_ENOANO,
548 [EBADRQC] = TARGET_EBADRQC,
549 [EBADSLT] = TARGET_EBADSLT,
550 [EBFONT] = TARGET_EBFONT,
551 [ENOSTR] = TARGET_ENOSTR,
552 [ENODATA] = TARGET_ENODATA,
553 [ETIME] = TARGET_ETIME,
554 [ENOSR] = TARGET_ENOSR,
555 [ENONET] = TARGET_ENONET,
556 [ENOPKG] = TARGET_ENOPKG,
557 [EREMOTE] = TARGET_EREMOTE,
558 [ENOLINK] = TARGET_ENOLINK,
559 [EADV] = TARGET_EADV,
560 [ESRMNT] = TARGET_ESRMNT,
561 [ECOMM] = TARGET_ECOMM,
562 [EPROTO] = TARGET_EPROTO,
563 [EDOTDOT] = TARGET_EDOTDOT,
564 [EMULTIHOP] = TARGET_EMULTIHOP,
565 [EBADMSG] = TARGET_EBADMSG,
566 [ENAMETOOLONG] = TARGET_ENAMETOOLONG,
567 [EOVERFLOW] = TARGET_EOVERFLOW,
568 [ENOTUNIQ] = TARGET_ENOTUNIQ,
569 [EBADFD] = TARGET_EBADFD,
570 [EREMCHG] = TARGET_EREMCHG,
571 [ELIBACC] = TARGET_ELIBACC,
572 [ELIBBAD] = TARGET_ELIBBAD,
573 [ELIBSCN] = TARGET_ELIBSCN,
574 [ELIBMAX] = TARGET_ELIBMAX,
575 [ELIBEXEC] = TARGET_ELIBEXEC,
576 [EILSEQ] = TARGET_EILSEQ,
577 [ENOSYS] = TARGET_ENOSYS,
578 [ELOOP] = TARGET_ELOOP,
579 [ERESTART] = TARGET_ERESTART,
580 [ESTRPIPE] = TARGET_ESTRPIPE,
581 [ENOTEMPTY] = TARGET_ENOTEMPTY,
582 [EUSERS] = TARGET_EUSERS,
583 [ENOTSOCK] = TARGET_ENOTSOCK,
584 [EDESTADDRREQ] = TARGET_EDESTADDRREQ,
585 [EMSGSIZE] = TARGET_EMSGSIZE,
586 [EPROTOTYPE] = TARGET_EPROTOTYPE,
587 [ENOPROTOOPT] = TARGET_ENOPROTOOPT,
588 [EPROTONOSUPPORT] = TARGET_EPROTONOSUPPORT,
589 [ESOCKTNOSUPPORT] = TARGET_ESOCKTNOSUPPORT,
590 [EOPNOTSUPP] = TARGET_EOPNOTSUPP,
591 [EPFNOSUPPORT] = TARGET_EPFNOSUPPORT,
592 [EAFNOSUPPORT] = TARGET_EAFNOSUPPORT,
593 [EADDRINUSE] = TARGET_EADDRINUSE,
594 [EADDRNOTAVAIL] = TARGET_EADDRNOTAVAIL,
595 [ENETDOWN] = TARGET_ENETDOWN,
596 [ENETUNREACH] = TARGET_ENETUNREACH,
597 [ENETRESET] = TARGET_ENETRESET,
598 [ECONNABORTED] = TARGET_ECONNABORTED,
599 [ECONNRESET] = TARGET_ECONNRESET,
600 [ENOBUFS] = TARGET_ENOBUFS,
601 [EISCONN] = TARGET_EISCONN,
602 [ENOTCONN] = TARGET_ENOTCONN,
603 [EUCLEAN] = TARGET_EUCLEAN,
604 [ENOTNAM] = TARGET_ENOTNAM,
605 [ENAVAIL] = TARGET_ENAVAIL,
606 [EISNAM] = TARGET_EISNAM,
607 [EREMOTEIO] = TARGET_EREMOTEIO,
608 [ESHUTDOWN] = TARGET_ESHUTDOWN,
609 [ETOOMANYREFS] = TARGET_ETOOMANYREFS,
610 [ETIMEDOUT] = TARGET_ETIMEDOUT,
611 [ECONNREFUSED] = TARGET_ECONNREFUSED,
612 [EHOSTDOWN] = TARGET_EHOSTDOWN,
613 [EHOSTUNREACH] = TARGET_EHOSTUNREACH,
614 [EALREADY] = TARGET_EALREADY,
615 [EINPROGRESS] = TARGET_EINPROGRESS,
616 [ESTALE] = TARGET_ESTALE,
617 [ECANCELED] = TARGET_ECANCELED,
618 [ENOMEDIUM] = TARGET_ENOMEDIUM,
619 [EMEDIUMTYPE] = TARGET_EMEDIUMTYPE,
620 #ifdef ENOKEY
621 [ENOKEY] = TARGET_ENOKEY,
622 #endif
623 #ifdef EKEYEXPIRED
624 [EKEYEXPIRED] = TARGET_EKEYEXPIRED,
625 #endif
626 #ifdef EKEYREVOKED
627 [EKEYREVOKED] = TARGET_EKEYREVOKED,
628 #endif
629 #ifdef EKEYREJECTED
630 [EKEYREJECTED] = TARGET_EKEYREJECTED,
631 #endif
632 #ifdef EOWNERDEAD
633 [EOWNERDEAD] = TARGET_EOWNERDEAD,
634 #endif
635 #ifdef ENOTRECOVERABLE
636 [ENOTRECOVERABLE] = TARGET_ENOTRECOVERABLE,
637 #endif
640 static inline int host_to_target_errno(int err)
642 if(host_to_target_errno_table[err])
643 return host_to_target_errno_table[err];
644 return err;
647 static inline int target_to_host_errno(int err)
649 if (target_to_host_errno_table[err])
650 return target_to_host_errno_table[err];
651 return err;
654 static inline abi_long get_errno(abi_long ret)
656 if (ret == -1)
657 return -host_to_target_errno(errno);
658 else
659 return ret;
662 static inline int is_error(abi_long ret)
664 return (abi_ulong)ret >= (abi_ulong)(-4096);
667 char *target_strerror(int err)
669 return strerror(target_to_host_errno(err));
672 static abi_ulong target_brk;
673 static abi_ulong target_original_brk;
675 void target_set_brk(abi_ulong new_brk)
677 target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
680 /* do_brk() must return target values and target errnos. */
681 abi_long do_brk(abi_ulong new_brk)
683 abi_ulong brk_page;
684 abi_long mapped_addr;
685 int new_alloc_size;
687 if (!new_brk)
688 return target_brk;
689 if (new_brk < target_original_brk)
690 return target_brk;
692 brk_page = HOST_PAGE_ALIGN(target_brk);
694 /* If the new brk is less than this, set it and we're done... */
695 if (new_brk < brk_page) {
696 target_brk = new_brk;
697 return target_brk;
700 /* We need to allocate more memory after the brk... */
701 new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
702 mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
703 PROT_READ|PROT_WRITE,
704 MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
706 if (!is_error(mapped_addr))
707 target_brk = new_brk;
709 return target_brk;
712 static inline abi_long copy_from_user_fdset(fd_set *fds,
713 abi_ulong target_fds_addr,
714 int n)
716 int i, nw, j, k;
717 abi_ulong b, *target_fds;
719 nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
720 if (!(target_fds = lock_user(VERIFY_READ,
721 target_fds_addr,
722 sizeof(abi_ulong) * nw,
723 1)))
724 return -TARGET_EFAULT;
726 FD_ZERO(fds);
727 k = 0;
728 for (i = 0; i < nw; i++) {
729 /* grab the abi_ulong */
730 __get_user(b, &target_fds[i]);
731 for (j = 0; j < TARGET_ABI_BITS; j++) {
732 /* check the bit inside the abi_ulong */
733 if ((b >> j) & 1)
734 FD_SET(k, fds);
735 k++;
739 unlock_user(target_fds, target_fds_addr, 0);
741 return 0;
744 static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
745 const fd_set *fds,
746 int n)
748 int i, nw, j, k;
749 abi_long v;
750 abi_ulong *target_fds;
752 nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
753 if (!(target_fds = lock_user(VERIFY_WRITE,
754 target_fds_addr,
755 sizeof(abi_ulong) * nw,
756 0)))
757 return -TARGET_EFAULT;
759 k = 0;
760 for (i = 0; i < nw; i++) {
761 v = 0;
762 for (j = 0; j < TARGET_ABI_BITS; j++) {
763 v |= ((FD_ISSET(k, fds) != 0) << j);
764 k++;
766 __put_user(v, &target_fds[i]);
769 unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
771 return 0;
774 #if defined(__alpha__)
775 #define HOST_HZ 1024
776 #else
777 #define HOST_HZ 100
778 #endif
780 static inline abi_long host_to_target_clock_t(long ticks)
782 #if HOST_HZ == TARGET_HZ
783 return ticks;
784 #else
785 return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
786 #endif
789 static inline abi_long host_to_target_rusage(abi_ulong target_addr,
790 const struct rusage *rusage)
792 struct target_rusage *target_rusage;
794 if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
795 return -TARGET_EFAULT;
796 target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
797 target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
798 target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
799 target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec);
800 target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss);
801 target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss);
802 target_rusage->ru_idrss = tswapl(rusage->ru_idrss);
803 target_rusage->ru_isrss = tswapl(rusage->ru_isrss);
804 target_rusage->ru_minflt = tswapl(rusage->ru_minflt);
805 target_rusage->ru_majflt = tswapl(rusage->ru_majflt);
806 target_rusage->ru_nswap = tswapl(rusage->ru_nswap);
807 target_rusage->ru_inblock = tswapl(rusage->ru_inblock);
808 target_rusage->ru_oublock = tswapl(rusage->ru_oublock);
809 target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd);
810 target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv);
811 target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);
812 target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
813 target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
814 unlock_user_struct(target_rusage, target_addr, 1);
816 return 0;
819 static inline abi_long copy_from_user_timeval(struct timeval *tv,
820 abi_ulong target_tv_addr)
822 struct target_timeval *target_tv;
824 if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
825 return -TARGET_EFAULT;
827 __get_user(tv->tv_sec, &target_tv->tv_sec);
828 __get_user(tv->tv_usec, &target_tv->tv_usec);
830 unlock_user_struct(target_tv, target_tv_addr, 0);
832 return 0;
835 static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
836 const struct timeval *tv)
838 struct target_timeval *target_tv;
840 if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
841 return -TARGET_EFAULT;
843 __put_user(tv->tv_sec, &target_tv->tv_sec);
844 __put_user(tv->tv_usec, &target_tv->tv_usec);
846 unlock_user_struct(target_tv, target_tv_addr, 1);
848 return 0;
851 static inline abi_long copy_from_user_mq_attr(struct mq_attr *attr,
852 abi_ulong target_mq_attr_addr)
854 struct target_mq_attr *target_mq_attr;
856 if (!lock_user_struct(VERIFY_READ, target_mq_attr,
857 target_mq_attr_addr, 1))
858 return -TARGET_EFAULT;
860 __get_user(attr->mq_flags, &target_mq_attr->mq_flags);
861 __get_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
862 __get_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
863 __get_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
865 unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0);
867 return 0;
870 static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr,
871 const struct mq_attr *attr)
873 struct target_mq_attr *target_mq_attr;
875 if (!lock_user_struct(VERIFY_WRITE, target_mq_attr,
876 target_mq_attr_addr, 0))
877 return -TARGET_EFAULT;
879 __put_user(attr->mq_flags, &target_mq_attr->mq_flags);
880 __put_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
881 __put_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
882 __put_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
884 unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1);
886 return 0;
889 /* do_select() must return target values and target errnos. */
890 static abi_long do_select(int n,
891 abi_ulong rfd_addr, abi_ulong wfd_addr,
892 abi_ulong efd_addr, abi_ulong target_tv_addr)
894 fd_set rfds, wfds, efds;
895 fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
896 struct timeval tv, *tv_ptr;
897 abi_long ret;
899 if (rfd_addr) {
900 if (copy_from_user_fdset(&rfds, rfd_addr, n))
901 return -TARGET_EFAULT;
902 rfds_ptr = &rfds;
903 } else {
904 rfds_ptr = NULL;
906 if (wfd_addr) {
907 if (copy_from_user_fdset(&wfds, wfd_addr, n))
908 return -TARGET_EFAULT;
909 wfds_ptr = &wfds;
910 } else {
911 wfds_ptr = NULL;
913 if (efd_addr) {
914 if (copy_from_user_fdset(&efds, efd_addr, n))
915 return -TARGET_EFAULT;
916 efds_ptr = &efds;
917 } else {
918 efds_ptr = NULL;
921 if (target_tv_addr) {
922 if (copy_from_user_timeval(&tv, target_tv_addr))
923 return -TARGET_EFAULT;
924 tv_ptr = &tv;
925 } else {
926 tv_ptr = NULL;
929 ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
931 if (!is_error(ret)) {
932 if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
933 return -TARGET_EFAULT;
934 if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
935 return -TARGET_EFAULT;
936 if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
937 return -TARGET_EFAULT;
939 if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
940 return -TARGET_EFAULT;
943 return ret;
946 static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn,
947 abi_ulong target_addr,
948 socklen_t len)
950 struct target_ip_mreqn *target_smreqn;
952 target_smreqn = lock_user(VERIFY_READ, target_addr, len, 1);
953 if (!target_smreqn)
954 return -TARGET_EFAULT;
955 mreqn->imr_multiaddr.s_addr = target_smreqn->imr_multiaddr.s_addr;
956 mreqn->imr_address.s_addr = target_smreqn->imr_address.s_addr;
957 if (len == sizeof(struct target_ip_mreqn))
958 mreqn->imr_ifindex = tswapl(target_smreqn->imr_ifindex);
959 unlock_user(target_smreqn, target_addr, 0);
961 return 0;
964 static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
965 abi_ulong target_addr,
966 socklen_t len)
968 const socklen_t unix_maxlen = sizeof (struct sockaddr_un);
969 sa_family_t sa_family;
970 struct target_sockaddr *target_saddr;
972 target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
973 if (!target_saddr)
974 return -TARGET_EFAULT;
976 sa_family = tswap16(target_saddr->sa_family);
978 /* Oops. The caller might send a incomplete sun_path; sun_path
979 * must be terminated by \0 (see the manual page), but
980 * unfortunately it is quite common to specify sockaddr_un
981 * length as "strlen(x->sun_path)" while it should be
982 * "strlen(...) + 1". We'll fix that here if needed.
983 * Linux kernel has a similar feature.
986 if (sa_family == AF_UNIX) {
987 if (len < unix_maxlen && len > 0) {
988 char *cp = (char*)target_saddr;
990 if ( cp[len-1] && !cp[len] )
991 len++;
993 if (len > unix_maxlen)
994 len = unix_maxlen;
997 memcpy(addr, target_saddr, len);
998 addr->sa_family = sa_family;
999 unlock_user(target_saddr, target_addr, 0);
1001 return 0;
1004 static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
1005 struct sockaddr *addr,
1006 socklen_t len)
1008 struct target_sockaddr *target_saddr;
1010 target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
1011 if (!target_saddr)
1012 return -TARGET_EFAULT;
1013 memcpy(target_saddr, addr, len);
1014 target_saddr->sa_family = tswap16(addr->sa_family);
1015 unlock_user(target_saddr, target_addr, len);
1017 return 0;
1020 /* ??? Should this also swap msgh->name? */
1021 static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
1022 struct target_msghdr *target_msgh)
1024 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1025 abi_long msg_controllen;
1026 abi_ulong target_cmsg_addr;
1027 struct target_cmsghdr *target_cmsg;
1028 socklen_t space = 0;
1030 msg_controllen = tswapl(target_msgh->msg_controllen);
1031 if (msg_controllen < sizeof (struct target_cmsghdr))
1032 goto the_end;
1033 target_cmsg_addr = tswapl(target_msgh->msg_control);
1034 target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
1035 if (!target_cmsg)
1036 return -TARGET_EFAULT;
1038 while (cmsg && target_cmsg) {
1039 void *data = CMSG_DATA(cmsg);
1040 void *target_data = TARGET_CMSG_DATA(target_cmsg);
1042 int len = tswapl(target_cmsg->cmsg_len)
1043 - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
1045 space += CMSG_SPACE(len);
1046 if (space > msgh->msg_controllen) {
1047 space -= CMSG_SPACE(len);
1048 gemu_log("Host cmsg overflow\n");
1049 break;
1052 cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
1053 cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
1054 cmsg->cmsg_len = CMSG_LEN(len);
1056 if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1057 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1058 memcpy(data, target_data, len);
1059 } else {
1060 int *fd = (int *)data;
1061 int *target_fd = (int *)target_data;
1062 int i, numfds = len / sizeof(int);
1064 for (i = 0; i < numfds; i++)
1065 fd[i] = tswap32(target_fd[i]);
1068 cmsg = CMSG_NXTHDR(msgh, cmsg);
1069 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1071 unlock_user(target_cmsg, target_cmsg_addr, 0);
1072 the_end:
1073 msgh->msg_controllen = space;
1074 return 0;
1077 /* ??? Should this also swap msgh->name? */
1078 static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
1079 struct msghdr *msgh)
1081 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1082 abi_long msg_controllen;
1083 abi_ulong target_cmsg_addr;
1084 struct target_cmsghdr *target_cmsg;
1085 socklen_t space = 0;
1087 msg_controllen = tswapl(target_msgh->msg_controllen);
1088 if (msg_controllen < sizeof (struct target_cmsghdr))
1089 goto the_end;
1090 target_cmsg_addr = tswapl(target_msgh->msg_control);
1091 target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
1092 if (!target_cmsg)
1093 return -TARGET_EFAULT;
1095 while (cmsg && target_cmsg) {
1096 void *data = CMSG_DATA(cmsg);
1097 void *target_data = TARGET_CMSG_DATA(target_cmsg);
1099 int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
1101 space += TARGET_CMSG_SPACE(len);
1102 if (space > msg_controllen) {
1103 space -= TARGET_CMSG_SPACE(len);
1104 gemu_log("Target cmsg overflow\n");
1105 break;
1108 target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
1109 target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
1110 target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
1112 if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1113 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1114 memcpy(target_data, data, len);
1115 } else {
1116 int *fd = (int *)data;
1117 int *target_fd = (int *)target_data;
1118 int i, numfds = len / sizeof(int);
1120 for (i = 0; i < numfds; i++)
1121 target_fd[i] = tswap32(fd[i]);
1124 cmsg = CMSG_NXTHDR(msgh, cmsg);
1125 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1127 unlock_user(target_cmsg, target_cmsg_addr, space);
1128 the_end:
1129 target_msgh->msg_controllen = tswapl(space);
1130 return 0;
1133 /* do_setsockopt() Must return target values and target errnos. */
1134 static abi_long do_setsockopt(int sockfd, int level, int optname,
1135 abi_ulong optval_addr, socklen_t optlen)
1137 abi_long ret;
1138 int val;
1139 struct ip_mreqn *ip_mreq;
1140 struct ip_mreq_source *ip_mreq_source;
1142 switch(level) {
1143 case SOL_TCP:
1144 /* TCP options all take an 'int' value. */
1145 if (optlen < sizeof(uint32_t))
1146 return -TARGET_EINVAL;
1148 if (get_user_u32(val, optval_addr))
1149 return -TARGET_EFAULT;
1150 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1151 break;
1152 case SOL_IP:
1153 switch(optname) {
1154 case IP_TOS:
1155 case IP_TTL:
1156 case IP_HDRINCL:
1157 case IP_ROUTER_ALERT:
1158 case IP_RECVOPTS:
1159 case IP_RETOPTS:
1160 case IP_PKTINFO:
1161 case IP_MTU_DISCOVER:
1162 case IP_RECVERR:
1163 case IP_RECVTOS:
1164 #ifdef IP_FREEBIND
1165 case IP_FREEBIND:
1166 #endif
1167 case IP_MULTICAST_TTL:
1168 case IP_MULTICAST_LOOP:
1169 val = 0;
1170 if (optlen >= sizeof(uint32_t)) {
1171 if (get_user_u32(val, optval_addr))
1172 return -TARGET_EFAULT;
1173 } else if (optlen >= 1) {
1174 if (get_user_u8(val, optval_addr))
1175 return -TARGET_EFAULT;
1177 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1178 break;
1179 case IP_ADD_MEMBERSHIP:
1180 case IP_DROP_MEMBERSHIP:
1181 if (optlen < sizeof (struct target_ip_mreq) ||
1182 optlen > sizeof (struct target_ip_mreqn))
1183 return -TARGET_EINVAL;
1185 ip_mreq = (struct ip_mreqn *) alloca(optlen);
1186 target_to_host_ip_mreq(ip_mreq, optval_addr, optlen);
1187 ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq, optlen));
1188 break;
1190 case IP_BLOCK_SOURCE:
1191 case IP_UNBLOCK_SOURCE:
1192 case IP_ADD_SOURCE_MEMBERSHIP:
1193 case IP_DROP_SOURCE_MEMBERSHIP:
1194 if (optlen != sizeof (struct target_ip_mreq_source))
1195 return -TARGET_EINVAL;
1197 ip_mreq_source = lock_user(VERIFY_READ, optval_addr, optlen, 1);
1198 ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq_source, optlen));
1199 unlock_user (ip_mreq_source, optval_addr, 0);
1200 break;
1202 default:
1203 goto unimplemented;
1205 break;
1206 case TARGET_SOL_SOCKET:
1207 switch (optname) {
1208 /* Options with 'int' argument. */
1209 case TARGET_SO_DEBUG:
1210 optname = SO_DEBUG;
1211 break;
1212 case TARGET_SO_REUSEADDR:
1213 optname = SO_REUSEADDR;
1214 break;
1215 case TARGET_SO_TYPE:
1216 optname = SO_TYPE;
1217 break;
1218 case TARGET_SO_ERROR:
1219 optname = SO_ERROR;
1220 break;
1221 case TARGET_SO_DONTROUTE:
1222 optname = SO_DONTROUTE;
1223 break;
1224 case TARGET_SO_BROADCAST:
1225 optname = SO_BROADCAST;
1226 break;
1227 case TARGET_SO_SNDBUF:
1228 optname = SO_SNDBUF;
1229 break;
1230 case TARGET_SO_RCVBUF:
1231 optname = SO_RCVBUF;
1232 break;
1233 case TARGET_SO_KEEPALIVE:
1234 optname = SO_KEEPALIVE;
1235 break;
1236 case TARGET_SO_OOBINLINE:
1237 optname = SO_OOBINLINE;
1238 break;
1239 case TARGET_SO_NO_CHECK:
1240 optname = SO_NO_CHECK;
1241 break;
1242 case TARGET_SO_PRIORITY:
1243 optname = SO_PRIORITY;
1244 break;
1245 #ifdef SO_BSDCOMPAT
1246 case TARGET_SO_BSDCOMPAT:
1247 optname = SO_BSDCOMPAT;
1248 break;
1249 #endif
1250 case TARGET_SO_PASSCRED:
1251 optname = SO_PASSCRED;
1252 break;
1253 case TARGET_SO_TIMESTAMP:
1254 optname = SO_TIMESTAMP;
1255 break;
1256 case TARGET_SO_RCVLOWAT:
1257 optname = SO_RCVLOWAT;
1258 break;
1259 case TARGET_SO_RCVTIMEO:
1260 optname = SO_RCVTIMEO;
1261 break;
1262 case TARGET_SO_SNDTIMEO:
1263 optname = SO_SNDTIMEO;
1264 break;
1265 break;
1266 default:
1267 goto unimplemented;
1269 if (optlen < sizeof(uint32_t))
1270 return -TARGET_EINVAL;
1272 if (get_user_u32(val, optval_addr))
1273 return -TARGET_EFAULT;
1274 ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
1275 break;
1276 default:
1277 unimplemented:
1278 gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
1279 ret = -TARGET_ENOPROTOOPT;
1281 return ret;
1284 /* do_getsockopt() Must return target values and target errnos. */
1285 static abi_long do_getsockopt(int sockfd, int level, int optname,
1286 abi_ulong optval_addr, abi_ulong optlen)
1288 abi_long ret;
1289 int len, val;
1290 socklen_t lv;
1292 switch(level) {
1293 case TARGET_SOL_SOCKET:
1294 level = SOL_SOCKET;
1295 switch (optname) {
1296 case TARGET_SO_LINGER:
1297 case TARGET_SO_RCVTIMEO:
1298 case TARGET_SO_SNDTIMEO:
1299 case TARGET_SO_PEERCRED:
1300 case TARGET_SO_PEERNAME:
1301 /* These don't just return a single integer */
1302 goto unimplemented;
1303 default:
1304 goto int_case;
1306 break;
1307 case SOL_TCP:
1308 /* TCP options all take an 'int' value. */
1309 int_case:
1310 if (get_user_u32(len, optlen))
1311 return -TARGET_EFAULT;
1312 if (len < 0)
1313 return -TARGET_EINVAL;
1314 lv = sizeof(int);
1315 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1316 if (ret < 0)
1317 return ret;
1318 val = tswap32(val);
1319 if (len > lv)
1320 len = lv;
1321 if (len == 4) {
1322 if (put_user_u32(val, optval_addr))
1323 return -TARGET_EFAULT;
1324 } else {
1325 if (put_user_u8(val, optval_addr))
1326 return -TARGET_EFAULT;
1328 if (put_user_u32(len, optlen))
1329 return -TARGET_EFAULT;
1330 break;
1331 case SOL_IP:
1332 switch(optname) {
1333 case IP_TOS:
1334 case IP_TTL:
1335 case IP_HDRINCL:
1336 case IP_ROUTER_ALERT:
1337 case IP_RECVOPTS:
1338 case IP_RETOPTS:
1339 case IP_PKTINFO:
1340 case IP_MTU_DISCOVER:
1341 case IP_RECVERR:
1342 case IP_RECVTOS:
1343 #ifdef IP_FREEBIND
1344 case IP_FREEBIND:
1345 #endif
1346 case IP_MULTICAST_TTL:
1347 case IP_MULTICAST_LOOP:
1348 if (get_user_u32(len, optlen))
1349 return -TARGET_EFAULT;
1350 if (len < 0)
1351 return -TARGET_EINVAL;
1352 lv = sizeof(int);
1353 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1354 if (ret < 0)
1355 return ret;
1356 if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
1357 len = 1;
1358 if (put_user_u32(len, optlen)
1359 || put_user_u8(val, optval_addr))
1360 return -TARGET_EFAULT;
1361 } else {
1362 if (len > sizeof(int))
1363 len = sizeof(int);
1364 if (put_user_u32(len, optlen)
1365 || put_user_u32(val, optval_addr))
1366 return -TARGET_EFAULT;
1368 break;
1369 default:
1370 ret = -TARGET_ENOPROTOOPT;
1371 break;
1373 break;
1374 default:
1375 unimplemented:
1376 gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1377 level, optname);
1378 ret = -TARGET_EOPNOTSUPP;
1379 break;
1381 return ret;
1384 /* FIXME
1385 * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1386 * other lock functions have a return code of 0 for failure.
1388 static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1389 int count, int copy)
1391 struct target_iovec *target_vec;
1392 abi_ulong base;
1393 int i;
1395 target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1396 if (!target_vec)
1397 return -TARGET_EFAULT;
1398 for(i = 0;i < count; i++) {
1399 base = tswapl(target_vec[i].iov_base);
1400 vec[i].iov_len = tswapl(target_vec[i].iov_len);
1401 if (vec[i].iov_len != 0) {
1402 vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
1403 /* Don't check lock_user return value. We must call writev even
1404 if a element has invalid base address. */
1405 } else {
1406 /* zero length pointer is ignored */
1407 vec[i].iov_base = NULL;
1410 unlock_user (target_vec, target_addr, 0);
1411 return 0;
1414 static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1415 int count, int copy)
1417 struct target_iovec *target_vec;
1418 abi_ulong base;
1419 int i;
1421 target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1422 if (!target_vec)
1423 return -TARGET_EFAULT;
1424 for(i = 0;i < count; i++) {
1425 if (target_vec[i].iov_base) {
1426 base = tswapl(target_vec[i].iov_base);
1427 unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1430 unlock_user (target_vec, target_addr, 0);
1432 return 0;
1435 /* do_socket() Must return target values and target errnos. */
1436 static abi_long do_socket(int domain, int type, int protocol)
1438 #if defined(TARGET_MIPS)
1439 switch(type) {
1440 case TARGET_SOCK_DGRAM:
1441 type = SOCK_DGRAM;
1442 break;
1443 case TARGET_SOCK_STREAM:
1444 type = SOCK_STREAM;
1445 break;
1446 case TARGET_SOCK_RAW:
1447 type = SOCK_RAW;
1448 break;
1449 case TARGET_SOCK_RDM:
1450 type = SOCK_RDM;
1451 break;
1452 case TARGET_SOCK_SEQPACKET:
1453 type = SOCK_SEQPACKET;
1454 break;
1455 case TARGET_SOCK_PACKET:
1456 type = SOCK_PACKET;
1457 break;
1459 #endif
1460 if (domain == PF_NETLINK)
1461 return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1462 return get_errno(socket(domain, type, protocol));
1465 /* do_bind() Must return target values and target errnos. */
1466 static abi_long do_bind(int sockfd, abi_ulong target_addr,
1467 socklen_t addrlen)
1469 void *addr;
1471 if (addrlen < 0)
1472 return -TARGET_EINVAL;
1474 addr = alloca(addrlen+1);
1476 target_to_host_sockaddr(addr, target_addr, addrlen);
1477 return get_errno(bind(sockfd, addr, addrlen));
1480 /* do_connect() Must return target values and target errnos. */
1481 static abi_long do_connect(int sockfd, abi_ulong target_addr,
1482 socklen_t addrlen)
1484 void *addr;
1486 if (addrlen < 0)
1487 return -TARGET_EINVAL;
1489 addr = alloca(addrlen);
1491 target_to_host_sockaddr(addr, target_addr, addrlen);
1492 return get_errno(connect(sockfd, addr, addrlen));
1495 /* do_sendrecvmsg() Must return target values and target errnos. */
1496 static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1497 int flags, int send)
1499 abi_long ret, len;
1500 struct target_msghdr *msgp;
1501 struct msghdr msg;
1502 int count;
1503 struct iovec *vec;
1504 abi_ulong target_vec;
1506 /* FIXME */
1507 if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1508 msgp,
1509 target_msg,
1510 send ? 1 : 0))
1511 return -TARGET_EFAULT;
1512 if (msgp->msg_name) {
1513 msg.msg_namelen = tswap32(msgp->msg_namelen);
1514 msg.msg_name = alloca(msg.msg_namelen);
1515 target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
1516 msg.msg_namelen);
1517 } else {
1518 msg.msg_name = NULL;
1519 msg.msg_namelen = 0;
1521 msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
1522 msg.msg_control = alloca(msg.msg_controllen);
1523 msg.msg_flags = tswap32(msgp->msg_flags);
1525 count = tswapl(msgp->msg_iovlen);
1526 vec = alloca(count * sizeof(struct iovec));
1527 target_vec = tswapl(msgp->msg_iov);
1528 lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1529 msg.msg_iovlen = count;
1530 msg.msg_iov = vec;
1532 if (send) {
1533 ret = target_to_host_cmsg(&msg, msgp);
1534 if (ret == 0)
1535 ret = get_errno(sendmsg(fd, &msg, flags));
1536 } else {
1537 ret = get_errno(recvmsg(fd, &msg, flags));
1538 if (!is_error(ret)) {
1539 len = ret;
1540 ret = host_to_target_cmsg(msgp, &msg);
1541 if (!is_error(ret))
1542 ret = len;
1545 unlock_iovec(vec, target_vec, count, !send);
1546 unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1547 return ret;
1550 /* do_accept() Must return target values and target errnos. */
1551 static abi_long do_accept(int fd, abi_ulong target_addr,
1552 abi_ulong target_addrlen_addr)
1554 socklen_t addrlen;
1555 void *addr;
1556 abi_long ret;
1558 if (get_user_u32(addrlen, target_addrlen_addr))
1559 return -TARGET_EFAULT;
1561 if (addrlen < 0)
1562 return -TARGET_EINVAL;
1564 addr = alloca(addrlen);
1566 ret = get_errno(accept(fd, addr, &addrlen));
1567 if (!is_error(ret)) {
1568 host_to_target_sockaddr(target_addr, addr, addrlen);
1569 if (put_user_u32(addrlen, target_addrlen_addr))
1570 ret = -TARGET_EFAULT;
1572 return ret;
1575 /* do_getpeername() Must return target values and target errnos. */
1576 static abi_long do_getpeername(int fd, abi_ulong target_addr,
1577 abi_ulong target_addrlen_addr)
1579 socklen_t addrlen;
1580 void *addr;
1581 abi_long ret;
1583 if (get_user_u32(addrlen, target_addrlen_addr))
1584 return -TARGET_EFAULT;
1586 if (addrlen < 0)
1587 return -TARGET_EINVAL;
1589 addr = alloca(addrlen);
1591 ret = get_errno(getpeername(fd, addr, &addrlen));
1592 if (!is_error(ret)) {
1593 host_to_target_sockaddr(target_addr, addr, addrlen);
1594 if (put_user_u32(addrlen, target_addrlen_addr))
1595 ret = -TARGET_EFAULT;
1597 return ret;
1600 /* do_getsockname() Must return target values and target errnos. */
1601 static abi_long do_getsockname(int fd, abi_ulong target_addr,
1602 abi_ulong target_addrlen_addr)
1604 socklen_t addrlen;
1605 void *addr;
1606 abi_long ret;
1608 if (target_addr == 0)
1609 return get_errno(accept(fd, NULL, NULL));
1611 if (get_user_u32(addrlen, target_addrlen_addr))
1612 return -TARGET_EFAULT;
1614 if (addrlen < 0)
1615 return -TARGET_EINVAL;
1617 addr = alloca(addrlen);
1619 ret = get_errno(getsockname(fd, addr, &addrlen));
1620 if (!is_error(ret)) {
1621 host_to_target_sockaddr(target_addr, addr, addrlen);
1622 if (put_user_u32(addrlen, target_addrlen_addr))
1623 ret = -TARGET_EFAULT;
1625 return ret;
1628 /* do_socketpair() Must return target values and target errnos. */
1629 static abi_long do_socketpair(int domain, int type, int protocol,
1630 abi_ulong target_tab_addr)
1632 int tab[2];
1633 abi_long ret;
1635 ret = get_errno(socketpair(domain, type, protocol, tab));
1636 if (!is_error(ret)) {
1637 if (put_user_s32(tab[0], target_tab_addr)
1638 || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1639 ret = -TARGET_EFAULT;
1641 return ret;
1644 /* do_sendto() Must return target values and target errnos. */
1645 static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
1646 abi_ulong target_addr, socklen_t addrlen)
1648 void *addr;
1649 void *host_msg;
1650 abi_long ret;
1652 if (addrlen < 0)
1653 return -TARGET_EINVAL;
1655 host_msg = lock_user(VERIFY_READ, msg, len, 1);
1656 if (!host_msg)
1657 return -TARGET_EFAULT;
1658 if (target_addr) {
1659 addr = alloca(addrlen);
1660 target_to_host_sockaddr(addr, target_addr, addrlen);
1661 ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
1662 } else {
1663 ret = get_errno(send(fd, host_msg, len, flags));
1665 unlock_user(host_msg, msg, 0);
1666 return ret;
1669 /* do_recvfrom() Must return target values and target errnos. */
1670 static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
1671 abi_ulong target_addr,
1672 abi_ulong target_addrlen)
1674 socklen_t addrlen;
1675 void *addr;
1676 void *host_msg;
1677 abi_long ret;
1679 host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
1680 if (!host_msg)
1681 return -TARGET_EFAULT;
1682 if (target_addr) {
1683 if (get_user_u32(addrlen, target_addrlen)) {
1684 ret = -TARGET_EFAULT;
1685 goto fail;
1687 if (addrlen < 0) {
1688 ret = -TARGET_EINVAL;
1689 goto fail;
1691 addr = alloca(addrlen);
1692 ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
1693 } else {
1694 addr = NULL; /* To keep compiler quiet. */
1695 ret = get_errno(recv(fd, host_msg, len, flags));
1697 if (!is_error(ret)) {
1698 if (target_addr) {
1699 host_to_target_sockaddr(target_addr, addr, addrlen);
1700 if (put_user_u32(addrlen, target_addrlen)) {
1701 ret = -TARGET_EFAULT;
1702 goto fail;
1705 unlock_user(host_msg, msg, len);
1706 } else {
1707 fail:
1708 unlock_user(host_msg, msg, 0);
1710 return ret;
1713 #ifdef TARGET_NR_socketcall
1714 /* do_socketcall() Must return target values and target errnos. */
1715 static abi_long do_socketcall(int num, abi_ulong vptr)
1717 abi_long ret;
1718 const int n = sizeof(abi_ulong);
1720 switch(num) {
1721 case SOCKOP_socket:
1723 int domain, type, protocol;
1725 if (get_user_s32(domain, vptr)
1726 || get_user_s32(type, vptr + n)
1727 || get_user_s32(protocol, vptr + 2 * n))
1728 return -TARGET_EFAULT;
1730 ret = do_socket(domain, type, protocol);
1732 break;
1733 case SOCKOP_bind:
1735 int sockfd;
1736 abi_ulong target_addr;
1737 socklen_t addrlen;
1739 if (get_user_s32(sockfd, vptr)
1740 || get_user_ual(target_addr, vptr + n)
1741 || get_user_u32(addrlen, vptr + 2 * n))
1742 return -TARGET_EFAULT;
1744 ret = do_bind(sockfd, target_addr, addrlen);
1746 break;
1747 case SOCKOP_connect:
1749 int sockfd;
1750 abi_ulong target_addr;
1751 socklen_t addrlen;
1753 if (get_user_s32(sockfd, vptr)
1754 || get_user_ual(target_addr, vptr + n)
1755 || get_user_u32(addrlen, vptr + 2 * n))
1756 return -TARGET_EFAULT;
1758 ret = do_connect(sockfd, target_addr, addrlen);
1760 break;
1761 case SOCKOP_listen:
1763 int sockfd, backlog;
1765 if (get_user_s32(sockfd, vptr)
1766 || get_user_s32(backlog, vptr + n))
1767 return -TARGET_EFAULT;
1769 ret = get_errno(listen(sockfd, backlog));
1771 break;
1772 case SOCKOP_accept:
1774 int sockfd;
1775 abi_ulong target_addr, target_addrlen;
1777 if (get_user_s32(sockfd, vptr)
1778 || get_user_ual(target_addr, vptr + n)
1779 || get_user_u32(target_addrlen, vptr + 2 * n))
1780 return -TARGET_EFAULT;
1782 ret = do_accept(sockfd, target_addr, target_addrlen);
1784 break;
1785 case SOCKOP_getsockname:
1787 int sockfd;
1788 abi_ulong target_addr, target_addrlen;
1790 if (get_user_s32(sockfd, vptr)
1791 || get_user_ual(target_addr, vptr + n)
1792 || get_user_u32(target_addrlen, vptr + 2 * n))
1793 return -TARGET_EFAULT;
1795 ret = do_getsockname(sockfd, target_addr, target_addrlen);
1797 break;
1798 case SOCKOP_getpeername:
1800 int sockfd;
1801 abi_ulong target_addr, target_addrlen;
1803 if (get_user_s32(sockfd, vptr)
1804 || get_user_ual(target_addr, vptr + n)
1805 || get_user_u32(target_addrlen, vptr + 2 * n))
1806 return -TARGET_EFAULT;
1808 ret = do_getpeername(sockfd, target_addr, target_addrlen);
1810 break;
1811 case SOCKOP_socketpair:
1813 int domain, type, protocol;
1814 abi_ulong tab;
1816 if (get_user_s32(domain, vptr)
1817 || get_user_s32(type, vptr + n)
1818 || get_user_s32(protocol, vptr + 2 * n)
1819 || get_user_ual(tab, vptr + 3 * n))
1820 return -TARGET_EFAULT;
1822 ret = do_socketpair(domain, type, protocol, tab);
1824 break;
1825 case SOCKOP_send:
1827 int sockfd;
1828 abi_ulong msg;
1829 size_t len;
1830 int flags;
1832 if (get_user_s32(sockfd, vptr)
1833 || get_user_ual(msg, vptr + n)
1834 || get_user_ual(len, vptr + 2 * n)
1835 || get_user_s32(flags, vptr + 3 * n))
1836 return -TARGET_EFAULT;
1838 ret = do_sendto(sockfd, msg, len, flags, 0, 0);
1840 break;
1841 case SOCKOP_recv:
1843 int sockfd;
1844 abi_ulong msg;
1845 size_t len;
1846 int flags;
1848 if (get_user_s32(sockfd, vptr)
1849 || get_user_ual(msg, vptr + n)
1850 || get_user_ual(len, vptr + 2 * n)
1851 || get_user_s32(flags, vptr + 3 * n))
1852 return -TARGET_EFAULT;
1854 ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
1856 break;
1857 case SOCKOP_sendto:
1859 int sockfd;
1860 abi_ulong msg;
1861 size_t len;
1862 int flags;
1863 abi_ulong addr;
1864 socklen_t addrlen;
1866 if (get_user_s32(sockfd, vptr)
1867 || get_user_ual(msg, vptr + n)
1868 || get_user_ual(len, vptr + 2 * n)
1869 || get_user_s32(flags, vptr + 3 * n)
1870 || get_user_ual(addr, vptr + 4 * n)
1871 || get_user_u32(addrlen, vptr + 5 * n))
1872 return -TARGET_EFAULT;
1874 ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
1876 break;
1877 case SOCKOP_recvfrom:
1879 int sockfd;
1880 abi_ulong msg;
1881 size_t len;
1882 int flags;
1883 abi_ulong addr;
1884 socklen_t addrlen;
1886 if (get_user_s32(sockfd, vptr)
1887 || get_user_ual(msg, vptr + n)
1888 || get_user_ual(len, vptr + 2 * n)
1889 || get_user_s32(flags, vptr + 3 * n)
1890 || get_user_ual(addr, vptr + 4 * n)
1891 || get_user_u32(addrlen, vptr + 5 * n))
1892 return -TARGET_EFAULT;
1894 ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
1896 break;
1897 case SOCKOP_shutdown:
1899 int sockfd, how;
1901 if (get_user_s32(sockfd, vptr)
1902 || get_user_s32(how, vptr + n))
1903 return -TARGET_EFAULT;
1905 ret = get_errno(shutdown(sockfd, how));
1907 break;
1908 case SOCKOP_sendmsg:
1909 case SOCKOP_recvmsg:
1911 int fd;
1912 abi_ulong target_msg;
1913 int flags;
1915 if (get_user_s32(fd, vptr)
1916 || get_user_ual(target_msg, vptr + n)
1917 || get_user_s32(flags, vptr + 2 * n))
1918 return -TARGET_EFAULT;
1920 ret = do_sendrecvmsg(fd, target_msg, flags,
1921 (num == SOCKOP_sendmsg));
1923 break;
1924 case SOCKOP_setsockopt:
1926 int sockfd;
1927 int level;
1928 int optname;
1929 abi_ulong optval;
1930 socklen_t optlen;
1932 if (get_user_s32(sockfd, vptr)
1933 || get_user_s32(level, vptr + n)
1934 || get_user_s32(optname, vptr + 2 * n)
1935 || get_user_ual(optval, vptr + 3 * n)
1936 || get_user_u32(optlen, vptr + 4 * n))
1937 return -TARGET_EFAULT;
1939 ret = do_setsockopt(sockfd, level, optname, optval, optlen);
1941 break;
1942 case SOCKOP_getsockopt:
1944 int sockfd;
1945 int level;
1946 int optname;
1947 abi_ulong optval;
1948 socklen_t optlen;
1950 if (get_user_s32(sockfd, vptr)
1951 || get_user_s32(level, vptr + n)
1952 || get_user_s32(optname, vptr + 2 * n)
1953 || get_user_ual(optval, vptr + 3 * n)
1954 || get_user_u32(optlen, vptr + 4 * n))
1955 return -TARGET_EFAULT;
1957 ret = do_getsockopt(sockfd, level, optname, optval, optlen);
1959 break;
1960 default:
1961 gemu_log("Unsupported socketcall: %d\n", num);
1962 ret = -TARGET_ENOSYS;
1963 break;
1965 return ret;
1967 #endif
1969 #define N_SHM_REGIONS 32
1971 static struct shm_region {
1972 abi_ulong start;
1973 abi_ulong size;
1974 } shm_regions[N_SHM_REGIONS];
1976 struct target_ipc_perm
1978 abi_long __key;
1979 abi_ulong uid;
1980 abi_ulong gid;
1981 abi_ulong cuid;
1982 abi_ulong cgid;
1983 unsigned short int mode;
1984 unsigned short int __pad1;
1985 unsigned short int __seq;
1986 unsigned short int __pad2;
1987 abi_ulong __unused1;
1988 abi_ulong __unused2;
1991 struct target_semid_ds
1993 struct target_ipc_perm sem_perm;
1994 abi_ulong sem_otime;
1995 abi_ulong __unused1;
1996 abi_ulong sem_ctime;
1997 abi_ulong __unused2;
1998 abi_ulong sem_nsems;
1999 abi_ulong __unused3;
2000 abi_ulong __unused4;
2003 static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
2004 abi_ulong target_addr)
2006 struct target_ipc_perm *target_ip;
2007 struct target_semid_ds *target_sd;
2009 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2010 return -TARGET_EFAULT;
2011 target_ip=&(target_sd->sem_perm);
2012 host_ip->__key = tswapl(target_ip->__key);
2013 host_ip->uid = tswapl(target_ip->uid);
2014 host_ip->gid = tswapl(target_ip->gid);
2015 host_ip->cuid = tswapl(target_ip->cuid);
2016 host_ip->cgid = tswapl(target_ip->cgid);
2017 host_ip->mode = tswapl(target_ip->mode);
2018 unlock_user_struct(target_sd, target_addr, 0);
2019 return 0;
2022 static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
2023 struct ipc_perm *host_ip)
2025 struct target_ipc_perm *target_ip;
2026 struct target_semid_ds *target_sd;
2028 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2029 return -TARGET_EFAULT;
2030 target_ip = &(target_sd->sem_perm);
2031 target_ip->__key = tswapl(host_ip->__key);
2032 target_ip->uid = tswapl(host_ip->uid);
2033 target_ip->gid = tswapl(host_ip->gid);
2034 target_ip->cuid = tswapl(host_ip->cuid);
2035 target_ip->cgid = tswapl(host_ip->cgid);
2036 target_ip->mode = tswapl(host_ip->mode);
2037 unlock_user_struct(target_sd, target_addr, 1);
2038 return 0;
2041 static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
2042 abi_ulong target_addr)
2044 struct target_semid_ds *target_sd;
2046 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2047 return -TARGET_EFAULT;
2048 if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr))
2049 return -TARGET_EFAULT;
2050 host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
2051 host_sd->sem_otime = tswapl(target_sd->sem_otime);
2052 host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
2053 unlock_user_struct(target_sd, target_addr, 0);
2054 return 0;
2057 static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
2058 struct semid_ds *host_sd)
2060 struct target_semid_ds *target_sd;
2062 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2063 return -TARGET_EFAULT;
2064 if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
2065 return -TARGET_EFAULT;;
2066 target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
2067 target_sd->sem_otime = tswapl(host_sd->sem_otime);
2068 target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
2069 unlock_user_struct(target_sd, target_addr, 1);
2070 return 0;
2073 struct target_seminfo {
2074 int semmap;
2075 int semmni;
2076 int semmns;
2077 int semmnu;
2078 int semmsl;
2079 int semopm;
2080 int semume;
2081 int semusz;
2082 int semvmx;
2083 int semaem;
2086 static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
2087 struct seminfo *host_seminfo)
2089 struct target_seminfo *target_seminfo;
2090 if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
2091 return -TARGET_EFAULT;
2092 __put_user(host_seminfo->semmap, &target_seminfo->semmap);
2093 __put_user(host_seminfo->semmni, &target_seminfo->semmni);
2094 __put_user(host_seminfo->semmns, &target_seminfo->semmns);
2095 __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
2096 __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
2097 __put_user(host_seminfo->semopm, &target_seminfo->semopm);
2098 __put_user(host_seminfo->semume, &target_seminfo->semume);
2099 __put_user(host_seminfo->semusz, &target_seminfo->semusz);
2100 __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
2101 __put_user(host_seminfo->semaem, &target_seminfo->semaem);
2102 unlock_user_struct(target_seminfo, target_addr, 1);
2103 return 0;
2106 union semun {
2107 int val;
2108 struct semid_ds *buf;
2109 unsigned short *array;
2110 struct seminfo *__buf;
2113 union target_semun {
2114 int val;
2115 abi_ulong buf;
2116 abi_ulong array;
2117 abi_ulong __buf;
2120 static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
2121 abi_ulong target_addr)
2123 int nsems;
2124 unsigned short *array;
2125 union semun semun;
2126 struct semid_ds semid_ds;
2127 int i, ret;
2129 semun.buf = &semid_ds;
2131 ret = semctl(semid, 0, IPC_STAT, semun);
2132 if (ret == -1)
2133 return get_errno(ret);
2135 nsems = semid_ds.sem_nsems;
2137 *host_array = malloc(nsems*sizeof(unsigned short));
2138 array = lock_user(VERIFY_READ, target_addr,
2139 nsems*sizeof(unsigned short), 1);
2140 if (!array)
2141 return -TARGET_EFAULT;
2143 for(i=0; i<nsems; i++) {
2144 __get_user((*host_array)[i], &array[i]);
2146 unlock_user(array, target_addr, 0);
2148 return 0;
2151 static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
2152 unsigned short **host_array)
2154 int nsems;
2155 unsigned short *array;
2156 union semun semun;
2157 struct semid_ds semid_ds;
2158 int i, ret;
2160 semun.buf = &semid_ds;
2162 ret = semctl(semid, 0, IPC_STAT, semun);
2163 if (ret == -1)
2164 return get_errno(ret);
2166 nsems = semid_ds.sem_nsems;
2168 array = lock_user(VERIFY_WRITE, target_addr,
2169 nsems*sizeof(unsigned short), 0);
2170 if (!array)
2171 return -TARGET_EFAULT;
2173 for(i=0; i<nsems; i++) {
2174 __put_user((*host_array)[i], &array[i]);
2176 free(*host_array);
2177 unlock_user(array, target_addr, 1);
2179 return 0;
2182 static inline abi_long do_semctl(int semid, int semnum, int cmd,
2183 union target_semun target_su)
2185 union semun arg;
2186 struct semid_ds dsarg;
2187 unsigned short *array;
2188 struct seminfo seminfo;
2189 abi_long ret = -TARGET_EINVAL;
2190 abi_long err;
2191 cmd &= 0xff;
2193 switch( cmd ) {
2194 case GETVAL:
2195 case SETVAL:
2196 arg.val = tswapl(target_su.val);
2197 ret = get_errno(semctl(semid, semnum, cmd, arg));
2198 target_su.val = tswapl(arg.val);
2199 break;
2200 case GETALL:
2201 case SETALL:
2202 err = target_to_host_semarray(semid, &array, target_su.array);
2203 if (err)
2204 return err;
2205 arg.array = array;
2206 ret = get_errno(semctl(semid, semnum, cmd, arg));
2207 err = host_to_target_semarray(semid, target_su.array, &array);
2208 if (err)
2209 return err;
2210 break;
2211 case IPC_STAT:
2212 case IPC_SET:
2213 case SEM_STAT:
2214 err = target_to_host_semid_ds(&dsarg, target_su.buf);
2215 if (err)
2216 return err;
2217 arg.buf = &dsarg;
2218 ret = get_errno(semctl(semid, semnum, cmd, arg));
2219 err = host_to_target_semid_ds(target_su.buf, &dsarg);
2220 if (err)
2221 return err;
2222 break;
2223 case IPC_INFO:
2224 case SEM_INFO:
2225 arg.__buf = &seminfo;
2226 ret = get_errno(semctl(semid, semnum, cmd, arg));
2227 err = host_to_target_seminfo(target_su.__buf, &seminfo);
2228 if (err)
2229 return err;
2230 break;
2231 case IPC_RMID:
2232 case GETPID:
2233 case GETNCNT:
2234 case GETZCNT:
2235 ret = get_errno(semctl(semid, semnum, cmd, NULL));
2236 break;
2239 return ret;
2242 struct target_sembuf {
2243 unsigned short sem_num;
2244 short sem_op;
2245 short sem_flg;
2248 static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
2249 abi_ulong target_addr,
2250 unsigned nsops)
2252 struct target_sembuf *target_sembuf;
2253 int i;
2255 target_sembuf = lock_user(VERIFY_READ, target_addr,
2256 nsops*sizeof(struct target_sembuf), 1);
2257 if (!target_sembuf)
2258 return -TARGET_EFAULT;
2260 for(i=0; i<nsops; i++) {
2261 __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
2262 __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
2263 __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
2266 unlock_user(target_sembuf, target_addr, 0);
2268 return 0;
2271 static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
2273 struct sembuf sops[nsops];
2275 if (target_to_host_sembuf(sops, ptr, nsops))
2276 return -TARGET_EFAULT;
2278 return semop(semid, sops, nsops);
2281 struct target_msqid_ds
2283 struct target_ipc_perm msg_perm;
2284 abi_ulong msg_stime;
2285 #if TARGET_ABI_BITS == 32
2286 abi_ulong __unused1;
2287 #endif
2288 abi_ulong msg_rtime;
2289 #if TARGET_ABI_BITS == 32
2290 abi_ulong __unused2;
2291 #endif
2292 abi_ulong msg_ctime;
2293 #if TARGET_ABI_BITS == 32
2294 abi_ulong __unused3;
2295 #endif
2296 abi_ulong __msg_cbytes;
2297 abi_ulong msg_qnum;
2298 abi_ulong msg_qbytes;
2299 abi_ulong msg_lspid;
2300 abi_ulong msg_lrpid;
2301 abi_ulong __unused4;
2302 abi_ulong __unused5;
2305 static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
2306 abi_ulong target_addr)
2308 struct target_msqid_ds *target_md;
2310 if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
2311 return -TARGET_EFAULT;
2312 if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
2313 return -TARGET_EFAULT;
2314 host_md->msg_stime = tswapl(target_md->msg_stime);
2315 host_md->msg_rtime = tswapl(target_md->msg_rtime);
2316 host_md->msg_ctime = tswapl(target_md->msg_ctime);
2317 host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
2318 host_md->msg_qnum = tswapl(target_md->msg_qnum);
2319 host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
2320 host_md->msg_lspid = tswapl(target_md->msg_lspid);
2321 host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
2322 unlock_user_struct(target_md, target_addr, 0);
2323 return 0;
2326 static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
2327 struct msqid_ds *host_md)
2329 struct target_msqid_ds *target_md;
2331 if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
2332 return -TARGET_EFAULT;
2333 if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
2334 return -TARGET_EFAULT;
2335 target_md->msg_stime = tswapl(host_md->msg_stime);
2336 target_md->msg_rtime = tswapl(host_md->msg_rtime);
2337 target_md->msg_ctime = tswapl(host_md->msg_ctime);
2338 target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
2339 target_md->msg_qnum = tswapl(host_md->msg_qnum);
2340 target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
2341 target_md->msg_lspid = tswapl(host_md->msg_lspid);
2342 target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
2343 unlock_user_struct(target_md, target_addr, 1);
2344 return 0;
2347 struct target_msginfo {
2348 int msgpool;
2349 int msgmap;
2350 int msgmax;
2351 int msgmnb;
2352 int msgmni;
2353 int msgssz;
2354 int msgtql;
2355 unsigned short int msgseg;
2358 static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
2359 struct msginfo *host_msginfo)
2361 struct target_msginfo *target_msginfo;
2362 if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
2363 return -TARGET_EFAULT;
2364 __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
2365 __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
2366 __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
2367 __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
2368 __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
2369 __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
2370 __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
2371 __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
2372 unlock_user_struct(target_msginfo, target_addr, 1);
2373 return 0;
2376 static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
2378 struct msqid_ds dsarg;
2379 struct msginfo msginfo;
2380 abi_long ret = -TARGET_EINVAL;
2382 cmd &= 0xff;
2384 switch (cmd) {
2385 case IPC_STAT:
2386 case IPC_SET:
2387 case MSG_STAT:
2388 if (target_to_host_msqid_ds(&dsarg,ptr))
2389 return -TARGET_EFAULT;
2390 ret = get_errno(msgctl(msgid, cmd, &dsarg));
2391 if (host_to_target_msqid_ds(ptr,&dsarg))
2392 return -TARGET_EFAULT;
2393 break;
2394 case IPC_RMID:
2395 ret = get_errno(msgctl(msgid, cmd, NULL));
2396 break;
2397 case IPC_INFO:
2398 case MSG_INFO:
2399 ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
2400 if (host_to_target_msginfo(ptr, &msginfo))
2401 return -TARGET_EFAULT;
2402 break;
2405 return ret;
2408 struct target_msgbuf {
2409 abi_long mtype;
2410 char mtext[1];
2413 static inline abi_long do_msgsnd(int msqid, abi_long msgp,
2414 unsigned int msgsz, int msgflg)
2416 struct target_msgbuf *target_mb;
2417 struct msgbuf *host_mb;
2418 abi_long ret = 0;
2420 if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
2421 return -TARGET_EFAULT;
2422 host_mb = malloc(msgsz+sizeof(long));
2423 host_mb->mtype = (abi_long) tswapl(target_mb->mtype);
2424 memcpy(host_mb->mtext, target_mb->mtext, msgsz);
2425 ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
2426 free(host_mb);
2427 unlock_user_struct(target_mb, msgp, 0);
2429 return ret;
2432 static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2433 unsigned int msgsz, abi_long msgtyp,
2434 int msgflg)
2436 struct target_msgbuf *target_mb;
2437 char *target_mtext;
2438 struct msgbuf *host_mb;
2439 abi_long ret = 0;
2441 if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2442 return -TARGET_EFAULT;
2444 host_mb = malloc(msgsz+sizeof(long));
2445 ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapl(msgtyp), msgflg));
2447 if (ret > 0) {
2448 abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2449 target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2450 if (!target_mtext) {
2451 ret = -TARGET_EFAULT;
2452 goto end;
2454 memcpy(target_mb->mtext, host_mb->mtext, ret);
2455 unlock_user(target_mtext, target_mtext_addr, ret);
2458 target_mb->mtype = tswapl(host_mb->mtype);
2459 free(host_mb);
2461 end:
2462 if (target_mb)
2463 unlock_user_struct(target_mb, msgp, 1);
2464 return ret;
2467 struct target_shmid_ds
2469 struct target_ipc_perm shm_perm;
2470 abi_ulong shm_segsz;
2471 abi_ulong shm_atime;
2472 #if TARGET_ABI_BITS == 32
2473 abi_ulong __unused1;
2474 #endif
2475 abi_ulong shm_dtime;
2476 #if TARGET_ABI_BITS == 32
2477 abi_ulong __unused2;
2478 #endif
2479 abi_ulong shm_ctime;
2480 #if TARGET_ABI_BITS == 32
2481 abi_ulong __unused3;
2482 #endif
2483 int shm_cpid;
2484 int shm_lpid;
2485 abi_ulong shm_nattch;
2486 unsigned long int __unused4;
2487 unsigned long int __unused5;
2490 static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
2491 abi_ulong target_addr)
2493 struct target_shmid_ds *target_sd;
2495 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2496 return -TARGET_EFAULT;
2497 if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr))
2498 return -TARGET_EFAULT;
2499 __get_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2500 __get_user(host_sd->shm_atime, &target_sd->shm_atime);
2501 __get_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2502 __get_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2503 __get_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2504 __get_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2505 __get_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2506 unlock_user_struct(target_sd, target_addr, 0);
2507 return 0;
2510 static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
2511 struct shmid_ds *host_sd)
2513 struct target_shmid_ds *target_sd;
2515 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2516 return -TARGET_EFAULT;
2517 if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm)))
2518 return -TARGET_EFAULT;
2519 __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2520 __put_user(host_sd->shm_atime, &target_sd->shm_atime);
2521 __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2522 __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2523 __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2524 __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2525 __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2526 unlock_user_struct(target_sd, target_addr, 1);
2527 return 0;
2530 struct target_shminfo {
2531 abi_ulong shmmax;
2532 abi_ulong shmmin;
2533 abi_ulong shmmni;
2534 abi_ulong shmseg;
2535 abi_ulong shmall;
2538 static inline abi_long host_to_target_shminfo(abi_ulong target_addr,
2539 struct shminfo *host_shminfo)
2541 struct target_shminfo *target_shminfo;
2542 if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0))
2543 return -TARGET_EFAULT;
2544 __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
2545 __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
2546 __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
2547 __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
2548 __put_user(host_shminfo->shmall, &target_shminfo->shmall);
2549 unlock_user_struct(target_shminfo, target_addr, 1);
2550 return 0;
2553 struct target_shm_info {
2554 int used_ids;
2555 abi_ulong shm_tot;
2556 abi_ulong shm_rss;
2557 abi_ulong shm_swp;
2558 abi_ulong swap_attempts;
2559 abi_ulong swap_successes;
2562 static inline abi_long host_to_target_shm_info(abi_ulong target_addr,
2563 struct shm_info *host_shm_info)
2565 struct target_shm_info *target_shm_info;
2566 if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0))
2567 return -TARGET_EFAULT;
2568 __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
2569 __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
2570 __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
2571 __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
2572 __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts);
2573 __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes);
2574 unlock_user_struct(target_shm_info, target_addr, 1);
2575 return 0;
2578 static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
2580 struct shmid_ds dsarg;
2581 struct shminfo shminfo;
2582 struct shm_info shm_info;
2583 abi_long ret = -TARGET_EINVAL;
2585 cmd &= 0xff;
2587 switch(cmd) {
2588 case IPC_STAT:
2589 case IPC_SET:
2590 case SHM_STAT:
2591 if (target_to_host_shmid_ds(&dsarg, buf))
2592 return -TARGET_EFAULT;
2593 ret = get_errno(shmctl(shmid, cmd, &dsarg));
2594 if (host_to_target_shmid_ds(buf, &dsarg))
2595 return -TARGET_EFAULT;
2596 break;
2597 case IPC_INFO:
2598 ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
2599 if (host_to_target_shminfo(buf, &shminfo))
2600 return -TARGET_EFAULT;
2601 break;
2602 case SHM_INFO:
2603 ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
2604 if (host_to_target_shm_info(buf, &shm_info))
2605 return -TARGET_EFAULT;
2606 break;
2607 case IPC_RMID:
2608 case SHM_LOCK:
2609 case SHM_UNLOCK:
2610 ret = get_errno(shmctl(shmid, cmd, NULL));
2611 break;
2614 return ret;
2617 static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
2619 abi_long raddr;
2620 void *host_raddr;
2621 struct shmid_ds shm_info;
2622 int i,ret;
2624 /* find out the length of the shared memory segment */
2625 ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
2626 if (is_error(ret)) {
2627 /* can't get length, bail out */
2628 return ret;
2631 mmap_lock();
2633 if (shmaddr)
2634 host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
2635 else {
2636 abi_ulong mmap_start;
2638 mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
2640 if (mmap_start == -1) {
2641 errno = ENOMEM;
2642 host_raddr = (void *)-1;
2643 } else
2644 host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);
2647 if (host_raddr == (void *)-1) {
2648 mmap_unlock();
2649 return get_errno((long)host_raddr);
2651 raddr=h2g((unsigned long)host_raddr);
2653 page_set_flags(raddr, raddr + shm_info.shm_segsz,
2654 PAGE_VALID | PAGE_READ |
2655 ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
2657 for (i = 0; i < N_SHM_REGIONS; i++) {
2658 if (shm_regions[i].start == 0) {
2659 shm_regions[i].start = raddr;
2660 shm_regions[i].size = shm_info.shm_segsz;
2661 break;
2665 mmap_unlock();
2666 return raddr;
2670 static inline abi_long do_shmdt(abi_ulong shmaddr)
2672 int i;
2674 for (i = 0; i < N_SHM_REGIONS; ++i) {
2675 if (shm_regions[i].start == shmaddr) {
2676 shm_regions[i].start = 0;
2677 page_set_flags(shmaddr, shm_regions[i].size, 0);
2678 break;
2682 return get_errno(shmdt(g2h(shmaddr)));
2685 #ifdef TARGET_NR_ipc
2686 /* ??? This only works with linear mappings. */
2687 /* do_ipc() must return target values and target errnos. */
2688 static abi_long do_ipc(unsigned int call, int first,
2689 int second, int third,
2690 abi_long ptr, abi_long fifth)
2692 int version;
2693 abi_long ret = 0;
2695 version = call >> 16;
2696 call &= 0xffff;
2698 switch (call) {
2699 case IPCOP_semop:
2700 ret = do_semop(first, ptr, second);
2701 break;
2703 case IPCOP_semget:
2704 ret = get_errno(semget(first, second, third));
2705 break;
2707 case IPCOP_semctl:
2708 ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr);
2709 break;
2711 case IPCOP_msgget:
2712 ret = get_errno(msgget(first, second));
2713 break;
2715 case IPCOP_msgsnd:
2716 ret = do_msgsnd(first, ptr, second, third);
2717 break;
2719 case IPCOP_msgctl:
2720 ret = do_msgctl(first, second, ptr);
2721 break;
2723 case IPCOP_msgrcv:
2724 switch (version) {
2725 case 0:
2727 struct target_ipc_kludge {
2728 abi_long msgp;
2729 abi_long msgtyp;
2730 } *tmp;
2732 if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
2733 ret = -TARGET_EFAULT;
2734 break;
2737 ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
2739 unlock_user_struct(tmp, ptr, 0);
2740 break;
2742 default:
2743 ret = do_msgrcv(first, ptr, second, fifth, third);
2745 break;
2747 case IPCOP_shmat:
2748 switch (version) {
2749 default:
2751 abi_ulong raddr;
2752 raddr = do_shmat(first, ptr, second);
2753 if (is_error(raddr))
2754 return get_errno(raddr);
2755 if (put_user_ual(raddr, third))
2756 return -TARGET_EFAULT;
2757 break;
2759 case 1:
2760 ret = -TARGET_EINVAL;
2761 break;
2763 break;
2764 case IPCOP_shmdt:
2765 ret = do_shmdt(ptr);
2766 break;
2768 case IPCOP_shmget:
2769 /* IPC_* flag values are the same on all linux platforms */
2770 ret = get_errno(shmget(first, second, third));
2771 break;
2773 /* IPC_* and SHM_* command values are the same on all linux platforms */
2774 case IPCOP_shmctl:
2775 ret = do_shmctl(first, second, third);
2776 break;
2777 default:
2778 gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2779 ret = -TARGET_ENOSYS;
2780 break;
2782 return ret;
2784 #endif
2786 /* kernel structure types definitions */
2787 #define IFNAMSIZ 16
2789 #define STRUCT(name, ...) STRUCT_ ## name,
2790 #define STRUCT_SPECIAL(name) STRUCT_ ## name,
2791 enum {
2792 #include "syscall_types.h"
2794 #undef STRUCT
2795 #undef STRUCT_SPECIAL
2797 #define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = { __VA_ARGS__, TYPE_NULL };
2798 #define STRUCT_SPECIAL(name)
2799 #include "syscall_types.h"
2800 #undef STRUCT
2801 #undef STRUCT_SPECIAL
2803 typedef struct IOCTLEntry {
2804 unsigned int target_cmd;
2805 unsigned int host_cmd;
2806 const char *name;
2807 int access;
2808 const argtype arg_type[5];
2809 } IOCTLEntry;
2811 #define IOC_R 0x0001
2812 #define IOC_W 0x0002
2813 #define IOC_RW (IOC_R | IOC_W)
2815 #define MAX_STRUCT_SIZE 4096
2817 static IOCTLEntry ioctl_entries[] = {
2818 #define IOCTL(cmd, access, ...) \
2819 { TARGET_ ## cmd, cmd, #cmd, access, { __VA_ARGS__ } },
2820 #include "ioctls.h"
2821 { 0, 0, },
2824 /* ??? Implement proper locking for ioctls. */
2825 /* do_ioctl() Must return target values and target errnos. */
2826 static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
2828 const IOCTLEntry *ie;
2829 const argtype *arg_type;
2830 abi_long ret;
2831 uint8_t buf_temp[MAX_STRUCT_SIZE];
2832 int target_size;
2833 void *argptr;
2835 ie = ioctl_entries;
2836 for(;;) {
2837 if (ie->target_cmd == 0) {
2838 gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
2839 return -TARGET_ENOSYS;
2841 if (ie->target_cmd == cmd)
2842 break;
2843 ie++;
2845 arg_type = ie->arg_type;
2846 #if defined(DEBUG)
2847 gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
2848 #endif
2849 switch(arg_type[0]) {
2850 case TYPE_NULL:
2851 /* no argument */
2852 ret = get_errno(ioctl(fd, ie->host_cmd));
2853 break;
2854 case TYPE_PTRVOID:
2855 case TYPE_INT:
2856 /* int argment */
2857 ret = get_errno(ioctl(fd, ie->host_cmd, arg));
2858 break;
2859 case TYPE_PTR:
2860 arg_type++;
2861 target_size = thunk_type_size(arg_type, 0);
2862 switch(ie->access) {
2863 case IOC_R:
2864 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2865 if (!is_error(ret)) {
2866 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2867 if (!argptr)
2868 return -TARGET_EFAULT;
2869 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2870 unlock_user(argptr, arg, target_size);
2872 break;
2873 case IOC_W:
2874 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2875 if (!argptr)
2876 return -TARGET_EFAULT;
2877 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2878 unlock_user(argptr, arg, 0);
2879 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2880 break;
2881 default:
2882 case IOC_RW:
2883 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2884 if (!argptr)
2885 return -TARGET_EFAULT;
2886 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2887 unlock_user(argptr, arg, 0);
2888 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2889 if (!is_error(ret)) {
2890 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2891 if (!argptr)
2892 return -TARGET_EFAULT;
2893 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2894 unlock_user(argptr, arg, target_size);
2896 break;
2898 break;
2899 default:
2900 gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
2901 (long)cmd, arg_type[0]);
2902 ret = -TARGET_ENOSYS;
2903 break;
2905 return ret;
2908 static const bitmask_transtbl iflag_tbl[] = {
2909 { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
2910 { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
2911 { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
2912 { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
2913 { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
2914 { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
2915 { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
2916 { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
2917 { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
2918 { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
2919 { TARGET_IXON, TARGET_IXON, IXON, IXON },
2920 { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
2921 { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
2922 { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
2923 { 0, 0, 0, 0 }
2926 static const bitmask_transtbl oflag_tbl[] = {
2927 { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
2928 { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
2929 { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
2930 { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
2931 { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
2932 { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
2933 { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
2934 { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
2935 { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
2936 { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
2937 { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
2938 { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
2939 { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
2940 { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
2941 { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
2942 { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
2943 { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
2944 { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
2945 { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
2946 { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
2947 { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
2948 { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
2949 { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
2950 { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
2951 { 0, 0, 0, 0 }
2954 static const bitmask_transtbl cflag_tbl[] = {
2955 { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
2956 { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
2957 { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
2958 { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
2959 { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
2960 { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
2961 { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
2962 { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
2963 { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
2964 { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
2965 { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
2966 { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
2967 { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
2968 { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
2969 { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
2970 { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
2971 { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
2972 { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
2973 { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
2974 { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
2975 { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
2976 { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
2977 { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
2978 { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
2979 { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
2980 { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
2981 { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
2982 { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
2983 { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
2984 { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
2985 { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
2986 { 0, 0, 0, 0 }
2989 static const bitmask_transtbl lflag_tbl[] = {
2990 { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
2991 { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
2992 { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
2993 { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
2994 { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
2995 { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
2996 { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
2997 { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
2998 { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
2999 { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
3000 { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
3001 { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
3002 { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
3003 { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
3004 { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
3005 { 0, 0, 0, 0 }
3008 static void target_to_host_termios (void *dst, const void *src)
3010 struct host_termios *host = dst;
3011 const struct target_termios *target = src;
3013 host->c_iflag =
3014 target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
3015 host->c_oflag =
3016 target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
3017 host->c_cflag =
3018 target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
3019 host->c_lflag =
3020 target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
3021 host->c_line = target->c_line;
3023 memset(host->c_cc, 0, sizeof(host->c_cc));
3024 host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
3025 host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
3026 host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
3027 host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
3028 host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
3029 host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
3030 host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
3031 host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
3032 host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
3033 host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
3034 host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
3035 host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
3036 host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
3037 host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
3038 host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
3039 host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
3040 host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
3043 static void host_to_target_termios (void *dst, const void *src)
3045 struct target_termios *target = dst;
3046 const struct host_termios *host = src;
3048 target->c_iflag =
3049 tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
3050 target->c_oflag =
3051 tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
3052 target->c_cflag =
3053 tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
3054 target->c_lflag =
3055 tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
3056 target->c_line = host->c_line;
3058 memset(target->c_cc, 0, sizeof(target->c_cc));
3059 target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
3060 target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
3061 target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
3062 target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
3063 target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
3064 target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
3065 target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
3066 target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
3067 target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
3068 target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
3069 target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
3070 target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
3071 target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
3072 target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
3073 target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
3074 target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
3075 target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
3078 static const StructEntry struct_termios_def = {
3079 .convert = { host_to_target_termios, target_to_host_termios },
3080 .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
3081 .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
3084 static bitmask_transtbl mmap_flags_tbl[] = {
3085 { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
3086 { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
3087 { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
3088 { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
3089 { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
3090 { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
3091 { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
3092 { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
3093 { 0, 0, 0, 0 }
3096 #if defined(TARGET_I386)
3098 /* NOTE: there is really one LDT for all the threads */
3099 static uint8_t *ldt_table;
3101 static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
3103 int size;
3104 void *p;
3106 if (!ldt_table)
3107 return 0;
3108 size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
3109 if (size > bytecount)
3110 size = bytecount;
3111 p = lock_user(VERIFY_WRITE, ptr, size, 0);
3112 if (!p)
3113 return -TARGET_EFAULT;
3114 /* ??? Should this by byteswapped? */
3115 memcpy(p, ldt_table, size);
3116 unlock_user(p, ptr, size);
3117 return size;
3120 /* XXX: add locking support */
3121 static abi_long write_ldt(CPUX86State *env,
3122 abi_ulong ptr, unsigned long bytecount, int oldmode)
3124 struct target_modify_ldt_ldt_s ldt_info;
3125 struct target_modify_ldt_ldt_s *target_ldt_info;
3126 int seg_32bit, contents, read_exec_only, limit_in_pages;
3127 int seg_not_present, useable, lm;
3128 uint32_t *lp, entry_1, entry_2;
3130 if (bytecount != sizeof(ldt_info))
3131 return -TARGET_EINVAL;
3132 if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
3133 return -TARGET_EFAULT;
3134 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3135 ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
3136 ldt_info.limit = tswap32(target_ldt_info->limit);
3137 ldt_info.flags = tswap32(target_ldt_info->flags);
3138 unlock_user_struct(target_ldt_info, ptr, 0);
3140 if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
3141 return -TARGET_EINVAL;
3142 seg_32bit = ldt_info.flags & 1;
3143 contents = (ldt_info.flags >> 1) & 3;
3144 read_exec_only = (ldt_info.flags >> 3) & 1;
3145 limit_in_pages = (ldt_info.flags >> 4) & 1;
3146 seg_not_present = (ldt_info.flags >> 5) & 1;
3147 useable = (ldt_info.flags >> 6) & 1;
3148 #ifdef TARGET_ABI32
3149 lm = 0;
3150 #else
3151 lm = (ldt_info.flags >> 7) & 1;
3152 #endif
3153 if (contents == 3) {
3154 if (oldmode)
3155 return -TARGET_EINVAL;
3156 if (seg_not_present == 0)
3157 return -TARGET_EINVAL;
3159 /* allocate the LDT */
3160 if (!ldt_table) {
3161 env->ldt.base = target_mmap(0,
3162 TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
3163 PROT_READ|PROT_WRITE,
3164 MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
3165 if (env->ldt.base == -1)
3166 return -TARGET_ENOMEM;
3167 memset(g2h(env->ldt.base), 0,
3168 TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
3169 env->ldt.limit = 0xffff;
3170 ldt_table = g2h(env->ldt.base);
3173 /* NOTE: same code as Linux kernel */
3174 /* Allow LDTs to be cleared by the user. */
3175 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3176 if (oldmode ||
3177 (contents == 0 &&
3178 read_exec_only == 1 &&
3179 seg_32bit == 0 &&
3180 limit_in_pages == 0 &&
3181 seg_not_present == 1 &&
3182 useable == 0 )) {
3183 entry_1 = 0;
3184 entry_2 = 0;
3185 goto install;
3189 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
3190 (ldt_info.limit & 0x0ffff);
3191 entry_2 = (ldt_info.base_addr & 0xff000000) |
3192 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3193 (ldt_info.limit & 0xf0000) |
3194 ((read_exec_only ^ 1) << 9) |
3195 (contents << 10) |
3196 ((seg_not_present ^ 1) << 15) |
3197 (seg_32bit << 22) |
3198 (limit_in_pages << 23) |
3199 (lm << 21) |
3200 0x7000;
3201 if (!oldmode)
3202 entry_2 |= (useable << 20);
3204 /* Install the new entry ... */
3205 install:
3206 lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
3207 lp[0] = tswap32(entry_1);
3208 lp[1] = tswap32(entry_2);
3209 return 0;
3212 /* specific and weird i386 syscalls */
3213 static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
3214 unsigned long bytecount)
3216 abi_long ret;
3218 switch (func) {
3219 case 0:
3220 ret = read_ldt(ptr, bytecount);
3221 break;
3222 case 1:
3223 ret = write_ldt(env, ptr, bytecount, 1);
3224 break;
3225 case 0x11:
3226 ret = write_ldt(env, ptr, bytecount, 0);
3227 break;
3228 default:
3229 ret = -TARGET_ENOSYS;
3230 break;
3232 return ret;
3235 #if defined(TARGET_I386) && defined(TARGET_ABI32)
3236 static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
3238 uint64_t *gdt_table = g2h(env->gdt.base);
3239 struct target_modify_ldt_ldt_s ldt_info;
3240 struct target_modify_ldt_ldt_s *target_ldt_info;
3241 int seg_32bit, contents, read_exec_only, limit_in_pages;
3242 int seg_not_present, useable, lm;
3243 uint32_t *lp, entry_1, entry_2;
3244 int i;
3246 lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3247 if (!target_ldt_info)
3248 return -TARGET_EFAULT;
3249 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3250 ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
3251 ldt_info.limit = tswap32(target_ldt_info->limit);
3252 ldt_info.flags = tswap32(target_ldt_info->flags);
3253 if (ldt_info.entry_number == -1) {
3254 for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
3255 if (gdt_table[i] == 0) {
3256 ldt_info.entry_number = i;
3257 target_ldt_info->entry_number = tswap32(i);
3258 break;
3262 unlock_user_struct(target_ldt_info, ptr, 1);
3264 if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN ||
3265 ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
3266 return -TARGET_EINVAL;
3267 seg_32bit = ldt_info.flags & 1;
3268 contents = (ldt_info.flags >> 1) & 3;
3269 read_exec_only = (ldt_info.flags >> 3) & 1;
3270 limit_in_pages = (ldt_info.flags >> 4) & 1;
3271 seg_not_present = (ldt_info.flags >> 5) & 1;
3272 useable = (ldt_info.flags >> 6) & 1;
3273 #ifdef TARGET_ABI32
3274 lm = 0;
3275 #else
3276 lm = (ldt_info.flags >> 7) & 1;
3277 #endif
3279 if (contents == 3) {
3280 if (seg_not_present == 0)
3281 return -TARGET_EINVAL;
3284 /* NOTE: same code as Linux kernel */
3285 /* Allow LDTs to be cleared by the user. */
3286 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3287 if ((contents == 0 &&
3288 read_exec_only == 1 &&
3289 seg_32bit == 0 &&
3290 limit_in_pages == 0 &&
3291 seg_not_present == 1 &&
3292 useable == 0 )) {
3293 entry_1 = 0;
3294 entry_2 = 0;
3295 goto install;
3299 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
3300 (ldt_info.limit & 0x0ffff);
3301 entry_2 = (ldt_info.base_addr & 0xff000000) |
3302 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3303 (ldt_info.limit & 0xf0000) |
3304 ((read_exec_only ^ 1) << 9) |
3305 (contents << 10) |
3306 ((seg_not_present ^ 1) << 15) |
3307 (seg_32bit << 22) |
3308 (limit_in_pages << 23) |
3309 (useable << 20) |
3310 (lm << 21) |
3311 0x7000;
3313 /* Install the new entry ... */
3314 install:
3315 lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
3316 lp[0] = tswap32(entry_1);
3317 lp[1] = tswap32(entry_2);
3318 return 0;
3321 static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
3323 struct target_modify_ldt_ldt_s *target_ldt_info;
3324 uint64_t *gdt_table = g2h(env->gdt.base);
3325 uint32_t base_addr, limit, flags;
3326 int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
3327 int seg_not_present, useable, lm;
3328 uint32_t *lp, entry_1, entry_2;
3330 lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3331 if (!target_ldt_info)
3332 return -TARGET_EFAULT;
3333 idx = tswap32(target_ldt_info->entry_number);
3334 if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
3335 idx > TARGET_GDT_ENTRY_TLS_MAX) {
3336 unlock_user_struct(target_ldt_info, ptr, 1);
3337 return -TARGET_EINVAL;
3339 lp = (uint32_t *)(gdt_table + idx);
3340 entry_1 = tswap32(lp[0]);
3341 entry_2 = tswap32(lp[1]);
3343 read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
3344 contents = (entry_2 >> 10) & 3;
3345 seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
3346 seg_32bit = (entry_2 >> 22) & 1;
3347 limit_in_pages = (entry_2 >> 23) & 1;
3348 useable = (entry_2 >> 20) & 1;
3349 #ifdef TARGET_ABI32
3350 lm = 0;
3351 #else
3352 lm = (entry_2 >> 21) & 1;
3353 #endif
3354 flags = (seg_32bit << 0) | (contents << 1) |
3355 (read_exec_only << 3) | (limit_in_pages << 4) |
3356 (seg_not_present << 5) | (useable << 6) | (lm << 7);
3357 limit = (entry_1 & 0xffff) | (entry_2 & 0xf0000);
3358 base_addr = (entry_1 >> 16) |
3359 (entry_2 & 0xff000000) |
3360 ((entry_2 & 0xff) << 16);
3361 target_ldt_info->base_addr = tswapl(base_addr);
3362 target_ldt_info->limit = tswap32(limit);
3363 target_ldt_info->flags = tswap32(flags);
3364 unlock_user_struct(target_ldt_info, ptr, 1);
3365 return 0;
3367 #endif /* TARGET_I386 && TARGET_ABI32 */
3369 #ifndef TARGET_ABI32
3370 static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
3372 abi_long ret;
3373 abi_ulong val;
3374 int idx;
3376 switch(code) {
3377 case TARGET_ARCH_SET_GS:
3378 case TARGET_ARCH_SET_FS:
3379 if (code == TARGET_ARCH_SET_GS)
3380 idx = R_GS;
3381 else
3382 idx = R_FS;
3383 cpu_x86_load_seg(env, idx, 0);
3384 env->segs[idx].base = addr;
3385 break;
3386 case TARGET_ARCH_GET_GS:
3387 case TARGET_ARCH_GET_FS:
3388 if (code == TARGET_ARCH_GET_GS)
3389 idx = R_GS;
3390 else
3391 idx = R_FS;
3392 val = env->segs[idx].base;
3393 if (put_user(val, addr, abi_ulong))
3394 return -TARGET_EFAULT;
3395 break;
3396 default:
3397 ret = -TARGET_EINVAL;
3398 break;
3400 return 0;
3402 #endif
3404 #endif /* defined(TARGET_I386) */
3406 #if defined(USE_NPTL)
3408 #define NEW_STACK_SIZE PTHREAD_STACK_MIN
3410 static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
3411 typedef struct {
3412 CPUState *env;
3413 pthread_mutex_t mutex;
3414 pthread_cond_t cond;
3415 pthread_t thread;
3416 uint32_t tid;
3417 abi_ulong child_tidptr;
3418 abi_ulong parent_tidptr;
3419 sigset_t sigmask;
3420 } new_thread_info;
3422 static void *clone_func(void *arg)
3424 new_thread_info *info = arg;
3425 CPUState *env;
3426 TaskState *ts;
3428 env = info->env;
3429 thread_env = env;
3430 ts = (TaskState *)thread_env->opaque;
3431 info->tid = gettid();
3432 env->host_tid = info->tid;
3433 task_settid(ts);
3434 if (info->child_tidptr)
3435 put_user_u32(info->tid, info->child_tidptr);
3436 if (info->parent_tidptr)
3437 put_user_u32(info->tid, info->parent_tidptr);
3438 /* Enable signals. */
3439 sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
3440 /* Signal to the parent that we're ready. */
3441 pthread_mutex_lock(&info->mutex);
3442 pthread_cond_broadcast(&info->cond);
3443 pthread_mutex_unlock(&info->mutex);
3444 /* Wait until the parent has finshed initializing the tls state. */
3445 pthread_mutex_lock(&clone_lock);
3446 pthread_mutex_unlock(&clone_lock);
3447 cpu_loop(env);
3448 /* never exits */
3449 return NULL;
3451 #else
3452 /* this stack is the equivalent of the kernel stack associated with a
3453 thread/process */
3454 #define NEW_STACK_SIZE 8192
3456 static int clone_func(void *arg)
3458 CPUState *env = arg;
3459 cpu_loop(env);
3460 /* never exits */
3461 return 0;
3463 #endif
3465 /* do_fork() Must return host values and target errnos (unlike most
3466 do_*() functions). */
3467 static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
3468 abi_ulong parent_tidptr, target_ulong newtls,
3469 abi_ulong child_tidptr)
3471 int ret;
3472 TaskState *ts;
3473 uint8_t *new_stack;
3474 CPUState *new_env;
3475 #if defined(USE_NPTL)
3476 unsigned int nptl_flags;
3477 sigset_t sigmask;
3478 #endif
3480 /* Emulate vfork() with fork() */
3481 if (flags & CLONE_VFORK)
3482 flags &= ~(CLONE_VFORK | CLONE_VM);
3484 if (flags & CLONE_VM) {
3485 TaskState *parent_ts = (TaskState *)env->opaque;
3486 #if defined(USE_NPTL)
3487 new_thread_info info;
3488 pthread_attr_t attr;
3489 #endif
3490 ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
3491 init_task_state(ts);
3492 new_stack = ts->stack;
3493 /* we create a new CPU instance. */
3494 new_env = cpu_copy(env);
3495 /* Init regs that differ from the parent. */
3496 cpu_clone_regs(new_env, newsp);
3497 new_env->opaque = ts;
3498 ts->bprm = parent_ts->bprm;
3499 ts->info = parent_ts->info;
3500 #if defined(USE_NPTL)
3501 nptl_flags = flags;
3502 flags &= ~CLONE_NPTL_FLAGS2;
3504 if (nptl_flags & CLONE_CHILD_CLEARTID) {
3505 ts->child_tidptr = child_tidptr;
3508 if (nptl_flags & CLONE_SETTLS)
3509 cpu_set_tls (new_env, newtls);
3511 /* Grab a mutex so that thread setup appears atomic. */
3512 pthread_mutex_lock(&clone_lock);
3514 memset(&info, 0, sizeof(info));
3515 pthread_mutex_init(&info.mutex, NULL);
3516 pthread_mutex_lock(&info.mutex);
3517 pthread_cond_init(&info.cond, NULL);
3518 info.env = new_env;
3519 if (nptl_flags & CLONE_CHILD_SETTID)
3520 info.child_tidptr = child_tidptr;
3521 if (nptl_flags & CLONE_PARENT_SETTID)
3522 info.parent_tidptr = parent_tidptr;
3524 ret = pthread_attr_init(&attr);
3525 ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE);
3526 /* It is not safe to deliver signals until the child has finished
3527 initializing, so temporarily block all signals. */
3528 sigfillset(&sigmask);
3529 sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
3531 ret = pthread_create(&info.thread, &attr, clone_func, &info);
3532 /* TODO: Free new CPU state if thread creation failed. */
3534 sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
3535 pthread_attr_destroy(&attr);
3536 if (ret == 0) {
3537 /* Wait for the child to initialize. */
3538 pthread_cond_wait(&info.cond, &info.mutex);
3539 ret = info.tid;
3540 if (flags & CLONE_PARENT_SETTID)
3541 put_user_u32(ret, parent_tidptr);
3542 } else {
3543 ret = -1;
3545 pthread_mutex_unlock(&info.mutex);
3546 pthread_cond_destroy(&info.cond);
3547 pthread_mutex_destroy(&info.mutex);
3548 pthread_mutex_unlock(&clone_lock);
3549 #else
3550 if (flags & CLONE_NPTL_FLAGS2)
3551 return -EINVAL;
3552 /* This is probably going to die very quickly, but do it anyway. */
3553 #ifdef __ia64__
3554 ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
3555 #else
3556 ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
3557 #endif
3558 #endif
3559 } else {
3560 /* if no CLONE_VM, we consider it is a fork */
3561 if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
3562 return -EINVAL;
3563 fork_start();
3564 ret = fork();
3565 if (ret == 0) {
3566 /* Child Process. */
3567 cpu_clone_regs(env, newsp);
3568 fork_end(1);
3569 #if defined(USE_NPTL)
3570 /* There is a race condition here. The parent process could
3571 theoretically read the TID in the child process before the child
3572 tid is set. This would require using either ptrace
3573 (not implemented) or having *_tidptr to point at a shared memory
3574 mapping. We can't repeat the spinlock hack used above because
3575 the child process gets its own copy of the lock. */
3576 if (flags & CLONE_CHILD_SETTID)
3577 put_user_u32(gettid(), child_tidptr);
3578 if (flags & CLONE_PARENT_SETTID)
3579 put_user_u32(gettid(), parent_tidptr);
3580 ts = (TaskState *)env->opaque;
3581 if (flags & CLONE_SETTLS)
3582 cpu_set_tls (env, newtls);
3583 if (flags & CLONE_CHILD_CLEARTID)
3584 ts->child_tidptr = child_tidptr;
3585 #endif
3586 } else {
3587 fork_end(0);
3590 return ret;
3593 static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
3595 struct flock fl;
3596 struct target_flock *target_fl;
3597 struct flock64 fl64;
3598 struct target_flock64 *target_fl64;
3599 abi_long ret;
3601 switch(cmd) {
3602 case TARGET_F_GETLK:
3603 if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3604 return -TARGET_EFAULT;
3605 fl.l_type = tswap16(target_fl->l_type);
3606 fl.l_whence = tswap16(target_fl->l_whence);
3607 fl.l_start = tswapl(target_fl->l_start);
3608 fl.l_len = tswapl(target_fl->l_len);
3609 fl.l_pid = tswapl(target_fl->l_pid);
3610 unlock_user_struct(target_fl, arg, 0);
3611 ret = get_errno(fcntl(fd, cmd, &fl));
3612 if (ret == 0) {
3613 if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
3614 return -TARGET_EFAULT;
3615 target_fl->l_type = tswap16(fl.l_type);
3616 target_fl->l_whence = tswap16(fl.l_whence);
3617 target_fl->l_start = tswapl(fl.l_start);
3618 target_fl->l_len = tswapl(fl.l_len);
3619 target_fl->l_pid = tswapl(fl.l_pid);
3620 unlock_user_struct(target_fl, arg, 1);
3622 break;
3624 case TARGET_F_SETLK:
3625 case TARGET_F_SETLKW:
3626 if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3627 return -TARGET_EFAULT;
3628 fl.l_type = tswap16(target_fl->l_type);
3629 fl.l_whence = tswap16(target_fl->l_whence);
3630 fl.l_start = tswapl(target_fl->l_start);
3631 fl.l_len = tswapl(target_fl->l_len);
3632 fl.l_pid = tswapl(target_fl->l_pid);
3633 unlock_user_struct(target_fl, arg, 0);
3634 ret = get_errno(fcntl(fd, cmd, &fl));
3635 break;
3637 case TARGET_F_GETLK64:
3638 if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3639 return -TARGET_EFAULT;
3640 fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3641 fl64.l_whence = tswap16(target_fl64->l_whence);
3642 fl64.l_start = tswapl(target_fl64->l_start);
3643 fl64.l_len = tswapl(target_fl64->l_len);
3644 fl64.l_pid = tswap16(target_fl64->l_pid);
3645 unlock_user_struct(target_fl64, arg, 0);
3646 ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
3647 if (ret == 0) {
3648 if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
3649 return -TARGET_EFAULT;
3650 target_fl64->l_type = tswap16(fl64.l_type) >> 1;
3651 target_fl64->l_whence = tswap16(fl64.l_whence);
3652 target_fl64->l_start = tswapl(fl64.l_start);
3653 target_fl64->l_len = tswapl(fl64.l_len);
3654 target_fl64->l_pid = tswapl(fl64.l_pid);
3655 unlock_user_struct(target_fl64, arg, 1);
3657 break;
3658 case TARGET_F_SETLK64:
3659 case TARGET_F_SETLKW64:
3660 if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3661 return -TARGET_EFAULT;
3662 fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3663 fl64.l_whence = tswap16(target_fl64->l_whence);
3664 fl64.l_start = tswapl(target_fl64->l_start);
3665 fl64.l_len = tswapl(target_fl64->l_len);
3666 fl64.l_pid = tswap16(target_fl64->l_pid);
3667 unlock_user_struct(target_fl64, arg, 0);
3668 ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
3669 break;
3671 case F_GETFL:
3672 ret = get_errno(fcntl(fd, cmd, arg));
3673 if (ret >= 0) {
3674 ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
3676 break;
3678 case F_SETFL:
3679 ret = get_errno(fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
3680 break;
3682 default:
3683 ret = get_errno(fcntl(fd, cmd, arg));
3684 break;
3686 return ret;
3689 #ifdef USE_UID16
3691 static inline int high2lowuid(int uid)
3693 if (uid > 65535)
3694 return 65534;
3695 else
3696 return uid;
3699 static inline int high2lowgid(int gid)
3701 if (gid > 65535)
3702 return 65534;
3703 else
3704 return gid;
3707 static inline int low2highuid(int uid)
3709 if ((int16_t)uid == -1)
3710 return -1;
3711 else
3712 return uid;
3715 static inline int low2highgid(int gid)
3717 if ((int16_t)gid == -1)
3718 return -1;
3719 else
3720 return gid;
3723 #endif /* USE_UID16 */
3725 void syscall_init(void)
3727 IOCTLEntry *ie;
3728 const argtype *arg_type;
3729 int size;
3730 int i;
3732 #define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3733 #define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3734 #include "syscall_types.h"
3735 #undef STRUCT
3736 #undef STRUCT_SPECIAL
3738 /* we patch the ioctl size if necessary. We rely on the fact that
3739 no ioctl has all the bits at '1' in the size field */
3740 ie = ioctl_entries;
3741 while (ie->target_cmd != 0) {
3742 if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
3743 TARGET_IOC_SIZEMASK) {
3744 arg_type = ie->arg_type;
3745 if (arg_type[0] != TYPE_PTR) {
3746 fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
3747 ie->target_cmd);
3748 exit(1);
3750 arg_type++;
3751 size = thunk_type_size(arg_type, 0);
3752 ie->target_cmd = (ie->target_cmd &
3753 ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
3754 (size << TARGET_IOC_SIZESHIFT);
3757 /* Build target_to_host_errno_table[] table from
3758 * host_to_target_errno_table[]. */
3759 for (i=0; i < ERRNO_TABLE_SIZE; i++)
3760 target_to_host_errno_table[host_to_target_errno_table[i]] = i;
3762 /* automatic consistency check if same arch */
3763 #if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
3764 (defined(__x86_64__) && defined(TARGET_X86_64))
3765 if (unlikely(ie->target_cmd != ie->host_cmd)) {
3766 fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
3767 ie->name, ie->target_cmd, ie->host_cmd);
3769 #endif
3770 ie++;
3774 #if TARGET_ABI_BITS == 32
3775 static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
3777 #ifdef TARGET_WORDS_BIGENDIAN
3778 return ((uint64_t)word0 << 32) | word1;
3779 #else
3780 return ((uint64_t)word1 << 32) | word0;
3781 #endif
3783 #else /* TARGET_ABI_BITS == 32 */
3784 static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
3786 return word0;
3788 #endif /* TARGET_ABI_BITS != 32 */
3790 #ifdef TARGET_NR_truncate64
3791 static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
3792 abi_long arg2,
3793 abi_long arg3,
3794 abi_long arg4)
3796 #ifdef TARGET_ARM
3797 if (((CPUARMState *)cpu_env)->eabi)
3799 arg2 = arg3;
3800 arg3 = arg4;
3802 #endif
3803 return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
3805 #endif
3807 #ifdef TARGET_NR_ftruncate64
3808 static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
3809 abi_long arg2,
3810 abi_long arg3,
3811 abi_long arg4)
3813 #ifdef TARGET_ARM
3814 if (((CPUARMState *)cpu_env)->eabi)
3816 arg2 = arg3;
3817 arg3 = arg4;
3819 #endif
3820 return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
3822 #endif
3824 static inline abi_long target_to_host_timespec(struct timespec *host_ts,
3825 abi_ulong target_addr)
3827 struct target_timespec *target_ts;
3829 if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
3830 return -TARGET_EFAULT;
3831 host_ts->tv_sec = tswapl(target_ts->tv_sec);
3832 host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
3833 unlock_user_struct(target_ts, target_addr, 0);
3834 return 0;
3837 static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3838 struct timespec *host_ts)
3840 struct target_timespec *target_ts;
3842 if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
3843 return -TARGET_EFAULT;
3844 target_ts->tv_sec = tswapl(host_ts->tv_sec);
3845 target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
3846 unlock_user_struct(target_ts, target_addr, 1);
3847 return 0;
3850 #if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
3851 static inline abi_long host_to_target_stat64(void *cpu_env,
3852 abi_ulong target_addr,
3853 struct stat *host_st)
3855 #ifdef TARGET_ARM
3856 if (((CPUARMState *)cpu_env)->eabi) {
3857 struct target_eabi_stat64 *target_st;
3859 if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3860 return -TARGET_EFAULT;
3861 memset(target_st, 0, sizeof(struct target_eabi_stat64));
3862 __put_user(host_st->st_dev, &target_st->st_dev);
3863 __put_user(host_st->st_ino, &target_st->st_ino);
3864 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3865 __put_user(host_st->st_ino, &target_st->__st_ino);
3866 #endif
3867 __put_user(host_st->st_mode, &target_st->st_mode);
3868 __put_user(host_st->st_nlink, &target_st->st_nlink);
3869 __put_user(host_st->st_uid, &target_st->st_uid);
3870 __put_user(host_st->st_gid, &target_st->st_gid);
3871 __put_user(host_st->st_rdev, &target_st->st_rdev);
3872 __put_user(host_st->st_size, &target_st->st_size);
3873 __put_user(host_st->st_blksize, &target_st->st_blksize);
3874 __put_user(host_st->st_blocks, &target_st->st_blocks);
3875 __put_user(host_st->st_atime, &target_st->target_st_atime);
3876 __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3877 __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3878 unlock_user_struct(target_st, target_addr, 1);
3879 } else
3880 #endif
3882 #if TARGET_LONG_BITS == 64
3883 struct target_stat *target_st;
3884 #else
3885 struct target_stat64 *target_st;
3886 #endif
3888 if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3889 return -TARGET_EFAULT;
3890 memset(target_st, 0, sizeof(*target_st));
3891 __put_user(host_st->st_dev, &target_st->st_dev);
3892 __put_user(host_st->st_ino, &target_st->st_ino);
3893 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3894 __put_user(host_st->st_ino, &target_st->__st_ino);
3895 #endif
3896 __put_user(host_st->st_mode, &target_st->st_mode);
3897 __put_user(host_st->st_nlink, &target_st->st_nlink);
3898 __put_user(host_st->st_uid, &target_st->st_uid);
3899 __put_user(host_st->st_gid, &target_st->st_gid);
3900 __put_user(host_st->st_rdev, &target_st->st_rdev);
3901 /* XXX: better use of kernel struct */
3902 __put_user(host_st->st_size, &target_st->st_size);
3903 __put_user(host_st->st_blksize, &target_st->st_blksize);
3904 __put_user(host_st->st_blocks, &target_st->st_blocks);
3905 __put_user(host_st->st_atime, &target_st->target_st_atime);
3906 __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3907 __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3908 unlock_user_struct(target_st, target_addr, 1);
3911 return 0;
3913 #endif
3915 #if defined(USE_NPTL)
3916 /* ??? Using host futex calls even when target atomic operations
3917 are not really atomic probably breaks things. However implementing
3918 futexes locally would make futexes shared between multiple processes
3919 tricky. However they're probably useless because guest atomic
3920 operations won't work either. */
3921 static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
3922 target_ulong uaddr2, int val3)
3924 struct timespec ts, *pts;
3926 /* ??? We assume FUTEX_* constants are the same on both host
3927 and target. */
3928 switch (op) {
3929 case FUTEX_WAIT:
3930 if (timeout) {
3931 pts = &ts;
3932 target_to_host_timespec(pts, timeout);
3933 } else {
3934 pts = NULL;
3936 return get_errno(sys_futex(g2h(uaddr), FUTEX_WAIT, tswap32(val),
3937 pts, NULL, 0));
3938 case FUTEX_WAKE:
3939 return get_errno(sys_futex(g2h(uaddr), FUTEX_WAKE, val, NULL, NULL, 0));
3940 case FUTEX_FD:
3941 return get_errno(sys_futex(g2h(uaddr), FUTEX_FD, val, NULL, NULL, 0));
3942 case FUTEX_REQUEUE:
3943 return get_errno(sys_futex(g2h(uaddr), FUTEX_REQUEUE, val,
3944 NULL, g2h(uaddr2), 0));
3945 case FUTEX_CMP_REQUEUE:
3946 return get_errno(sys_futex(g2h(uaddr), FUTEX_CMP_REQUEUE, val,
3947 NULL, g2h(uaddr2), tswap32(val3)));
3948 default:
3949 return -TARGET_ENOSYS;
3952 #endif
3954 /* Map host to target signal numbers for the wait family of syscalls.
3955 Assume all other status bits are the same. */
3956 static int host_to_target_waitstatus(int status)
3958 if (WIFSIGNALED(status)) {
3959 return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f);
3961 if (WIFSTOPPED(status)) {
3962 return (host_to_target_signal(WSTOPSIG(status)) << 8)
3963 | (status & 0xff);
3965 return status;
3968 int get_osversion(void)
3970 static int osversion;
3971 struct new_utsname buf;
3972 const char *s;
3973 int i, n, tmp;
3974 if (osversion)
3975 return osversion;
3976 if (qemu_uname_release && *qemu_uname_release) {
3977 s = qemu_uname_release;
3978 } else {
3979 if (sys_uname(&buf))
3980 return 0;
3981 s = buf.release;
3983 tmp = 0;
3984 for (i = 0; i < 3; i++) {
3985 n = 0;
3986 while (*s >= '0' && *s <= '9') {
3987 n *= 10;
3988 n += *s - '0';
3989 s++;
3991 tmp = (tmp << 8) + n;
3992 if (*s == '.')
3993 s++;
3995 osversion = tmp;
3996 return osversion;
3999 /* do_syscall() should always have a single exit point at the end so
4000 that actions, such as logging of syscall results, can be performed.
4001 All errnos that do_syscall() returns must be -TARGET_<errcode>. */
4002 abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4003 abi_long arg2, abi_long arg3, abi_long arg4,
4004 abi_long arg5, abi_long arg6)
4006 abi_long ret;
4007 struct stat st;
4008 struct statfs stfs;
4009 void *p;
4011 #ifdef DEBUG
4012 gemu_log("syscall %d", num);
4013 #endif
4014 if(do_strace)
4015 print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
4017 switch(num) {
4018 case TARGET_NR_exit:
4019 #ifdef USE_NPTL
4020 /* In old applications this may be used to implement _exit(2).
4021 However in threaded applictions it is used for thread termination,
4022 and _exit_group is used for application termination.
4023 Do thread termination if we have more then one thread. */
4024 /* FIXME: This probably breaks if a signal arrives. We should probably
4025 be disabling signals. */
4026 if (first_cpu->next_cpu) {
4027 TaskState *ts;
4028 CPUState **lastp;
4029 CPUState *p;
4031 cpu_list_lock();
4032 lastp = &first_cpu;
4033 p = first_cpu;
4034 while (p && p != (CPUState *)cpu_env) {
4035 lastp = &p->next_cpu;
4036 p = p->next_cpu;
4038 /* If we didn't find the CPU for this thread then something is
4039 horribly wrong. */
4040 if (!p)
4041 abort();
4042 /* Remove the CPU from the list. */
4043 *lastp = p->next_cpu;
4044 cpu_list_unlock();
4045 ts = ((CPUState *)cpu_env)->opaque;
4046 if (ts->child_tidptr) {
4047 put_user_u32(0, ts->child_tidptr);
4048 sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
4049 NULL, NULL, 0);
4051 /* TODO: Free CPU state. */
4052 pthread_exit(NULL);
4054 #endif
4055 #ifdef HAVE_GPROF
4056 _mcleanup();
4057 #endif
4058 gdb_exit(cpu_env, arg1);
4059 _exit(arg1);
4060 ret = 0; /* avoid warning */
4061 break;
4062 case TARGET_NR_read:
4063 if (arg3 == 0)
4064 ret = 0;
4065 else {
4066 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
4067 goto efault;
4068 ret = get_errno(read(arg1, p, arg3));
4069 unlock_user(p, arg2, ret);
4071 break;
4072 case TARGET_NR_write:
4073 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
4074 goto efault;
4075 ret = get_errno(write(arg1, p, arg3));
4076 unlock_user(p, arg2, 0);
4077 break;
4078 case TARGET_NR_open:
4079 if (!(p = lock_user_string(arg1)))
4080 goto efault;
4081 ret = get_errno(open(path(p),
4082 target_to_host_bitmask(arg2, fcntl_flags_tbl),
4083 arg3));
4084 unlock_user(p, arg1, 0);
4085 break;
4086 #if defined(TARGET_NR_openat) && defined(__NR_openat)
4087 case TARGET_NR_openat:
4088 if (!(p = lock_user_string(arg2)))
4089 goto efault;
4090 ret = get_errno(sys_openat(arg1,
4091 path(p),
4092 target_to_host_bitmask(arg3, fcntl_flags_tbl),
4093 arg4));
4094 unlock_user(p, arg2, 0);
4095 break;
4096 #endif
4097 case TARGET_NR_close:
4098 ret = get_errno(close(arg1));
4099 break;
4100 case TARGET_NR_brk:
4101 ret = do_brk(arg1);
4102 break;
4103 case TARGET_NR_fork:
4104 ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
4105 break;
4106 #ifdef TARGET_NR_waitpid
4107 case TARGET_NR_waitpid:
4109 int status;
4110 ret = get_errno(waitpid(arg1, &status, arg3));
4111 if (!is_error(ret) && arg2
4112 && put_user_s32(host_to_target_waitstatus(status), arg2))
4113 goto efault;
4115 break;
4116 #endif
4117 #ifdef TARGET_NR_waitid
4118 case TARGET_NR_waitid:
4120 siginfo_t info;
4121 info.si_pid = 0;
4122 ret = get_errno(waitid(arg1, arg2, &info, arg4));
4123 if (!is_error(ret) && arg3 && info.si_pid != 0) {
4124 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
4125 goto efault;
4126 host_to_target_siginfo(p, &info);
4127 unlock_user(p, arg3, sizeof(target_siginfo_t));
4130 break;
4131 #endif
4132 #ifdef TARGET_NR_creat /* not on alpha */
4133 case TARGET_NR_creat:
4134 if (!(p = lock_user_string(arg1)))
4135 goto efault;
4136 ret = get_errno(creat(p, arg2));
4137 unlock_user(p, arg1, 0);
4138 break;
4139 #endif
4140 case TARGET_NR_link:
4142 void * p2;
4143 p = lock_user_string(arg1);
4144 p2 = lock_user_string(arg2);
4145 if (!p || !p2)
4146 ret = -TARGET_EFAULT;
4147 else
4148 ret = get_errno(link(p, p2));
4149 unlock_user(p2, arg2, 0);
4150 unlock_user(p, arg1, 0);
4152 break;
4153 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
4154 case TARGET_NR_linkat:
4156 void * p2 = NULL;
4157 if (!arg2 || !arg4)
4158 goto efault;
4159 p = lock_user_string(arg2);
4160 p2 = lock_user_string(arg4);
4161 if (!p || !p2)
4162 ret = -TARGET_EFAULT;
4163 else
4164 ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
4165 unlock_user(p, arg2, 0);
4166 unlock_user(p2, arg4, 0);
4168 break;
4169 #endif
4170 case TARGET_NR_unlink:
4171 if (!(p = lock_user_string(arg1)))
4172 goto efault;
4173 ret = get_errno(unlink(p));
4174 unlock_user(p, arg1, 0);
4175 break;
4176 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
4177 case TARGET_NR_unlinkat:
4178 if (!(p = lock_user_string(arg2)))
4179 goto efault;
4180 ret = get_errno(sys_unlinkat(arg1, p, arg3));
4181 unlock_user(p, arg2, 0);
4182 break;
4183 #endif
4184 case TARGET_NR_execve:
4186 char **argp, **envp;
4187 int argc, envc;
4188 abi_ulong gp;
4189 abi_ulong guest_argp;
4190 abi_ulong guest_envp;
4191 abi_ulong addr;
4192 char **q;
4194 argc = 0;
4195 guest_argp = arg2;
4196 for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
4197 if (get_user_ual(addr, gp))
4198 goto efault;
4199 if (!addr)
4200 break;
4201 argc++;
4203 envc = 0;
4204 guest_envp = arg3;
4205 for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
4206 if (get_user_ual(addr, gp))
4207 goto efault;
4208 if (!addr)
4209 break;
4210 envc++;
4213 argp = alloca((argc + 1) * sizeof(void *));
4214 envp = alloca((envc + 1) * sizeof(void *));
4216 for (gp = guest_argp, q = argp; gp;
4217 gp += sizeof(abi_ulong), q++) {
4218 if (get_user_ual(addr, gp))
4219 goto execve_efault;
4220 if (!addr)
4221 break;
4222 if (!(*q = lock_user_string(addr)))
4223 goto execve_efault;
4225 *q = NULL;
4227 for (gp = guest_envp, q = envp; gp;
4228 gp += sizeof(abi_ulong), q++) {
4229 if (get_user_ual(addr, gp))
4230 goto execve_efault;
4231 if (!addr)
4232 break;
4233 if (!(*q = lock_user_string(addr)))
4234 goto execve_efault;
4236 *q = NULL;
4238 if (!(p = lock_user_string(arg1)))
4239 goto execve_efault;
4240 ret = get_errno(execve(p, argp, envp));
4241 unlock_user(p, arg1, 0);
4243 goto execve_end;
4245 execve_efault:
4246 ret = -TARGET_EFAULT;
4248 execve_end:
4249 for (gp = guest_argp, q = argp; *q;
4250 gp += sizeof(abi_ulong), q++) {
4251 if (get_user_ual(addr, gp)
4252 || !addr)
4253 break;
4254 unlock_user(*q, addr, 0);
4256 for (gp = guest_envp, q = envp; *q;
4257 gp += sizeof(abi_ulong), q++) {
4258 if (get_user_ual(addr, gp)
4259 || !addr)
4260 break;
4261 unlock_user(*q, addr, 0);
4264 break;
4265 case TARGET_NR_chdir:
4266 if (!(p = lock_user_string(arg1)))
4267 goto efault;
4268 ret = get_errno(chdir(p));
4269 unlock_user(p, arg1, 0);
4270 break;
4271 #ifdef TARGET_NR_time
4272 case TARGET_NR_time:
4274 time_t host_time;
4275 ret = get_errno(time(&host_time));
4276 if (!is_error(ret)
4277 && arg1
4278 && put_user_sal(host_time, arg1))
4279 goto efault;
4281 break;
4282 #endif
4283 case TARGET_NR_mknod:
4284 if (!(p = lock_user_string(arg1)))
4285 goto efault;
4286 ret = get_errno(mknod(p, arg2, arg3));
4287 unlock_user(p, arg1, 0);
4288 break;
4289 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
4290 case TARGET_NR_mknodat:
4291 if (!(p = lock_user_string(arg2)))
4292 goto efault;
4293 ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
4294 unlock_user(p, arg2, 0);
4295 break;
4296 #endif
4297 case TARGET_NR_chmod:
4298 if (!(p = lock_user_string(arg1)))
4299 goto efault;
4300 ret = get_errno(chmod(p, arg2));
4301 unlock_user(p, arg1, 0);
4302 break;
4303 #ifdef TARGET_NR_break
4304 case TARGET_NR_break:
4305 goto unimplemented;
4306 #endif
4307 #ifdef TARGET_NR_oldstat
4308 case TARGET_NR_oldstat:
4309 goto unimplemented;
4310 #endif
4311 case TARGET_NR_lseek:
4312 ret = get_errno(lseek(arg1, arg2, arg3));
4313 break;
4314 #ifdef TARGET_NR_getxpid
4315 case TARGET_NR_getxpid:
4316 #else
4317 case TARGET_NR_getpid:
4318 #endif
4319 ret = get_errno(getpid());
4320 break;
4321 case TARGET_NR_mount:
4323 /* need to look at the data field */
4324 void *p2, *p3;
4325 p = lock_user_string(arg1);
4326 p2 = lock_user_string(arg2);
4327 p3 = lock_user_string(arg3);
4328 if (!p || !p2 || !p3)
4329 ret = -TARGET_EFAULT;
4330 else
4331 /* FIXME - arg5 should be locked, but it isn't clear how to
4332 * do that since it's not guaranteed to be a NULL-terminated
4333 * string.
4335 ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
4336 unlock_user(p, arg1, 0);
4337 unlock_user(p2, arg2, 0);
4338 unlock_user(p3, arg3, 0);
4339 break;
4341 #ifdef TARGET_NR_umount
4342 case TARGET_NR_umount:
4343 if (!(p = lock_user_string(arg1)))
4344 goto efault;
4345 ret = get_errno(umount(p));
4346 unlock_user(p, arg1, 0);
4347 break;
4348 #endif
4349 #ifdef TARGET_NR_stime /* not on alpha */
4350 case TARGET_NR_stime:
4352 time_t host_time;
4353 if (get_user_sal(host_time, arg1))
4354 goto efault;
4355 ret = get_errno(stime(&host_time));
4357 break;
4358 #endif
4359 case TARGET_NR_ptrace:
4360 goto unimplemented;
4361 #ifdef TARGET_NR_alarm /* not on alpha */
4362 case TARGET_NR_alarm:
4363 ret = alarm(arg1);
4364 break;
4365 #endif
4366 #ifdef TARGET_NR_oldfstat
4367 case TARGET_NR_oldfstat:
4368 goto unimplemented;
4369 #endif
4370 #ifdef TARGET_NR_pause /* not on alpha */
4371 case TARGET_NR_pause:
4372 ret = get_errno(pause());
4373 break;
4374 #endif
4375 #ifdef TARGET_NR_utime
4376 case TARGET_NR_utime:
4378 struct utimbuf tbuf, *host_tbuf;
4379 struct target_utimbuf *target_tbuf;
4380 if (arg2) {
4381 if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
4382 goto efault;
4383 tbuf.actime = tswapl(target_tbuf->actime);
4384 tbuf.modtime = tswapl(target_tbuf->modtime);
4385 unlock_user_struct(target_tbuf, arg2, 0);
4386 host_tbuf = &tbuf;
4387 } else {
4388 host_tbuf = NULL;
4390 if (!(p = lock_user_string(arg1)))
4391 goto efault;
4392 ret = get_errno(utime(p, host_tbuf));
4393 unlock_user(p, arg1, 0);
4395 break;
4396 #endif
4397 case TARGET_NR_utimes:
4399 struct timeval *tvp, tv[2];
4400 if (arg2) {
4401 if (copy_from_user_timeval(&tv[0], arg2)
4402 || copy_from_user_timeval(&tv[1],
4403 arg2 + sizeof(struct target_timeval)))
4404 goto efault;
4405 tvp = tv;
4406 } else {
4407 tvp = NULL;
4409 if (!(p = lock_user_string(arg1)))
4410 goto efault;
4411 ret = get_errno(utimes(p, tvp));
4412 unlock_user(p, arg1, 0);
4414 break;
4415 #if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
4416 case TARGET_NR_futimesat:
4418 struct timeval *tvp, tv[2];
4419 if (arg3) {
4420 if (copy_from_user_timeval(&tv[0], arg3)
4421 || copy_from_user_timeval(&tv[1],
4422 arg3 + sizeof(struct target_timeval)))
4423 goto efault;
4424 tvp = tv;
4425 } else {
4426 tvp = NULL;
4428 if (!(p = lock_user_string(arg2)))
4429 goto efault;
4430 ret = get_errno(sys_futimesat(arg1, path(p), tvp));
4431 unlock_user(p, arg2, 0);
4433 break;
4434 #endif
4435 #ifdef TARGET_NR_stty
4436 case TARGET_NR_stty:
4437 goto unimplemented;
4438 #endif
4439 #ifdef TARGET_NR_gtty
4440 case TARGET_NR_gtty:
4441 goto unimplemented;
4442 #endif
4443 case TARGET_NR_access:
4444 if (!(p = lock_user_string(arg1)))
4445 goto efault;
4446 ret = get_errno(access(p, arg2));
4447 unlock_user(p, arg1, 0);
4448 break;
4449 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
4450 case TARGET_NR_faccessat:
4451 if (!(p = lock_user_string(arg2)))
4452 goto efault;
4453 ret = get_errno(sys_faccessat(arg1, p, arg3));
4454 unlock_user(p, arg2, 0);
4455 break;
4456 #endif
4457 #ifdef TARGET_NR_nice /* not on alpha */
4458 case TARGET_NR_nice:
4459 ret = get_errno(nice(arg1));
4460 break;
4461 #endif
4462 #ifdef TARGET_NR_ftime
4463 case TARGET_NR_ftime:
4464 goto unimplemented;
4465 #endif
4466 case TARGET_NR_sync:
4467 sync();
4468 ret = 0;
4469 break;
4470 case TARGET_NR_kill:
4471 ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
4472 break;
4473 case TARGET_NR_rename:
4475 void *p2;
4476 p = lock_user_string(arg1);
4477 p2 = lock_user_string(arg2);
4478 if (!p || !p2)
4479 ret = -TARGET_EFAULT;
4480 else
4481 ret = get_errno(rename(p, p2));
4482 unlock_user(p2, arg2, 0);
4483 unlock_user(p, arg1, 0);
4485 break;
4486 #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
4487 case TARGET_NR_renameat:
4489 void *p2;
4490 p = lock_user_string(arg2);
4491 p2 = lock_user_string(arg4);
4492 if (!p || !p2)
4493 ret = -TARGET_EFAULT;
4494 else
4495 ret = get_errno(sys_renameat(arg1, p, arg3, p2));
4496 unlock_user(p2, arg4, 0);
4497 unlock_user(p, arg2, 0);
4499 break;
4500 #endif
4501 case TARGET_NR_mkdir:
4502 if (!(p = lock_user_string(arg1)))
4503 goto efault;
4504 ret = get_errno(mkdir(p, arg2));
4505 unlock_user(p, arg1, 0);
4506 break;
4507 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
4508 case TARGET_NR_mkdirat:
4509 if (!(p = lock_user_string(arg2)))
4510 goto efault;
4511 ret = get_errno(sys_mkdirat(arg1, p, arg3));
4512 unlock_user(p, arg2, 0);
4513 break;
4514 #endif
4515 case TARGET_NR_rmdir:
4516 if (!(p = lock_user_string(arg1)))
4517 goto efault;
4518 ret = get_errno(rmdir(p));
4519 unlock_user(p, arg1, 0);
4520 break;
4521 case TARGET_NR_dup:
4522 ret = get_errno(dup(arg1));
4523 break;
4524 case TARGET_NR_pipe:
4526 int host_pipe[2];
4527 ret = get_errno(pipe(host_pipe));
4528 if (!is_error(ret)) {
4529 #if defined(TARGET_MIPS)
4530 CPUMIPSState *env = (CPUMIPSState*)cpu_env;
4531 env->active_tc.gpr[3] = host_pipe[1];
4532 ret = host_pipe[0];
4533 #elif defined(TARGET_SH4)
4534 ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
4535 ret = host_pipe[0];
4536 #else
4537 if (put_user_s32(host_pipe[0], arg1)
4538 || put_user_s32(host_pipe[1], arg1 + sizeof(host_pipe[0])))
4539 goto efault;
4540 #endif
4543 break;
4544 case TARGET_NR_times:
4546 struct target_tms *tmsp;
4547 struct tms tms;
4548 ret = get_errno(times(&tms));
4549 if (arg1) {
4550 tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
4551 if (!tmsp)
4552 goto efault;
4553 tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
4554 tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
4555 tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
4556 tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime));
4558 if (!is_error(ret))
4559 ret = host_to_target_clock_t(ret);
4561 break;
4562 #ifdef TARGET_NR_prof
4563 case TARGET_NR_prof:
4564 goto unimplemented;
4565 #endif
4566 #ifdef TARGET_NR_signal
4567 case TARGET_NR_signal:
4568 goto unimplemented;
4569 #endif
4570 case TARGET_NR_acct:
4571 if (arg1 == 0) {
4572 ret = get_errno(acct(NULL));
4573 } else {
4574 if (!(p = lock_user_string(arg1)))
4575 goto efault;
4576 ret = get_errno(acct(path(p)));
4577 unlock_user(p, arg1, 0);
4579 break;
4580 #ifdef TARGET_NR_umount2 /* not on alpha */
4581 case TARGET_NR_umount2:
4582 if (!(p = lock_user_string(arg1)))
4583 goto efault;
4584 ret = get_errno(umount2(p, arg2));
4585 unlock_user(p, arg1, 0);
4586 break;
4587 #endif
4588 #ifdef TARGET_NR_lock
4589 case TARGET_NR_lock:
4590 goto unimplemented;
4591 #endif
4592 case TARGET_NR_ioctl:
4593 ret = do_ioctl(arg1, arg2, arg3);
4594 break;
4595 case TARGET_NR_fcntl:
4596 ret = do_fcntl(arg1, arg2, arg3);
4597 break;
4598 #ifdef TARGET_NR_mpx
4599 case TARGET_NR_mpx:
4600 goto unimplemented;
4601 #endif
4602 case TARGET_NR_setpgid:
4603 ret = get_errno(setpgid(arg1, arg2));
4604 break;
4605 #ifdef TARGET_NR_ulimit
4606 case TARGET_NR_ulimit:
4607 goto unimplemented;
4608 #endif
4609 #ifdef TARGET_NR_oldolduname
4610 case TARGET_NR_oldolduname:
4611 goto unimplemented;
4612 #endif
4613 case TARGET_NR_umask:
4614 ret = get_errno(umask(arg1));
4615 break;
4616 case TARGET_NR_chroot:
4617 if (!(p = lock_user_string(arg1)))
4618 goto efault;
4619 ret = get_errno(chroot(p));
4620 unlock_user(p, arg1, 0);
4621 break;
4622 case TARGET_NR_ustat:
4623 goto unimplemented;
4624 case TARGET_NR_dup2:
4625 ret = get_errno(dup2(arg1, arg2));
4626 break;
4627 #ifdef TARGET_NR_getppid /* not on alpha */
4628 case TARGET_NR_getppid:
4629 ret = get_errno(getppid());
4630 break;
4631 #endif
4632 case TARGET_NR_getpgrp:
4633 ret = get_errno(getpgrp());
4634 break;
4635 case TARGET_NR_setsid:
4636 ret = get_errno(setsid());
4637 break;
4638 #ifdef TARGET_NR_sigaction
4639 case TARGET_NR_sigaction:
4641 #if !defined(TARGET_MIPS)
4642 struct target_old_sigaction *old_act;
4643 struct target_sigaction act, oact, *pact;
4644 if (arg2) {
4645 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4646 goto efault;
4647 act._sa_handler = old_act->_sa_handler;
4648 target_siginitset(&act.sa_mask, old_act->sa_mask);
4649 act.sa_flags = old_act->sa_flags;
4650 act.sa_restorer = old_act->sa_restorer;
4651 unlock_user_struct(old_act, arg2, 0);
4652 pact = &act;
4653 } else {
4654 pact = NULL;
4656 ret = get_errno(do_sigaction(arg1, pact, &oact));
4657 if (!is_error(ret) && arg3) {
4658 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4659 goto efault;
4660 old_act->_sa_handler = oact._sa_handler;
4661 old_act->sa_mask = oact.sa_mask.sig[0];
4662 old_act->sa_flags = oact.sa_flags;
4663 old_act->sa_restorer = oact.sa_restorer;
4664 unlock_user_struct(old_act, arg3, 1);
4666 #else
4667 struct target_sigaction act, oact, *pact, *old_act;
4669 if (arg2) {
4670 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4671 goto efault;
4672 act._sa_handler = old_act->_sa_handler;
4673 target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
4674 act.sa_flags = old_act->sa_flags;
4675 unlock_user_struct(old_act, arg2, 0);
4676 pact = &act;
4677 } else {
4678 pact = NULL;
4681 ret = get_errno(do_sigaction(arg1, pact, &oact));
4683 if (!is_error(ret) && arg3) {
4684 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4685 goto efault;
4686 old_act->_sa_handler = oact._sa_handler;
4687 old_act->sa_flags = oact.sa_flags;
4688 old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
4689 old_act->sa_mask.sig[1] = 0;
4690 old_act->sa_mask.sig[2] = 0;
4691 old_act->sa_mask.sig[3] = 0;
4692 unlock_user_struct(old_act, arg3, 1);
4694 #endif
4696 break;
4697 #endif
4698 case TARGET_NR_rt_sigaction:
4700 struct target_sigaction *act;
4701 struct target_sigaction *oact;
4703 if (arg2) {
4704 if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
4705 goto efault;
4706 } else
4707 act = NULL;
4708 if (arg3) {
4709 if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
4710 ret = -TARGET_EFAULT;
4711 goto rt_sigaction_fail;
4713 } else
4714 oact = NULL;
4715 ret = get_errno(do_sigaction(arg1, act, oact));
4716 rt_sigaction_fail:
4717 if (act)
4718 unlock_user_struct(act, arg2, 0);
4719 if (oact)
4720 unlock_user_struct(oact, arg3, 1);
4722 break;
4723 #ifdef TARGET_NR_sgetmask /* not on alpha */
4724 case TARGET_NR_sgetmask:
4726 sigset_t cur_set;
4727 abi_ulong target_set;
4728 sigprocmask(0, NULL, &cur_set);
4729 host_to_target_old_sigset(&target_set, &cur_set);
4730 ret = target_set;
4732 break;
4733 #endif
4734 #ifdef TARGET_NR_ssetmask /* not on alpha */
4735 case TARGET_NR_ssetmask:
4737 sigset_t set, oset, cur_set;
4738 abi_ulong target_set = arg1;
4739 sigprocmask(0, NULL, &cur_set);
4740 target_to_host_old_sigset(&set, &target_set);
4741 sigorset(&set, &set, &cur_set);
4742 sigprocmask(SIG_SETMASK, &set, &oset);
4743 host_to_target_old_sigset(&target_set, &oset);
4744 ret = target_set;
4746 break;
4747 #endif
4748 #ifdef TARGET_NR_sigprocmask
4749 case TARGET_NR_sigprocmask:
4751 int how = arg1;
4752 sigset_t set, oldset, *set_ptr;
4754 if (arg2) {
4755 switch(how) {
4756 case TARGET_SIG_BLOCK:
4757 how = SIG_BLOCK;
4758 break;
4759 case TARGET_SIG_UNBLOCK:
4760 how = SIG_UNBLOCK;
4761 break;
4762 case TARGET_SIG_SETMASK:
4763 how = SIG_SETMASK;
4764 break;
4765 default:
4766 ret = -TARGET_EINVAL;
4767 goto fail;
4769 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4770 goto efault;
4771 target_to_host_old_sigset(&set, p);
4772 unlock_user(p, arg2, 0);
4773 set_ptr = &set;
4774 } else {
4775 how = 0;
4776 set_ptr = NULL;
4778 ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
4779 if (!is_error(ret) && arg3) {
4780 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4781 goto efault;
4782 host_to_target_old_sigset(p, &oldset);
4783 unlock_user(p, arg3, sizeof(target_sigset_t));
4786 break;
4787 #endif
4788 case TARGET_NR_rt_sigprocmask:
4790 int how = arg1;
4791 sigset_t set, oldset, *set_ptr;
4793 if (arg2) {
4794 switch(how) {
4795 case TARGET_SIG_BLOCK:
4796 how = SIG_BLOCK;
4797 break;
4798 case TARGET_SIG_UNBLOCK:
4799 how = SIG_UNBLOCK;
4800 break;
4801 case TARGET_SIG_SETMASK:
4802 how = SIG_SETMASK;
4803 break;
4804 default:
4805 ret = -TARGET_EINVAL;
4806 goto fail;
4808 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4809 goto efault;
4810 target_to_host_sigset(&set, p);
4811 unlock_user(p, arg2, 0);
4812 set_ptr = &set;
4813 } else {
4814 how = 0;
4815 set_ptr = NULL;
4817 ret = get_errno(sigprocmask(how, set_ptr, &oldset));
4818 if (!is_error(ret) && arg3) {
4819 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4820 goto efault;
4821 host_to_target_sigset(p, &oldset);
4822 unlock_user(p, arg3, sizeof(target_sigset_t));
4825 break;
4826 #ifdef TARGET_NR_sigpending
4827 case TARGET_NR_sigpending:
4829 sigset_t set;
4830 ret = get_errno(sigpending(&set));
4831 if (!is_error(ret)) {
4832 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4833 goto efault;
4834 host_to_target_old_sigset(p, &set);
4835 unlock_user(p, arg1, sizeof(target_sigset_t));
4838 break;
4839 #endif
4840 case TARGET_NR_rt_sigpending:
4842 sigset_t set;
4843 ret = get_errno(sigpending(&set));
4844 if (!is_error(ret)) {
4845 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4846 goto efault;
4847 host_to_target_sigset(p, &set);
4848 unlock_user(p, arg1, sizeof(target_sigset_t));
4851 break;
4852 #ifdef TARGET_NR_sigsuspend
4853 case TARGET_NR_sigsuspend:
4855 sigset_t set;
4856 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4857 goto efault;
4858 target_to_host_old_sigset(&set, p);
4859 unlock_user(p, arg1, 0);
4860 ret = get_errno(sigsuspend(&set));
4862 break;
4863 #endif
4864 case TARGET_NR_rt_sigsuspend:
4866 sigset_t set;
4867 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4868 goto efault;
4869 target_to_host_sigset(&set, p);
4870 unlock_user(p, arg1, 0);
4871 ret = get_errno(sigsuspend(&set));
4873 break;
4874 case TARGET_NR_rt_sigtimedwait:
4876 sigset_t set;
4877 struct timespec uts, *puts;
4878 siginfo_t uinfo;
4880 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4881 goto efault;
4882 target_to_host_sigset(&set, p);
4883 unlock_user(p, arg1, 0);
4884 if (arg3) {
4885 puts = &uts;
4886 target_to_host_timespec(puts, arg3);
4887 } else {
4888 puts = NULL;
4890 ret = get_errno(sigtimedwait(&set, &uinfo, puts));
4891 if (!is_error(ret) && arg2) {
4892 if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
4893 goto efault;
4894 host_to_target_siginfo(p, &uinfo);
4895 unlock_user(p, arg2, sizeof(target_siginfo_t));
4898 break;
4899 case TARGET_NR_rt_sigqueueinfo:
4901 siginfo_t uinfo;
4902 if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
4903 goto efault;
4904 target_to_host_siginfo(&uinfo, p);
4905 unlock_user(p, arg1, 0);
4906 ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
4908 break;
4909 #ifdef TARGET_NR_sigreturn
4910 case TARGET_NR_sigreturn:
4911 /* NOTE: ret is eax, so not transcoding must be done */
4912 ret = do_sigreturn(cpu_env);
4913 break;
4914 #endif
4915 case TARGET_NR_rt_sigreturn:
4916 /* NOTE: ret is eax, so not transcoding must be done */
4917 ret = do_rt_sigreturn(cpu_env);
4918 break;
4919 case TARGET_NR_sethostname:
4920 if (!(p = lock_user_string(arg1)))
4921 goto efault;
4922 ret = get_errno(sethostname(p, arg2));
4923 unlock_user(p, arg1, 0);
4924 break;
4925 case TARGET_NR_setrlimit:
4927 /* XXX: convert resource ? */
4928 int resource = arg1;
4929 struct target_rlimit *target_rlim;
4930 struct rlimit rlim;
4931 if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
4932 goto efault;
4933 rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4934 rlim.rlim_max = tswapl(target_rlim->rlim_max);
4935 unlock_user_struct(target_rlim, arg2, 0);
4936 ret = get_errno(setrlimit(resource, &rlim));
4938 break;
4939 case TARGET_NR_getrlimit:
4941 /* XXX: convert resource ? */
4942 int resource = arg1;
4943 struct target_rlimit *target_rlim;
4944 struct rlimit rlim;
4946 ret = get_errno(getrlimit(resource, &rlim));
4947 if (!is_error(ret)) {
4948 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
4949 goto efault;
4950 rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4951 rlim.rlim_max = tswapl(target_rlim->rlim_max);
4952 unlock_user_struct(target_rlim, arg2, 1);
4955 break;
4956 case TARGET_NR_getrusage:
4958 struct rusage rusage;
4959 ret = get_errno(getrusage(arg1, &rusage));
4960 if (!is_error(ret)) {
4961 host_to_target_rusage(arg2, &rusage);
4964 break;
4965 case TARGET_NR_gettimeofday:
4967 struct timeval tv;
4968 ret = get_errno(gettimeofday(&tv, NULL));
4969 if (!is_error(ret)) {
4970 if (copy_to_user_timeval(arg1, &tv))
4971 goto efault;
4974 break;
4975 case TARGET_NR_settimeofday:
4977 struct timeval tv;
4978 if (copy_from_user_timeval(&tv, arg1))
4979 goto efault;
4980 ret = get_errno(settimeofday(&tv, NULL));
4982 break;
4983 #ifdef TARGET_NR_select
4984 case TARGET_NR_select:
4986 struct target_sel_arg_struct *sel;
4987 abi_ulong inp, outp, exp, tvp;
4988 long nsel;
4990 if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
4991 goto efault;
4992 nsel = tswapl(sel->n);
4993 inp = tswapl(sel->inp);
4994 outp = tswapl(sel->outp);
4995 exp = tswapl(sel->exp);
4996 tvp = tswapl(sel->tvp);
4997 unlock_user_struct(sel, arg1, 0);
4998 ret = do_select(nsel, inp, outp, exp, tvp);
5000 break;
5001 #endif
5002 case TARGET_NR_symlink:
5004 void *p2;
5005 p = lock_user_string(arg1);
5006 p2 = lock_user_string(arg2);
5007 if (!p || !p2)
5008 ret = -TARGET_EFAULT;
5009 else
5010 ret = get_errno(symlink(p, p2));
5011 unlock_user(p2, arg2, 0);
5012 unlock_user(p, arg1, 0);
5014 break;
5015 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
5016 case TARGET_NR_symlinkat:
5018 void *p2;
5019 p = lock_user_string(arg1);
5020 p2 = lock_user_string(arg3);
5021 if (!p || !p2)
5022 ret = -TARGET_EFAULT;
5023 else
5024 ret = get_errno(sys_symlinkat(p, arg2, p2));
5025 unlock_user(p2, arg3, 0);
5026 unlock_user(p, arg1, 0);
5028 break;
5029 #endif
5030 #ifdef TARGET_NR_oldlstat
5031 case TARGET_NR_oldlstat:
5032 goto unimplemented;
5033 #endif
5034 case TARGET_NR_readlink:
5036 void *p2, *temp;
5037 p = lock_user_string(arg1);
5038 p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
5039 if (!p || !p2)
5040 ret = -TARGET_EFAULT;
5041 else {
5042 if (strncmp((const char *)p, "/proc/self/exe", 14) == 0) {
5043 char real[PATH_MAX];
5044 temp = realpath(exec_path,real);
5045 ret = (temp==NULL) ? get_errno(-1) : strlen(real) ;
5046 snprintf((char *)p2, arg3, "%s", real);
5048 else
5049 ret = get_errno(readlink(path(p), p2, arg3));
5051 unlock_user(p2, arg2, ret);
5052 unlock_user(p, arg1, 0);
5054 break;
5055 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
5056 case TARGET_NR_readlinkat:
5058 void *p2;
5059 p = lock_user_string(arg2);
5060 p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
5061 if (!p || !p2)
5062 ret = -TARGET_EFAULT;
5063 else
5064 ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
5065 unlock_user(p2, arg3, ret);
5066 unlock_user(p, arg2, 0);
5068 break;
5069 #endif
5070 #ifdef TARGET_NR_uselib
5071 case TARGET_NR_uselib:
5072 goto unimplemented;
5073 #endif
5074 #ifdef TARGET_NR_swapon
5075 case TARGET_NR_swapon:
5076 if (!(p = lock_user_string(arg1)))
5077 goto efault;
5078 ret = get_errno(swapon(p, arg2));
5079 unlock_user(p, arg1, 0);
5080 break;
5081 #endif
5082 case TARGET_NR_reboot:
5083 goto unimplemented;
5084 #ifdef TARGET_NR_readdir
5085 case TARGET_NR_readdir:
5086 goto unimplemented;
5087 #endif
5088 #ifdef TARGET_NR_mmap
5089 case TARGET_NR_mmap:
5090 #if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE)
5092 abi_ulong *v;
5093 abi_ulong v1, v2, v3, v4, v5, v6;
5094 if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
5095 goto efault;
5096 v1 = tswapl(v[0]);
5097 v2 = tswapl(v[1]);
5098 v3 = tswapl(v[2]);
5099 v4 = tswapl(v[3]);
5100 v5 = tswapl(v[4]);
5101 v6 = tswapl(v[5]);
5102 unlock_user(v, arg1, 0);
5103 ret = get_errno(target_mmap(v1, v2, v3,
5104 target_to_host_bitmask(v4, mmap_flags_tbl),
5105 v5, v6));
5107 #else
5108 ret = get_errno(target_mmap(arg1, arg2, arg3,
5109 target_to_host_bitmask(arg4, mmap_flags_tbl),
5110 arg5,
5111 arg6));
5112 #endif
5113 break;
5114 #endif
5115 #ifdef TARGET_NR_mmap2
5116 case TARGET_NR_mmap2:
5117 #ifndef MMAP_SHIFT
5118 #define MMAP_SHIFT 12
5119 #endif
5120 ret = get_errno(target_mmap(arg1, arg2, arg3,
5121 target_to_host_bitmask(arg4, mmap_flags_tbl),
5122 arg5,
5123 arg6 << MMAP_SHIFT));
5124 break;
5125 #endif
5126 case TARGET_NR_munmap:
5127 ret = get_errno(target_munmap(arg1, arg2));
5128 break;
5129 case TARGET_NR_mprotect:
5130 ret = get_errno(target_mprotect(arg1, arg2, arg3));
5131 break;
5132 #ifdef TARGET_NR_mremap
5133 case TARGET_NR_mremap:
5134 ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
5135 break;
5136 #endif
5137 /* ??? msync/mlock/munlock are broken for softmmu. */
5138 #ifdef TARGET_NR_msync
5139 case TARGET_NR_msync:
5140 ret = get_errno(msync(g2h(arg1), arg2, arg3));
5141 break;
5142 #endif
5143 #ifdef TARGET_NR_mlock
5144 case TARGET_NR_mlock:
5145 ret = get_errno(mlock(g2h(arg1), arg2));
5146 break;
5147 #endif
5148 #ifdef TARGET_NR_munlock
5149 case TARGET_NR_munlock:
5150 ret = get_errno(munlock(g2h(arg1), arg2));
5151 break;
5152 #endif
5153 #ifdef TARGET_NR_mlockall
5154 case TARGET_NR_mlockall:
5155 ret = get_errno(mlockall(arg1));
5156 break;
5157 #endif
5158 #ifdef TARGET_NR_munlockall
5159 case TARGET_NR_munlockall:
5160 ret = get_errno(munlockall());
5161 break;
5162 #endif
5163 case TARGET_NR_truncate:
5164 if (!(p = lock_user_string(arg1)))
5165 goto efault;
5166 ret = get_errno(truncate(p, arg2));
5167 unlock_user(p, arg1, 0);
5168 break;
5169 case TARGET_NR_ftruncate:
5170 ret = get_errno(ftruncate(arg1, arg2));
5171 break;
5172 case TARGET_NR_fchmod:
5173 ret = get_errno(fchmod(arg1, arg2));
5174 break;
5175 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
5176 case TARGET_NR_fchmodat:
5177 if (!(p = lock_user_string(arg2)))
5178 goto efault;
5179 ret = get_errno(sys_fchmodat(arg1, p, arg3));
5180 unlock_user(p, arg2, 0);
5181 break;
5182 #endif
5183 case TARGET_NR_getpriority:
5184 /* libc does special remapping of the return value of
5185 * sys_getpriority() so it's just easiest to call
5186 * sys_getpriority() directly rather than through libc. */
5187 ret = sys_getpriority(arg1, arg2);
5188 break;
5189 case TARGET_NR_setpriority:
5190 ret = get_errno(setpriority(arg1, arg2, arg3));
5191 break;
5192 #ifdef TARGET_NR_profil
5193 case TARGET_NR_profil:
5194 goto unimplemented;
5195 #endif
5196 case TARGET_NR_statfs:
5197 if (!(p = lock_user_string(arg1)))
5198 goto efault;
5199 ret = get_errno(statfs(path(p), &stfs));
5200 unlock_user(p, arg1, 0);
5201 convert_statfs:
5202 if (!is_error(ret)) {
5203 struct target_statfs *target_stfs;
5205 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
5206 goto efault;
5207 __put_user(stfs.f_type, &target_stfs->f_type);
5208 __put_user(stfs.f_bsize, &target_stfs->f_bsize);
5209 __put_user(stfs.f_blocks, &target_stfs->f_blocks);
5210 __put_user(stfs.f_bfree, &target_stfs->f_bfree);
5211 __put_user(stfs.f_bavail, &target_stfs->f_bavail);
5212 __put_user(stfs.f_files, &target_stfs->f_files);
5213 __put_user(stfs.f_ffree, &target_stfs->f_ffree);
5214 __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
5215 __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
5216 __put_user(stfs.f_namelen, &target_stfs->f_namelen);
5217 unlock_user_struct(target_stfs, arg2, 1);
5219 break;
5220 case TARGET_NR_fstatfs:
5221 ret = get_errno(fstatfs(arg1, &stfs));
5222 goto convert_statfs;
5223 #ifdef TARGET_NR_statfs64
5224 case TARGET_NR_statfs64:
5225 if (!(p = lock_user_string(arg1)))
5226 goto efault;
5227 ret = get_errno(statfs(path(p), &stfs));
5228 unlock_user(p, arg1, 0);
5229 convert_statfs64:
5230 if (!is_error(ret)) {
5231 struct target_statfs64 *target_stfs;
5233 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
5234 goto efault;
5235 __put_user(stfs.f_type, &target_stfs->f_type);
5236 __put_user(stfs.f_bsize, &target_stfs->f_bsize);
5237 __put_user(stfs.f_blocks, &target_stfs->f_blocks);
5238 __put_user(stfs.f_bfree, &target_stfs->f_bfree);
5239 __put_user(stfs.f_bavail, &target_stfs->f_bavail);
5240 __put_user(stfs.f_files, &target_stfs->f_files);
5241 __put_user(stfs.f_ffree, &target_stfs->f_ffree);
5242 __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
5243 __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
5244 __put_user(stfs.f_namelen, &target_stfs->f_namelen);
5245 unlock_user_struct(target_stfs, arg3, 1);
5247 break;
5248 case TARGET_NR_fstatfs64:
5249 ret = get_errno(fstatfs(arg1, &stfs));
5250 goto convert_statfs64;
5251 #endif
5252 #ifdef TARGET_NR_ioperm
5253 case TARGET_NR_ioperm:
5254 goto unimplemented;
5255 #endif
5256 #ifdef TARGET_NR_socketcall
5257 case TARGET_NR_socketcall:
5258 ret = do_socketcall(arg1, arg2);
5259 break;
5260 #endif
5261 #ifdef TARGET_NR_accept
5262 case TARGET_NR_accept:
5263 ret = do_accept(arg1, arg2, arg3);
5264 break;
5265 #endif
5266 #ifdef TARGET_NR_bind
5267 case TARGET_NR_bind:
5268 ret = do_bind(arg1, arg2, arg3);
5269 break;
5270 #endif
5271 #ifdef TARGET_NR_connect
5272 case TARGET_NR_connect:
5273 ret = do_connect(arg1, arg2, arg3);
5274 break;
5275 #endif
5276 #ifdef TARGET_NR_getpeername
5277 case TARGET_NR_getpeername:
5278 ret = do_getpeername(arg1, arg2, arg3);
5279 break;
5280 #endif
5281 #ifdef TARGET_NR_getsockname
5282 case TARGET_NR_getsockname:
5283 ret = do_getsockname(arg1, arg2, arg3);
5284 break;
5285 #endif
5286 #ifdef TARGET_NR_getsockopt
5287 case TARGET_NR_getsockopt:
5288 ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
5289 break;
5290 #endif
5291 #ifdef TARGET_NR_listen
5292 case TARGET_NR_listen:
5293 ret = get_errno(listen(arg1, arg2));
5294 break;
5295 #endif
5296 #ifdef TARGET_NR_recv
5297 case TARGET_NR_recv:
5298 ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
5299 break;
5300 #endif
5301 #ifdef TARGET_NR_recvfrom
5302 case TARGET_NR_recvfrom:
5303 ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
5304 break;
5305 #endif
5306 #ifdef TARGET_NR_recvmsg
5307 case TARGET_NR_recvmsg:
5308 ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
5309 break;
5310 #endif
5311 #ifdef TARGET_NR_send
5312 case TARGET_NR_send:
5313 ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
5314 break;
5315 #endif
5316 #ifdef TARGET_NR_sendmsg
5317 case TARGET_NR_sendmsg:
5318 ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
5319 break;
5320 #endif
5321 #ifdef TARGET_NR_sendto
5322 case TARGET_NR_sendto:
5323 ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
5324 break;
5325 #endif
5326 #ifdef TARGET_NR_shutdown
5327 case TARGET_NR_shutdown:
5328 ret = get_errno(shutdown(arg1, arg2));
5329 break;
5330 #endif
5331 #ifdef TARGET_NR_socket
5332 case TARGET_NR_socket:
5333 ret = do_socket(arg1, arg2, arg3);
5334 break;
5335 #endif
5336 #ifdef TARGET_NR_socketpair
5337 case TARGET_NR_socketpair:
5338 ret = do_socketpair(arg1, arg2, arg3, arg4);
5339 break;
5340 #endif
5341 #ifdef TARGET_NR_setsockopt
5342 case TARGET_NR_setsockopt:
5343 ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
5344 break;
5345 #endif
5347 case TARGET_NR_syslog:
5348 if (!(p = lock_user_string(arg2)))
5349 goto efault;
5350 ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
5351 unlock_user(p, arg2, 0);
5352 break;
5354 case TARGET_NR_setitimer:
5356 struct itimerval value, ovalue, *pvalue;
5358 if (arg2) {
5359 pvalue = &value;
5360 if (copy_from_user_timeval(&pvalue->it_interval, arg2)
5361 || copy_from_user_timeval(&pvalue->it_value,
5362 arg2 + sizeof(struct target_timeval)))
5363 goto efault;
5364 } else {
5365 pvalue = NULL;
5367 ret = get_errno(setitimer(arg1, pvalue, &ovalue));
5368 if (!is_error(ret) && arg3) {
5369 if (copy_to_user_timeval(arg3,
5370 &ovalue.it_interval)
5371 || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
5372 &ovalue.it_value))
5373 goto efault;
5376 break;
5377 case TARGET_NR_getitimer:
5379 struct itimerval value;
5381 ret = get_errno(getitimer(arg1, &value));
5382 if (!is_error(ret) && arg2) {
5383 if (copy_to_user_timeval(arg2,
5384 &value.it_interval)
5385 || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
5386 &value.it_value))
5387 goto efault;
5390 break;
5391 case TARGET_NR_stat:
5392 if (!(p = lock_user_string(arg1)))
5393 goto efault;
5394 ret = get_errno(stat(path(p), &st));
5395 unlock_user(p, arg1, 0);
5396 goto do_stat;
5397 case TARGET_NR_lstat:
5398 if (!(p = lock_user_string(arg1)))
5399 goto efault;
5400 ret = get_errno(lstat(path(p), &st));
5401 unlock_user(p, arg1, 0);
5402 goto do_stat;
5403 case TARGET_NR_fstat:
5405 ret = get_errno(fstat(arg1, &st));
5406 do_stat:
5407 if (!is_error(ret)) {
5408 struct target_stat *target_st;
5410 if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
5411 goto efault;
5412 __put_user(st.st_dev, &target_st->st_dev);
5413 __put_user(st.st_ino, &target_st->st_ino);
5414 __put_user(st.st_mode, &target_st->st_mode);
5415 __put_user(st.st_uid, &target_st->st_uid);
5416 __put_user(st.st_gid, &target_st->st_gid);
5417 __put_user(st.st_nlink, &target_st->st_nlink);
5418 __put_user(st.st_rdev, &target_st->st_rdev);
5419 __put_user(st.st_size, &target_st->st_size);
5420 __put_user(st.st_blksize, &target_st->st_blksize);
5421 __put_user(st.st_blocks, &target_st->st_blocks);
5422 __put_user(st.st_atime, &target_st->target_st_atime);
5423 __put_user(st.st_mtime, &target_st->target_st_mtime);
5424 __put_user(st.st_ctime, &target_st->target_st_ctime);
5425 unlock_user_struct(target_st, arg2, 1);
5428 break;
5429 #ifdef TARGET_NR_olduname
5430 case TARGET_NR_olduname:
5431 goto unimplemented;
5432 #endif
5433 #ifdef TARGET_NR_iopl
5434 case TARGET_NR_iopl:
5435 goto unimplemented;
5436 #endif
5437 case TARGET_NR_vhangup:
5438 ret = get_errno(vhangup());
5439 break;
5440 #ifdef TARGET_NR_idle
5441 case TARGET_NR_idle:
5442 goto unimplemented;
5443 #endif
5444 #ifdef TARGET_NR_syscall
5445 case TARGET_NR_syscall:
5446 ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
5447 break;
5448 #endif
5449 case TARGET_NR_wait4:
5451 int status;
5452 abi_long status_ptr = arg2;
5453 struct rusage rusage, *rusage_ptr;
5454 abi_ulong target_rusage = arg4;
5455 if (target_rusage)
5456 rusage_ptr = &rusage;
5457 else
5458 rusage_ptr = NULL;
5459 ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
5460 if (!is_error(ret)) {
5461 if (status_ptr) {
5462 status = host_to_target_waitstatus(status);
5463 if (put_user_s32(status, status_ptr))
5464 goto efault;
5466 if (target_rusage)
5467 host_to_target_rusage(target_rusage, &rusage);
5470 break;
5471 #ifdef TARGET_NR_swapoff
5472 case TARGET_NR_swapoff:
5473 if (!(p = lock_user_string(arg1)))
5474 goto efault;
5475 ret = get_errno(swapoff(p));
5476 unlock_user(p, arg1, 0);
5477 break;
5478 #endif
5479 case TARGET_NR_sysinfo:
5481 struct target_sysinfo *target_value;
5482 struct sysinfo value;
5483 ret = get_errno(sysinfo(&value));
5484 if (!is_error(ret) && arg1)
5486 if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
5487 goto efault;
5488 __put_user(value.uptime, &target_value->uptime);
5489 __put_user(value.loads[0], &target_value->loads[0]);
5490 __put_user(value.loads[1], &target_value->loads[1]);
5491 __put_user(value.loads[2], &target_value->loads[2]);
5492 __put_user(value.totalram, &target_value->totalram);
5493 __put_user(value.freeram, &target_value->freeram);
5494 __put_user(value.sharedram, &target_value->sharedram);
5495 __put_user(value.bufferram, &target_value->bufferram);
5496 __put_user(value.totalswap, &target_value->totalswap);
5497 __put_user(value.freeswap, &target_value->freeswap);
5498 __put_user(value.procs, &target_value->procs);
5499 __put_user(value.totalhigh, &target_value->totalhigh);
5500 __put_user(value.freehigh, &target_value->freehigh);
5501 __put_user(value.mem_unit, &target_value->mem_unit);
5502 unlock_user_struct(target_value, arg1, 1);
5505 break;
5506 #ifdef TARGET_NR_ipc
5507 case TARGET_NR_ipc:
5508 ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
5509 break;
5510 #endif
5511 #ifdef TARGET_NR_semget
5512 case TARGET_NR_semget:
5513 ret = get_errno(semget(arg1, arg2, arg3));
5514 break;
5515 #endif
5516 #ifdef TARGET_NR_semop
5517 case TARGET_NR_semop:
5518 ret = get_errno(do_semop(arg1, arg2, arg3));
5519 break;
5520 #endif
5521 #ifdef TARGET_NR_semctl
5522 case TARGET_NR_semctl:
5523 ret = do_semctl(arg1, arg2, arg3, (union target_semun)(abi_ulong)arg4);
5524 break;
5525 #endif
5526 #ifdef TARGET_NR_msgctl
5527 case TARGET_NR_msgctl:
5528 ret = do_msgctl(arg1, arg2, arg3);
5529 break;
5530 #endif
5531 #ifdef TARGET_NR_msgget
5532 case TARGET_NR_msgget:
5533 ret = get_errno(msgget(arg1, arg2));
5534 break;
5535 #endif
5536 #ifdef TARGET_NR_msgrcv
5537 case TARGET_NR_msgrcv:
5538 ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
5539 break;
5540 #endif
5541 #ifdef TARGET_NR_msgsnd
5542 case TARGET_NR_msgsnd:
5543 ret = do_msgsnd(arg1, arg2, arg3, arg4);
5544 break;
5545 #endif
5546 #ifdef TARGET_NR_shmget
5547 case TARGET_NR_shmget:
5548 ret = get_errno(shmget(arg1, arg2, arg3));
5549 break;
5550 #endif
5551 #ifdef TARGET_NR_shmctl
5552 case TARGET_NR_shmctl:
5553 ret = do_shmctl(arg1, arg2, arg3);
5554 break;
5555 #endif
5556 #ifdef TARGET_NR_shmat
5557 case TARGET_NR_shmat:
5558 ret = do_shmat(arg1, arg2, arg3);
5559 break;
5560 #endif
5561 #ifdef TARGET_NR_shmdt
5562 case TARGET_NR_shmdt:
5563 ret = do_shmdt(arg1);
5564 break;
5565 #endif
5566 case TARGET_NR_fsync:
5567 ret = get_errno(fsync(arg1));
5568 break;
5569 case TARGET_NR_clone:
5570 #if defined(TARGET_SH4)
5571 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
5572 #elif defined(TARGET_CRIS)
5573 ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg4, arg5));
5574 #else
5575 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
5576 #endif
5577 break;
5578 #ifdef __NR_exit_group
5579 /* new thread calls */
5580 case TARGET_NR_exit_group:
5581 #ifdef HAVE_GPROF
5582 _mcleanup();
5583 #endif
5584 gdb_exit(cpu_env, arg1);
5585 ret = get_errno(exit_group(arg1));
5586 break;
5587 #endif
5588 case TARGET_NR_setdomainname:
5589 if (!(p = lock_user_string(arg1)))
5590 goto efault;
5591 ret = get_errno(setdomainname(p, arg2));
5592 unlock_user(p, arg1, 0);
5593 break;
5594 case TARGET_NR_uname:
5595 /* no need to transcode because we use the linux syscall */
5597 struct new_utsname * buf;
5599 if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
5600 goto efault;
5601 ret = get_errno(sys_uname(buf));
5602 if (!is_error(ret)) {
5603 /* Overrite the native machine name with whatever is being
5604 emulated. */
5605 strcpy (buf->machine, UNAME_MACHINE);
5606 /* Allow the user to override the reported release. */
5607 if (qemu_uname_release && *qemu_uname_release)
5608 strcpy (buf->release, qemu_uname_release);
5610 unlock_user_struct(buf, arg1, 1);
5612 break;
5613 #ifdef TARGET_I386
5614 case TARGET_NR_modify_ldt:
5615 ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
5616 break;
5617 #if !defined(TARGET_X86_64)
5618 case TARGET_NR_vm86old:
5619 goto unimplemented;
5620 case TARGET_NR_vm86:
5621 ret = do_vm86(cpu_env, arg1, arg2);
5622 break;
5623 #endif
5624 #endif
5625 case TARGET_NR_adjtimex:
5626 goto unimplemented;
5627 #ifdef TARGET_NR_create_module
5628 case TARGET_NR_create_module:
5629 #endif
5630 case TARGET_NR_init_module:
5631 case TARGET_NR_delete_module:
5632 #ifdef TARGET_NR_get_kernel_syms
5633 case TARGET_NR_get_kernel_syms:
5634 #endif
5635 goto unimplemented;
5636 case TARGET_NR_quotactl:
5637 goto unimplemented;
5638 case TARGET_NR_getpgid:
5639 ret = get_errno(getpgid(arg1));
5640 break;
5641 case TARGET_NR_fchdir:
5642 ret = get_errno(fchdir(arg1));
5643 break;
5644 #ifdef TARGET_NR_bdflush /* not on x86_64 */
5645 case TARGET_NR_bdflush:
5646 goto unimplemented;
5647 #endif
5648 #ifdef TARGET_NR_sysfs
5649 case TARGET_NR_sysfs:
5650 goto unimplemented;
5651 #endif
5652 case TARGET_NR_personality:
5653 ret = get_errno(personality(arg1));
5654 break;
5655 #ifdef TARGET_NR_afs_syscall
5656 case TARGET_NR_afs_syscall:
5657 goto unimplemented;
5658 #endif
5659 #ifdef TARGET_NR__llseek /* Not on alpha */
5660 case TARGET_NR__llseek:
5662 #if defined (__x86_64__)
5663 ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
5664 if (put_user_s64(ret, arg4))
5665 goto efault;
5666 #else
5667 int64_t res;
5668 ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
5669 if (put_user_s64(res, arg4))
5670 goto efault;
5671 #endif
5673 break;
5674 #endif
5675 case TARGET_NR_getdents:
5676 #if TARGET_ABI_BITS != 32
5677 goto unimplemented;
5678 #elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
5680 struct target_dirent *target_dirp;
5681 struct linux_dirent *dirp;
5682 abi_long count = arg3;
5684 dirp = malloc(count);
5685 if (!dirp) {
5686 ret = -TARGET_ENOMEM;
5687 goto fail;
5690 ret = get_errno(sys_getdents(arg1, dirp, count));
5691 if (!is_error(ret)) {
5692 struct linux_dirent *de;
5693 struct target_dirent *tde;
5694 int len = ret;
5695 int reclen, treclen;
5696 int count1, tnamelen;
5698 count1 = 0;
5699 de = dirp;
5700 if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5701 goto efault;
5702 tde = target_dirp;
5703 while (len > 0) {
5704 reclen = de->d_reclen;
5705 treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
5706 tde->d_reclen = tswap16(treclen);
5707 tde->d_ino = tswapl(de->d_ino);
5708 tde->d_off = tswapl(de->d_off);
5709 tnamelen = treclen - (2 * sizeof(abi_long) + 2);
5710 if (tnamelen > 256)
5711 tnamelen = 256;
5712 /* XXX: may not be correct */
5713 pstrcpy(tde->d_name, tnamelen, de->d_name);
5714 de = (struct linux_dirent *)((char *)de + reclen);
5715 len -= reclen;
5716 tde = (struct target_dirent *)((char *)tde + treclen);
5717 count1 += treclen;
5719 ret = count1;
5720 unlock_user(target_dirp, arg2, ret);
5722 free(dirp);
5724 #else
5726 struct linux_dirent *dirp;
5727 abi_long count = arg3;
5729 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5730 goto efault;
5731 ret = get_errno(sys_getdents(arg1, dirp, count));
5732 if (!is_error(ret)) {
5733 struct linux_dirent *de;
5734 int len = ret;
5735 int reclen;
5736 de = dirp;
5737 while (len > 0) {
5738 reclen = de->d_reclen;
5739 if (reclen > len)
5740 break;
5741 de->d_reclen = tswap16(reclen);
5742 tswapls(&de->d_ino);
5743 tswapls(&de->d_off);
5744 de = (struct linux_dirent *)((char *)de + reclen);
5745 len -= reclen;
5748 unlock_user(dirp, arg2, ret);
5750 #endif
5751 break;
5752 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
5753 case TARGET_NR_getdents64:
5755 struct linux_dirent64 *dirp;
5756 abi_long count = arg3;
5757 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5758 goto efault;
5759 ret = get_errno(sys_getdents64(arg1, dirp, count));
5760 if (!is_error(ret)) {
5761 struct linux_dirent64 *de;
5762 int len = ret;
5763 int reclen;
5764 de = dirp;
5765 while (len > 0) {
5766 reclen = de->d_reclen;
5767 if (reclen > len)
5768 break;
5769 de->d_reclen = tswap16(reclen);
5770 tswap64s((uint64_t *)&de->d_ino);
5771 tswap64s((uint64_t *)&de->d_off);
5772 de = (struct linux_dirent64 *)((char *)de + reclen);
5773 len -= reclen;
5776 unlock_user(dirp, arg2, ret);
5778 break;
5779 #endif /* TARGET_NR_getdents64 */
5780 #ifdef TARGET_NR__newselect
5781 case TARGET_NR__newselect:
5782 ret = do_select(arg1, arg2, arg3, arg4, arg5);
5783 break;
5784 #endif
5785 #ifdef TARGET_NR_poll
5786 case TARGET_NR_poll:
5788 struct target_pollfd *target_pfd;
5789 unsigned int nfds = arg2;
5790 int timeout = arg3;
5791 struct pollfd *pfd;
5792 unsigned int i;
5794 target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
5795 if (!target_pfd)
5796 goto efault;
5797 pfd = alloca(sizeof(struct pollfd) * nfds);
5798 for(i = 0; i < nfds; i++) {
5799 pfd[i].fd = tswap32(target_pfd[i].fd);
5800 pfd[i].events = tswap16(target_pfd[i].events);
5802 ret = get_errno(poll(pfd, nfds, timeout));
5803 if (!is_error(ret)) {
5804 for(i = 0; i < nfds; i++) {
5805 target_pfd[i].revents = tswap16(pfd[i].revents);
5807 ret += nfds * (sizeof(struct target_pollfd)
5808 - sizeof(struct pollfd));
5810 unlock_user(target_pfd, arg1, ret);
5812 break;
5813 #endif
5814 case TARGET_NR_flock:
5815 /* NOTE: the flock constant seems to be the same for every
5816 Linux platform */
5817 ret = get_errno(flock(arg1, arg2));
5818 break;
5819 case TARGET_NR_readv:
5821 int count = arg3;
5822 struct iovec *vec;
5824 vec = alloca(count * sizeof(struct iovec));
5825 if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
5826 goto efault;
5827 ret = get_errno(readv(arg1, vec, count));
5828 unlock_iovec(vec, arg2, count, 1);
5830 break;
5831 case TARGET_NR_writev:
5833 int count = arg3;
5834 struct iovec *vec;
5836 vec = alloca(count * sizeof(struct iovec));
5837 if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
5838 goto efault;
5839 ret = get_errno(writev(arg1, vec, count));
5840 unlock_iovec(vec, arg2, count, 0);
5842 break;
5843 case TARGET_NR_getsid:
5844 ret = get_errno(getsid(arg1));
5845 break;
5846 #if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
5847 case TARGET_NR_fdatasync:
5848 ret = get_errno(fdatasync(arg1));
5849 break;
5850 #endif
5851 case TARGET_NR__sysctl:
5852 /* We don't implement this, but ENOTDIR is always a safe
5853 return value. */
5854 ret = -TARGET_ENOTDIR;
5855 break;
5856 case TARGET_NR_sched_setparam:
5858 struct sched_param *target_schp;
5859 struct sched_param schp;
5861 if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
5862 goto efault;
5863 schp.sched_priority = tswap32(target_schp->sched_priority);
5864 unlock_user_struct(target_schp, arg2, 0);
5865 ret = get_errno(sched_setparam(arg1, &schp));
5867 break;
5868 case TARGET_NR_sched_getparam:
5870 struct sched_param *target_schp;
5871 struct sched_param schp;
5872 ret = get_errno(sched_getparam(arg1, &schp));
5873 if (!is_error(ret)) {
5874 if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
5875 goto efault;
5876 target_schp->sched_priority = tswap32(schp.sched_priority);
5877 unlock_user_struct(target_schp, arg2, 1);
5880 break;
5881 case TARGET_NR_sched_setscheduler:
5883 struct sched_param *target_schp;
5884 struct sched_param schp;
5885 if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
5886 goto efault;
5887 schp.sched_priority = tswap32(target_schp->sched_priority);
5888 unlock_user_struct(target_schp, arg3, 0);
5889 ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
5891 break;
5892 case TARGET_NR_sched_getscheduler:
5893 ret = get_errno(sched_getscheduler(arg1));
5894 break;
5895 case TARGET_NR_sched_yield:
5896 ret = get_errno(sched_yield());
5897 break;
5898 case TARGET_NR_sched_get_priority_max:
5899 ret = get_errno(sched_get_priority_max(arg1));
5900 break;
5901 case TARGET_NR_sched_get_priority_min:
5902 ret = get_errno(sched_get_priority_min(arg1));
5903 break;
5904 case TARGET_NR_sched_rr_get_interval:
5906 struct timespec ts;
5907 ret = get_errno(sched_rr_get_interval(arg1, &ts));
5908 if (!is_error(ret)) {
5909 host_to_target_timespec(arg2, &ts);
5912 break;
5913 case TARGET_NR_nanosleep:
5915 struct timespec req, rem;
5916 target_to_host_timespec(&req, arg1);
5917 ret = get_errno(nanosleep(&req, &rem));
5918 if (is_error(ret) && arg2) {
5919 host_to_target_timespec(arg2, &rem);
5922 break;
5923 #ifdef TARGET_NR_query_module
5924 case TARGET_NR_query_module:
5925 goto unimplemented;
5926 #endif
5927 #ifdef TARGET_NR_nfsservctl
5928 case TARGET_NR_nfsservctl:
5929 goto unimplemented;
5930 #endif
5931 case TARGET_NR_prctl:
5932 switch (arg1)
5934 case PR_GET_PDEATHSIG:
5936 int deathsig;
5937 ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
5938 if (!is_error(ret) && arg2
5939 && put_user_ual(deathsig, arg2))
5940 goto efault;
5942 break;
5943 default:
5944 ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
5945 break;
5947 break;
5948 #ifdef TARGET_NR_arch_prctl
5949 case TARGET_NR_arch_prctl:
5950 #if defined(TARGET_I386) && !defined(TARGET_ABI32)
5951 ret = do_arch_prctl(cpu_env, arg1, arg2);
5952 break;
5953 #else
5954 goto unimplemented;
5955 #endif
5956 #endif
5957 #ifdef TARGET_NR_pread
5958 case TARGET_NR_pread:
5959 #ifdef TARGET_ARM
5960 if (((CPUARMState *)cpu_env)->eabi)
5961 arg4 = arg5;
5962 #endif
5963 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5964 goto efault;
5965 ret = get_errno(pread(arg1, p, arg3, arg4));
5966 unlock_user(p, arg2, ret);
5967 break;
5968 case TARGET_NR_pwrite:
5969 #ifdef TARGET_ARM
5970 if (((CPUARMState *)cpu_env)->eabi)
5971 arg4 = arg5;
5972 #endif
5973 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5974 goto efault;
5975 ret = get_errno(pwrite(arg1, p, arg3, arg4));
5976 unlock_user(p, arg2, 0);
5977 break;
5978 #endif
5979 #ifdef TARGET_NR_pread64
5980 case TARGET_NR_pread64:
5981 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5982 goto efault;
5983 ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
5984 unlock_user(p, arg2, ret);
5985 break;
5986 case TARGET_NR_pwrite64:
5987 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5988 goto efault;
5989 ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
5990 unlock_user(p, arg2, 0);
5991 break;
5992 #endif
5993 case TARGET_NR_getcwd:
5994 if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
5995 goto efault;
5996 ret = get_errno(sys_getcwd1(p, arg2));
5997 unlock_user(p, arg1, ret);
5998 break;
5999 case TARGET_NR_capget:
6000 goto unimplemented;
6001 case TARGET_NR_capset:
6002 goto unimplemented;
6003 case TARGET_NR_sigaltstack:
6004 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
6005 defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA)
6006 ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env));
6007 break;
6008 #else
6009 goto unimplemented;
6010 #endif
6011 case TARGET_NR_sendfile:
6012 goto unimplemented;
6013 #ifdef TARGET_NR_getpmsg
6014 case TARGET_NR_getpmsg:
6015 goto unimplemented;
6016 #endif
6017 #ifdef TARGET_NR_putpmsg
6018 case TARGET_NR_putpmsg:
6019 goto unimplemented;
6020 #endif
6021 #ifdef TARGET_NR_vfork
6022 case TARGET_NR_vfork:
6023 ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
6024 0, 0, 0, 0));
6025 break;
6026 #endif
6027 #ifdef TARGET_NR_ugetrlimit
6028 case TARGET_NR_ugetrlimit:
6030 struct rlimit rlim;
6031 ret = get_errno(getrlimit(arg1, &rlim));
6032 if (!is_error(ret)) {
6033 struct target_rlimit *target_rlim;
6034 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
6035 goto efault;
6036 target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
6037 target_rlim->rlim_max = tswapl(rlim.rlim_max);
6038 unlock_user_struct(target_rlim, arg2, 1);
6040 break;
6042 #endif
6043 #ifdef TARGET_NR_truncate64
6044 case TARGET_NR_truncate64:
6045 if (!(p = lock_user_string(arg1)))
6046 goto efault;
6047 ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
6048 unlock_user(p, arg1, 0);
6049 break;
6050 #endif
6051 #ifdef TARGET_NR_ftruncate64
6052 case TARGET_NR_ftruncate64:
6053 ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
6054 break;
6055 #endif
6056 #ifdef TARGET_NR_stat64
6057 case TARGET_NR_stat64:
6058 if (!(p = lock_user_string(arg1)))
6059 goto efault;
6060 ret = get_errno(stat(path(p), &st));
6061 unlock_user(p, arg1, 0);
6062 if (!is_error(ret))
6063 ret = host_to_target_stat64(cpu_env, arg2, &st);
6064 break;
6065 #endif
6066 #ifdef TARGET_NR_lstat64
6067 case TARGET_NR_lstat64:
6068 if (!(p = lock_user_string(arg1)))
6069 goto efault;
6070 ret = get_errno(lstat(path(p), &st));
6071 unlock_user(p, arg1, 0);
6072 if (!is_error(ret))
6073 ret = host_to_target_stat64(cpu_env, arg2, &st);
6074 break;
6075 #endif
6076 #ifdef TARGET_NR_fstat64
6077 case TARGET_NR_fstat64:
6078 ret = get_errno(fstat(arg1, &st));
6079 if (!is_error(ret))
6080 ret = host_to_target_stat64(cpu_env, arg2, &st);
6081 break;
6082 #endif
6083 #if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
6084 (defined(__NR_fstatat64) || defined(__NR_newfstatat))
6085 #ifdef TARGET_NR_fstatat64
6086 case TARGET_NR_fstatat64:
6087 #endif
6088 #ifdef TARGET_NR_newfstatat
6089 case TARGET_NR_newfstatat:
6090 #endif
6091 if (!(p = lock_user_string(arg2)))
6092 goto efault;
6093 #ifdef __NR_fstatat64
6094 ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
6095 #else
6096 ret = get_errno(sys_newfstatat(arg1, path(p), &st, arg4));
6097 #endif
6098 if (!is_error(ret))
6099 ret = host_to_target_stat64(cpu_env, arg3, &st);
6100 break;
6101 #endif
6102 #ifdef USE_UID16
6103 case TARGET_NR_lchown:
6104 if (!(p = lock_user_string(arg1)))
6105 goto efault;
6106 ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
6107 unlock_user(p, arg1, 0);
6108 break;
6109 case TARGET_NR_getuid:
6110 ret = get_errno(high2lowuid(getuid()));
6111 break;
6112 case TARGET_NR_getgid:
6113 ret = get_errno(high2lowgid(getgid()));
6114 break;
6115 case TARGET_NR_geteuid:
6116 ret = get_errno(high2lowuid(geteuid()));
6117 break;
6118 case TARGET_NR_getegid:
6119 ret = get_errno(high2lowgid(getegid()));
6120 break;
6121 case TARGET_NR_setreuid:
6122 ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
6123 break;
6124 case TARGET_NR_setregid:
6125 ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
6126 break;
6127 case TARGET_NR_getgroups:
6129 int gidsetsize = arg1;
6130 uint16_t *target_grouplist;
6131 gid_t *grouplist;
6132 int i;
6134 grouplist = alloca(gidsetsize * sizeof(gid_t));
6135 ret = get_errno(getgroups(gidsetsize, grouplist));
6136 if (gidsetsize == 0)
6137 break;
6138 if (!is_error(ret)) {
6139 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
6140 if (!target_grouplist)
6141 goto efault;
6142 for(i = 0;i < ret; i++)
6143 target_grouplist[i] = tswap16(grouplist[i]);
6144 unlock_user(target_grouplist, arg2, gidsetsize * 2);
6147 break;
6148 case TARGET_NR_setgroups:
6150 int gidsetsize = arg1;
6151 uint16_t *target_grouplist;
6152 gid_t *grouplist;
6153 int i;
6155 grouplist = alloca(gidsetsize * sizeof(gid_t));
6156 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
6157 if (!target_grouplist) {
6158 ret = -TARGET_EFAULT;
6159 goto fail;
6161 for(i = 0;i < gidsetsize; i++)
6162 grouplist[i] = tswap16(target_grouplist[i]);
6163 unlock_user(target_grouplist, arg2, 0);
6164 ret = get_errno(setgroups(gidsetsize, grouplist));
6166 break;
6167 case TARGET_NR_fchown:
6168 ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
6169 break;
6170 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
6171 case TARGET_NR_fchownat:
6172 if (!(p = lock_user_string(arg2)))
6173 goto efault;
6174 ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
6175 unlock_user(p, arg2, 0);
6176 break;
6177 #endif
6178 #ifdef TARGET_NR_setresuid
6179 case TARGET_NR_setresuid:
6180 ret = get_errno(setresuid(low2highuid(arg1),
6181 low2highuid(arg2),
6182 low2highuid(arg3)));
6183 break;
6184 #endif
6185 #ifdef TARGET_NR_getresuid
6186 case TARGET_NR_getresuid:
6188 uid_t ruid, euid, suid;
6189 ret = get_errno(getresuid(&ruid, &euid, &suid));
6190 if (!is_error(ret)) {
6191 if (put_user_u16(high2lowuid(ruid), arg1)
6192 || put_user_u16(high2lowuid(euid), arg2)
6193 || put_user_u16(high2lowuid(suid), arg3))
6194 goto efault;
6197 break;
6198 #endif
6199 #ifdef TARGET_NR_getresgid
6200 case TARGET_NR_setresgid:
6201 ret = get_errno(setresgid(low2highgid(arg1),
6202 low2highgid(arg2),
6203 low2highgid(arg3)));
6204 break;
6205 #endif
6206 #ifdef TARGET_NR_getresgid
6207 case TARGET_NR_getresgid:
6209 gid_t rgid, egid, sgid;
6210 ret = get_errno(getresgid(&rgid, &egid, &sgid));
6211 if (!is_error(ret)) {
6212 if (put_user_u16(high2lowgid(rgid), arg1)
6213 || put_user_u16(high2lowgid(egid), arg2)
6214 || put_user_u16(high2lowgid(sgid), arg3))
6215 goto efault;
6218 break;
6219 #endif
6220 case TARGET_NR_chown:
6221 if (!(p = lock_user_string(arg1)))
6222 goto efault;
6223 ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
6224 unlock_user(p, arg1, 0);
6225 break;
6226 case TARGET_NR_setuid:
6227 ret = get_errno(setuid(low2highuid(arg1)));
6228 break;
6229 case TARGET_NR_setgid:
6230 ret = get_errno(setgid(low2highgid(arg1)));
6231 break;
6232 case TARGET_NR_setfsuid:
6233 ret = get_errno(setfsuid(arg1));
6234 break;
6235 case TARGET_NR_setfsgid:
6236 ret = get_errno(setfsgid(arg1));
6237 break;
6238 #endif /* USE_UID16 */
6240 #ifdef TARGET_NR_lchown32
6241 case TARGET_NR_lchown32:
6242 if (!(p = lock_user_string(arg1)))
6243 goto efault;
6244 ret = get_errno(lchown(p, arg2, arg3));
6245 unlock_user(p, arg1, 0);
6246 break;
6247 #endif
6248 #ifdef TARGET_NR_getuid32
6249 case TARGET_NR_getuid32:
6250 ret = get_errno(getuid());
6251 break;
6252 #endif
6254 #if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
6255 /* Alpha specific */
6256 case TARGET_NR_getxuid:
6258 uid_t euid;
6259 euid=geteuid();
6260 ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
6262 ret = get_errno(getuid());
6263 break;
6264 #endif
6265 #if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
6266 /* Alpha specific */
6267 case TARGET_NR_getxgid:
6269 uid_t egid;
6270 egid=getegid();
6271 ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
6273 ret = get_errno(getgid());
6274 break;
6275 #endif
6277 #ifdef TARGET_NR_getgid32
6278 case TARGET_NR_getgid32:
6279 ret = get_errno(getgid());
6280 break;
6281 #endif
6282 #ifdef TARGET_NR_geteuid32
6283 case TARGET_NR_geteuid32:
6284 ret = get_errno(geteuid());
6285 break;
6286 #endif
6287 #ifdef TARGET_NR_getegid32
6288 case TARGET_NR_getegid32:
6289 ret = get_errno(getegid());
6290 break;
6291 #endif
6292 #ifdef TARGET_NR_setreuid32
6293 case TARGET_NR_setreuid32:
6294 ret = get_errno(setreuid(arg1, arg2));
6295 break;
6296 #endif
6297 #ifdef TARGET_NR_setregid32
6298 case TARGET_NR_setregid32:
6299 ret = get_errno(setregid(arg1, arg2));
6300 break;
6301 #endif
6302 #ifdef TARGET_NR_getgroups32
6303 case TARGET_NR_getgroups32:
6305 int gidsetsize = arg1;
6306 uint32_t *target_grouplist;
6307 gid_t *grouplist;
6308 int i;
6310 grouplist = alloca(gidsetsize * sizeof(gid_t));
6311 ret = get_errno(getgroups(gidsetsize, grouplist));
6312 if (gidsetsize == 0)
6313 break;
6314 if (!is_error(ret)) {
6315 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
6316 if (!target_grouplist) {
6317 ret = -TARGET_EFAULT;
6318 goto fail;
6320 for(i = 0;i < ret; i++)
6321 target_grouplist[i] = tswap32(grouplist[i]);
6322 unlock_user(target_grouplist, arg2, gidsetsize * 4);
6325 break;
6326 #endif
6327 #ifdef TARGET_NR_setgroups32
6328 case TARGET_NR_setgroups32:
6330 int gidsetsize = arg1;
6331 uint32_t *target_grouplist;
6332 gid_t *grouplist;
6333 int i;
6335 grouplist = alloca(gidsetsize * sizeof(gid_t));
6336 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
6337 if (!target_grouplist) {
6338 ret = -TARGET_EFAULT;
6339 goto fail;
6341 for(i = 0;i < gidsetsize; i++)
6342 grouplist[i] = tswap32(target_grouplist[i]);
6343 unlock_user(target_grouplist, arg2, 0);
6344 ret = get_errno(setgroups(gidsetsize, grouplist));
6346 break;
6347 #endif
6348 #ifdef TARGET_NR_fchown32
6349 case TARGET_NR_fchown32:
6350 ret = get_errno(fchown(arg1, arg2, arg3));
6351 break;
6352 #endif
6353 #ifdef TARGET_NR_setresuid32
6354 case TARGET_NR_setresuid32:
6355 ret = get_errno(setresuid(arg1, arg2, arg3));
6356 break;
6357 #endif
6358 #ifdef TARGET_NR_getresuid32
6359 case TARGET_NR_getresuid32:
6361 uid_t ruid, euid, suid;
6362 ret = get_errno(getresuid(&ruid, &euid, &suid));
6363 if (!is_error(ret)) {
6364 if (put_user_u32(ruid, arg1)
6365 || put_user_u32(euid, arg2)
6366 || put_user_u32(suid, arg3))
6367 goto efault;
6370 break;
6371 #endif
6372 #ifdef TARGET_NR_setresgid32
6373 case TARGET_NR_setresgid32:
6374 ret = get_errno(setresgid(arg1, arg2, arg3));
6375 break;
6376 #endif
6377 #ifdef TARGET_NR_getresgid32
6378 case TARGET_NR_getresgid32:
6380 gid_t rgid, egid, sgid;
6381 ret = get_errno(getresgid(&rgid, &egid, &sgid));
6382 if (!is_error(ret)) {
6383 if (put_user_u32(rgid, arg1)
6384 || put_user_u32(egid, arg2)
6385 || put_user_u32(sgid, arg3))
6386 goto efault;
6389 break;
6390 #endif
6391 #ifdef TARGET_NR_chown32
6392 case TARGET_NR_chown32:
6393 if (!(p = lock_user_string(arg1)))
6394 goto efault;
6395 ret = get_errno(chown(p, arg2, arg3));
6396 unlock_user(p, arg1, 0);
6397 break;
6398 #endif
6399 #ifdef TARGET_NR_setuid32
6400 case TARGET_NR_setuid32:
6401 ret = get_errno(setuid(arg1));
6402 break;
6403 #endif
6404 #ifdef TARGET_NR_setgid32
6405 case TARGET_NR_setgid32:
6406 ret = get_errno(setgid(arg1));
6407 break;
6408 #endif
6409 #ifdef TARGET_NR_setfsuid32
6410 case TARGET_NR_setfsuid32:
6411 ret = get_errno(setfsuid(arg1));
6412 break;
6413 #endif
6414 #ifdef TARGET_NR_setfsgid32
6415 case TARGET_NR_setfsgid32:
6416 ret = get_errno(setfsgid(arg1));
6417 break;
6418 #endif
6420 case TARGET_NR_pivot_root:
6421 goto unimplemented;
6422 #ifdef TARGET_NR_mincore
6423 case TARGET_NR_mincore:
6425 void *a;
6426 ret = -TARGET_EFAULT;
6427 if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
6428 goto efault;
6429 if (!(p = lock_user_string(arg3)))
6430 goto mincore_fail;
6431 ret = get_errno(mincore(a, arg2, p));
6432 unlock_user(p, arg3, ret);
6433 mincore_fail:
6434 unlock_user(a, arg1, 0);
6436 break;
6437 #endif
6438 #ifdef TARGET_NR_arm_fadvise64_64
6439 case TARGET_NR_arm_fadvise64_64:
6442 * arm_fadvise64_64 looks like fadvise64_64 but
6443 * with different argument order
6445 abi_long temp;
6446 temp = arg3;
6447 arg3 = arg4;
6448 arg4 = temp;
6450 #endif
6451 #if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64)
6452 #ifdef TARGET_NR_fadvise64_64
6453 case TARGET_NR_fadvise64_64:
6454 #endif
6455 /* This is a hint, so ignoring and returning success is ok. */
6456 ret = get_errno(0);
6457 break;
6458 #endif
6459 #ifdef TARGET_NR_madvise
6460 case TARGET_NR_madvise:
6461 /* A straight passthrough may not be safe because qemu sometimes
6462 turns private flie-backed mappings into anonymous mappings.
6463 This will break MADV_DONTNEED.
6464 This is a hint, so ignoring and returning success is ok. */
6465 ret = get_errno(0);
6466 break;
6467 #endif
6468 #if TARGET_ABI_BITS == 32
6469 case TARGET_NR_fcntl64:
6471 int cmd;
6472 struct flock64 fl;
6473 struct target_flock64 *target_fl;
6474 #ifdef TARGET_ARM
6475 struct target_eabi_flock64 *target_efl;
6476 #endif
6478 switch(arg2){
6479 case TARGET_F_GETLK64:
6480 cmd = F_GETLK64;
6481 break;
6482 case TARGET_F_SETLK64:
6483 cmd = F_SETLK64;
6484 break;
6485 case TARGET_F_SETLKW64:
6486 cmd = F_SETLK64;
6487 break;
6488 default:
6489 cmd = arg2;
6490 break;
6493 switch(arg2) {
6494 case TARGET_F_GETLK64:
6495 #ifdef TARGET_ARM
6496 if (((CPUARMState *)cpu_env)->eabi) {
6497 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1))
6498 goto efault;
6499 fl.l_type = tswap16(target_efl->l_type);
6500 fl.l_whence = tswap16(target_efl->l_whence);
6501 fl.l_start = tswap64(target_efl->l_start);
6502 fl.l_len = tswap64(target_efl->l_len);
6503 fl.l_pid = tswapl(target_efl->l_pid);
6504 unlock_user_struct(target_efl, arg3, 0);
6505 } else
6506 #endif
6508 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1))
6509 goto efault;
6510 fl.l_type = tswap16(target_fl->l_type);
6511 fl.l_whence = tswap16(target_fl->l_whence);
6512 fl.l_start = tswap64(target_fl->l_start);
6513 fl.l_len = tswap64(target_fl->l_len);
6514 fl.l_pid = tswapl(target_fl->l_pid);
6515 unlock_user_struct(target_fl, arg3, 0);
6517 ret = get_errno(fcntl(arg1, cmd, &fl));
6518 if (ret == 0) {
6519 #ifdef TARGET_ARM
6520 if (((CPUARMState *)cpu_env)->eabi) {
6521 if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0))
6522 goto efault;
6523 target_efl->l_type = tswap16(fl.l_type);
6524 target_efl->l_whence = tswap16(fl.l_whence);
6525 target_efl->l_start = tswap64(fl.l_start);
6526 target_efl->l_len = tswap64(fl.l_len);
6527 target_efl->l_pid = tswapl(fl.l_pid);
6528 unlock_user_struct(target_efl, arg3, 1);
6529 } else
6530 #endif
6532 if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0))
6533 goto efault;
6534 target_fl->l_type = tswap16(fl.l_type);
6535 target_fl->l_whence = tswap16(fl.l_whence);
6536 target_fl->l_start = tswap64(fl.l_start);
6537 target_fl->l_len = tswap64(fl.l_len);
6538 target_fl->l_pid = tswapl(fl.l_pid);
6539 unlock_user_struct(target_fl, arg3, 1);
6542 break;
6544 case TARGET_F_SETLK64:
6545 case TARGET_F_SETLKW64:
6546 #ifdef TARGET_ARM
6547 if (((CPUARMState *)cpu_env)->eabi) {
6548 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1))
6549 goto efault;
6550 fl.l_type = tswap16(target_efl->l_type);
6551 fl.l_whence = tswap16(target_efl->l_whence);
6552 fl.l_start = tswap64(target_efl->l_start);
6553 fl.l_len = tswap64(target_efl->l_len);
6554 fl.l_pid = tswapl(target_efl->l_pid);
6555 unlock_user_struct(target_efl, arg3, 0);
6556 } else
6557 #endif
6559 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1))
6560 goto efault;
6561 fl.l_type = tswap16(target_fl->l_type);
6562 fl.l_whence = tswap16(target_fl->l_whence);
6563 fl.l_start = tswap64(target_fl->l_start);
6564 fl.l_len = tswap64(target_fl->l_len);
6565 fl.l_pid = tswapl(target_fl->l_pid);
6566 unlock_user_struct(target_fl, arg3, 0);
6568 ret = get_errno(fcntl(arg1, cmd, &fl));
6569 break;
6570 default:
6571 ret = do_fcntl(arg1, cmd, arg3);
6572 break;
6574 break;
6576 #endif
6577 #ifdef TARGET_NR_cacheflush
6578 case TARGET_NR_cacheflush:
6579 /* self-modifying code is handled automatically, so nothing needed */
6580 ret = 0;
6581 break;
6582 #endif
6583 #ifdef TARGET_NR_security
6584 case TARGET_NR_security:
6585 goto unimplemented;
6586 #endif
6587 #ifdef TARGET_NR_getpagesize
6588 case TARGET_NR_getpagesize:
6589 ret = TARGET_PAGE_SIZE;
6590 break;
6591 #endif
6592 case TARGET_NR_gettid:
6593 ret = get_errno(gettid());
6594 break;
6595 #ifdef TARGET_NR_readahead
6596 case TARGET_NR_readahead:
6597 #if TARGET_ABI_BITS == 32
6598 #ifdef TARGET_ARM
6599 if (((CPUARMState *)cpu_env)->eabi)
6601 arg2 = arg3;
6602 arg3 = arg4;
6603 arg4 = arg5;
6605 #endif
6606 ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
6607 #else
6608 ret = get_errno(readahead(arg1, arg2, arg3));
6609 #endif
6610 break;
6611 #endif
6612 #ifdef TARGET_NR_setxattr
6613 case TARGET_NR_setxattr:
6614 case TARGET_NR_lsetxattr:
6615 case TARGET_NR_fsetxattr:
6616 case TARGET_NR_getxattr:
6617 case TARGET_NR_lgetxattr:
6618 case TARGET_NR_fgetxattr:
6619 case TARGET_NR_listxattr:
6620 case TARGET_NR_llistxattr:
6621 case TARGET_NR_flistxattr:
6622 case TARGET_NR_removexattr:
6623 case TARGET_NR_lremovexattr:
6624 case TARGET_NR_fremovexattr:
6625 ret = -TARGET_EOPNOTSUPP;
6626 break;
6627 #endif
6628 #ifdef TARGET_NR_set_thread_area
6629 case TARGET_NR_set_thread_area:
6630 #if defined(TARGET_MIPS)
6631 ((CPUMIPSState *) cpu_env)->tls_value = arg1;
6632 ret = 0;
6633 break;
6634 #elif defined(TARGET_CRIS)
6635 if (arg1 & 0xff)
6636 ret = -TARGET_EINVAL;
6637 else {
6638 ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
6639 ret = 0;
6641 break;
6642 #elif defined(TARGET_I386) && defined(TARGET_ABI32)
6643 ret = do_set_thread_area(cpu_env, arg1);
6644 break;
6645 #else
6646 goto unimplemented_nowarn;
6647 #endif
6648 #endif
6649 #ifdef TARGET_NR_get_thread_area
6650 case TARGET_NR_get_thread_area:
6651 #if defined(TARGET_I386) && defined(TARGET_ABI32)
6652 ret = do_get_thread_area(cpu_env, arg1);
6653 #else
6654 goto unimplemented_nowarn;
6655 #endif
6656 #endif
6657 #ifdef TARGET_NR_getdomainname
6658 case TARGET_NR_getdomainname:
6659 goto unimplemented_nowarn;
6660 #endif
6662 #ifdef TARGET_NR_clock_gettime
6663 case TARGET_NR_clock_gettime:
6665 struct timespec ts;
6666 ret = get_errno(clock_gettime(arg1, &ts));
6667 if (!is_error(ret)) {
6668 host_to_target_timespec(arg2, &ts);
6670 break;
6672 #endif
6673 #ifdef TARGET_NR_clock_getres
6674 case TARGET_NR_clock_getres:
6676 struct timespec ts;
6677 ret = get_errno(clock_getres(arg1, &ts));
6678 if (!is_error(ret)) {
6679 host_to_target_timespec(arg2, &ts);
6681 break;
6683 #endif
6684 #ifdef TARGET_NR_clock_nanosleep
6685 case TARGET_NR_clock_nanosleep:
6687 struct timespec ts;
6688 target_to_host_timespec(&ts, arg3);
6689 ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
6690 if (arg4)
6691 host_to_target_timespec(arg4, &ts);
6692 break;
6694 #endif
6696 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
6697 case TARGET_NR_set_tid_address:
6698 ret = get_errno(set_tid_address((int *)g2h(arg1)));
6699 break;
6700 #endif
6702 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
6703 case TARGET_NR_tkill:
6704 ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
6705 break;
6706 #endif
6708 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
6709 case TARGET_NR_tgkill:
6710 ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
6711 target_to_host_signal(arg3)));
6712 break;
6713 #endif
6715 #ifdef TARGET_NR_set_robust_list
6716 case TARGET_NR_set_robust_list:
6717 goto unimplemented_nowarn;
6718 #endif
6720 #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
6721 case TARGET_NR_utimensat:
6723 struct timespec *tsp, ts[2];
6724 if (!arg3) {
6725 tsp = NULL;
6726 } else {
6727 target_to_host_timespec(ts, arg3);
6728 target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
6729 tsp = ts;
6731 if (!arg2)
6732 ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4));
6733 else {
6734 if (!(p = lock_user_string(arg2))) {
6735 ret = -TARGET_EFAULT;
6736 goto fail;
6738 ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4));
6739 unlock_user(p, arg2, 0);
6742 break;
6743 #endif
6744 #if defined(USE_NPTL)
6745 case TARGET_NR_futex:
6746 ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
6747 break;
6748 #endif
6749 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
6750 case TARGET_NR_inotify_init:
6751 ret = get_errno(sys_inotify_init());
6752 break;
6753 #endif
6754 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
6755 case TARGET_NR_inotify_add_watch:
6756 p = lock_user_string(arg2);
6757 ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
6758 unlock_user(p, arg2, 0);
6759 break;
6760 #endif
6761 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
6762 case TARGET_NR_inotify_rm_watch:
6763 ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
6764 break;
6765 #endif
6767 #ifdef TARGET_NR_mq_open
6768 case TARGET_NR_mq_open:
6770 struct mq_attr posix_mq_attr;
6772 p = lock_user_string(arg1 - 1);
6773 if (arg4 != 0)
6774 copy_from_user_mq_attr (&posix_mq_attr, arg4);
6775 ret = get_errno(mq_open(p, arg2, arg3, &posix_mq_attr));
6776 unlock_user (p, arg1, 0);
6778 break;
6780 case TARGET_NR_mq_unlink:
6781 p = lock_user_string(arg1 - 1);
6782 ret = get_errno(mq_unlink(p));
6783 unlock_user (p, arg1, 0);
6784 break;
6786 case TARGET_NR_mq_timedsend:
6788 struct timespec ts;
6790 p = lock_user (VERIFY_READ, arg2, arg3, 1);
6791 if (arg5 != 0) {
6792 target_to_host_timespec(&ts, arg5);
6793 ret = get_errno(mq_timedsend(arg1, p, arg3, arg4, &ts));
6794 host_to_target_timespec(arg5, &ts);
6796 else
6797 ret = get_errno(mq_send(arg1, p, arg3, arg4));
6798 unlock_user (p, arg2, arg3);
6800 break;
6802 case TARGET_NR_mq_timedreceive:
6804 struct timespec ts;
6805 unsigned int prio;
6807 p = lock_user (VERIFY_READ, arg2, arg3, 1);
6808 if (arg5 != 0) {
6809 target_to_host_timespec(&ts, arg5);
6810 ret = get_errno(mq_timedreceive(arg1, p, arg3, &prio, &ts));
6811 host_to_target_timespec(arg5, &ts);
6813 else
6814 ret = get_errno(mq_receive(arg1, p, arg3, &prio));
6815 unlock_user (p, arg2, arg3);
6816 if (arg4 != 0)
6817 put_user_u32(prio, arg4);
6819 break;
6821 /* Not implemented for now... */
6822 /* case TARGET_NR_mq_notify: */
6823 /* break; */
6825 case TARGET_NR_mq_getsetattr:
6827 struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
6828 ret = 0;
6829 if (arg3 != 0) {
6830 ret = mq_getattr(arg1, &posix_mq_attr_out);
6831 copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
6833 if (arg2 != 0) {
6834 copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
6835 ret |= mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_attr_out);
6839 break;
6840 #endif
6842 default:
6843 unimplemented:
6844 gemu_log("qemu: Unsupported syscall: %d\n", num);
6845 #if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
6846 unimplemented_nowarn:
6847 #endif
6848 ret = -TARGET_ENOSYS;
6849 break;
6851 fail:
6852 #ifdef DEBUG
6853 gemu_log(" = %ld\n", ret);
6854 #endif
6855 if(do_strace)
6856 print_syscall_ret(num, ret);
6857 return ret;
6858 efault:
6859 ret = -TARGET_EFAULT;
6860 goto fail;