Merge branch 'master' of ssh://repo.or.cz/srv/git/qemu
[qemu/hppa.git] / linux-user / syscall.c
bloba188468b68ecff3433a1a3023b19a19dc9fcfda6
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/msg.h>
54 #include <sys/statfs.h>
55 #include <utime.h>
56 #include <sys/sysinfo.h>
57 #include <sys/utsname.h>
58 //#include <sys/user.h>
59 #include <netinet/ip.h>
60 #include <netinet/tcp.h>
61 #include <qemu-common.h>
62 #ifdef HAVE_GPROF
63 #include <sys/gmon.h>
64 #endif
66 #define termios host_termios
67 #define winsize host_winsize
68 #define termio host_termio
69 #define sgttyb host_sgttyb /* same as target */
70 #define tchars host_tchars /* same as target */
71 #define ltchars host_ltchars /* same as target */
73 #include <linux/termios.h>
74 #include <linux/unistd.h>
75 #include <linux/utsname.h>
76 #include <linux/cdrom.h>
77 #include <linux/hdreg.h>
78 #include <linux/soundcard.h>
79 #include <linux/kd.h>
80 #include <linux/mtio.h>
81 #include "linux_loop.h"
83 #include "qemu.h"
84 #include "qemu-common.h"
86 #if defined(USE_NPTL)
87 #include <linux/futex.h>
88 #define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
89 CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
90 #else
91 /* XXX: Hardcode the above values. */
92 #define CLONE_NPTL_FLAGS2 0
93 #endif
95 //#define DEBUG
97 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \
98 || defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS)
99 /* 16 bit uid wrappers emulation */
100 #define USE_UID16
101 #endif
103 //#include <linux/msdos_fs.h>
104 #define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct linux_dirent [2])
105 #define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct linux_dirent [2])
108 #undef _syscall0
109 #undef _syscall1
110 #undef _syscall2
111 #undef _syscall3
112 #undef _syscall4
113 #undef _syscall5
114 #undef _syscall6
116 #define _syscall0(type,name) \
117 static type name (void) \
119 return syscall(__NR_##name); \
122 #define _syscall1(type,name,type1,arg1) \
123 static type name (type1 arg1) \
125 return syscall(__NR_##name, arg1); \
128 #define _syscall2(type,name,type1,arg1,type2,arg2) \
129 static type name (type1 arg1,type2 arg2) \
131 return syscall(__NR_##name, arg1, arg2); \
134 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
135 static type name (type1 arg1,type2 arg2,type3 arg3) \
137 return syscall(__NR_##name, arg1, arg2, arg3); \
140 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
141 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4) \
143 return syscall(__NR_##name, arg1, arg2, arg3, arg4); \
146 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
147 type5,arg5) \
148 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
150 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5); \
154 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
155 type5,arg5,type6,arg6) \
156 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \
157 type6 arg6) \
159 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6); \
163 #define __NR_sys_uname __NR_uname
164 #define __NR_sys_faccessat __NR_faccessat
165 #define __NR_sys_fchmodat __NR_fchmodat
166 #define __NR_sys_fchownat __NR_fchownat
167 #define __NR_sys_fstatat64 __NR_fstatat64
168 #define __NR_sys_futimesat __NR_futimesat
169 #define __NR_sys_getcwd1 __NR_getcwd
170 #define __NR_sys_getdents __NR_getdents
171 #define __NR_sys_getdents64 __NR_getdents64
172 #define __NR_sys_getpriority __NR_getpriority
173 #define __NR_sys_linkat __NR_linkat
174 #define __NR_sys_mkdirat __NR_mkdirat
175 #define __NR_sys_mknodat __NR_mknodat
176 #define __NR_sys_newfstatat __NR_newfstatat
177 #define __NR_sys_openat __NR_openat
178 #define __NR_sys_readlinkat __NR_readlinkat
179 #define __NR_sys_renameat __NR_renameat
180 #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
181 #define __NR_sys_symlinkat __NR_symlinkat
182 #define __NR_sys_syslog __NR_syslog
183 #define __NR_sys_tgkill __NR_tgkill
184 #define __NR_sys_tkill __NR_tkill
185 #define __NR_sys_unlinkat __NR_unlinkat
186 #define __NR_sys_utimensat __NR_utimensat
187 #define __NR_sys_futex __NR_futex
188 #define __NR_sys_inotify_init __NR_inotify_init
189 #define __NR_sys_inotify_add_watch __NR_inotify_add_watch
190 #define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
192 #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
193 #define __NR__llseek __NR_lseek
194 #endif
196 #ifdef __NR_gettid
197 _syscall0(int, gettid)
198 #else
199 /* This is a replacement for the host gettid() and must return a host
200 errno. */
201 static int gettid(void) {
202 return -ENOSYS;
204 #endif
205 #if TARGET_ABI_BITS == 32
206 _syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
207 #endif
208 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
209 _syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
210 #endif
211 _syscall2(int, sys_getpriority, int, which, int, who);
212 #if defined(TARGET_NR__llseek) && !defined (__x86_64__)
213 _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo,
214 loff_t *, res, uint, wh);
215 #endif
216 _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
217 _syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
218 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
219 _syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
220 #endif
221 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
222 _syscall2(int,sys_tkill,int,tid,int,sig)
223 #endif
224 #ifdef __NR_exit_group
225 _syscall1(int,exit_group,int,error_code)
226 #endif
227 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
228 _syscall1(int,set_tid_address,int *,tidptr)
229 #endif
230 #if defined(USE_NPTL)
231 #if defined(TARGET_NR_futex) && defined(__NR_futex)
232 _syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
233 const struct timespec *,timeout,int *,uaddr2,int,val3)
234 #endif
235 #endif
237 static bitmask_transtbl fcntl_flags_tbl[] = {
238 { TARGET_O_ACCMODE, TARGET_O_WRONLY, O_ACCMODE, O_WRONLY, },
239 { TARGET_O_ACCMODE, TARGET_O_RDWR, O_ACCMODE, O_RDWR, },
240 { TARGET_O_CREAT, TARGET_O_CREAT, O_CREAT, O_CREAT, },
241 { TARGET_O_EXCL, TARGET_O_EXCL, O_EXCL, O_EXCL, },
242 { TARGET_O_NOCTTY, TARGET_O_NOCTTY, O_NOCTTY, O_NOCTTY, },
243 { TARGET_O_TRUNC, TARGET_O_TRUNC, O_TRUNC, O_TRUNC, },
244 { TARGET_O_APPEND, TARGET_O_APPEND, O_APPEND, O_APPEND, },
245 { TARGET_O_NONBLOCK, TARGET_O_NONBLOCK, O_NONBLOCK, O_NONBLOCK, },
246 { TARGET_O_SYNC, TARGET_O_SYNC, O_SYNC, O_SYNC, },
247 { TARGET_FASYNC, TARGET_FASYNC, FASYNC, FASYNC, },
248 { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
249 { TARGET_O_NOFOLLOW, TARGET_O_NOFOLLOW, O_NOFOLLOW, O_NOFOLLOW, },
250 { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
251 #if defined(O_DIRECT)
252 { TARGET_O_DIRECT, TARGET_O_DIRECT, O_DIRECT, O_DIRECT, },
253 #endif
254 { 0, 0, 0, 0 }
257 #define COPY_UTSNAME_FIELD(dest, src) \
258 do { \
259 /* __NEW_UTS_LEN doesn't include terminating null */ \
260 (void) strncpy((dest), (src), __NEW_UTS_LEN); \
261 (dest)[__NEW_UTS_LEN] = '\0'; \
262 } while (0)
264 static int sys_uname(struct new_utsname *buf)
266 struct utsname uts_buf;
268 if (uname(&uts_buf) < 0)
269 return (-1);
272 * Just in case these have some differences, we
273 * translate utsname to new_utsname (which is the
274 * struct linux kernel uses).
277 bzero(buf, sizeof (*buf));
278 COPY_UTSNAME_FIELD(buf->sysname, uts_buf.sysname);
279 COPY_UTSNAME_FIELD(buf->nodename, uts_buf.nodename);
280 COPY_UTSNAME_FIELD(buf->release, uts_buf.release);
281 COPY_UTSNAME_FIELD(buf->version, uts_buf.version);
282 COPY_UTSNAME_FIELD(buf->machine, uts_buf.machine);
283 #ifdef _GNU_SOURCE
284 COPY_UTSNAME_FIELD(buf->domainname, uts_buf.domainname);
285 #endif
286 return (0);
288 #undef COPY_UTSNAME_FIELD
291 static int sys_getcwd1(char *buf, size_t size)
293 if (getcwd(buf, size) == NULL) {
294 /* getcwd() sets errno */
295 return (-1);
297 return strlen(buf)+1;
300 #ifdef CONFIG_ATFILE
302 * Host system seems to have atfile syscall stubs available. We
303 * now enable them one by one as specified by target syscall_nr.h.
306 #ifdef TARGET_NR_faccessat
307 static int sys_faccessat(int dirfd, const char *pathname, int mode)
309 return (faccessat(dirfd, pathname, mode, 0));
311 #endif
312 #ifdef TARGET_NR_fchmodat
313 static int sys_fchmodat(int dirfd, const char *pathname, mode_t mode)
315 return (fchmodat(dirfd, pathname, mode, 0));
317 #endif
318 #if defined(TARGET_NR_fchownat) && defined(USE_UID16)
319 static int sys_fchownat(int dirfd, const char *pathname, uid_t owner,
320 gid_t group, int flags)
322 return (fchownat(dirfd, pathname, owner, group, flags));
324 #endif
325 #ifdef __NR_fstatat64
326 static int sys_fstatat64(int dirfd, const char *pathname, struct stat *buf,
327 int flags)
329 return (fstatat(dirfd, pathname, buf, flags));
331 #endif
332 #ifdef __NR_newfstatat
333 static int sys_newfstatat(int dirfd, const char *pathname, struct stat *buf,
334 int flags)
336 return (fstatat(dirfd, pathname, buf, flags));
338 #endif
339 #ifdef TARGET_NR_futimesat
340 static int sys_futimesat(int dirfd, const char *pathname,
341 const struct timeval times[2])
343 return (futimesat(dirfd, pathname, times));
345 #endif
346 #ifdef TARGET_NR_linkat
347 static int sys_linkat(int olddirfd, const char *oldpath,
348 int newdirfd, const char *newpath, int flags)
350 return (linkat(olddirfd, oldpath, newdirfd, newpath, flags));
352 #endif
353 #ifdef TARGET_NR_mkdirat
354 static int sys_mkdirat(int dirfd, const char *pathname, mode_t mode)
356 return (mkdirat(dirfd, pathname, mode));
358 #endif
359 #ifdef TARGET_NR_mknodat
360 static int sys_mknodat(int dirfd, const char *pathname, mode_t mode,
361 dev_t dev)
363 return (mknodat(dirfd, pathname, mode, dev));
365 #endif
366 #ifdef TARGET_NR_openat
367 static int sys_openat(int dirfd, const char *pathname, int flags, ...)
370 * open(2) has extra parameter 'mode' when called with
371 * flag O_CREAT.
373 if ((flags & O_CREAT) != 0) {
374 va_list ap;
375 mode_t mode;
378 * Get the 'mode' parameter and translate it to
379 * host bits.
381 va_start(ap, flags);
382 mode = va_arg(ap, mode_t);
383 mode = target_to_host_bitmask(mode, fcntl_flags_tbl);
384 va_end(ap);
386 return (openat(dirfd, pathname, flags, mode));
388 return (openat(dirfd, pathname, flags));
390 #endif
391 #ifdef TARGET_NR_readlinkat
392 static int sys_readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz)
394 return (readlinkat(dirfd, pathname, buf, bufsiz));
396 #endif
397 #ifdef TARGET_NR_renameat
398 static int sys_renameat(int olddirfd, const char *oldpath,
399 int newdirfd, const char *newpath)
401 return (renameat(olddirfd, oldpath, newdirfd, newpath));
403 #endif
404 #ifdef TARGET_NR_symlinkat
405 static int sys_symlinkat(const char *oldpath, int newdirfd, const char *newpath)
407 return (symlinkat(oldpath, newdirfd, newpath));
409 #endif
410 #ifdef TARGET_NR_unlinkat
411 static int sys_unlinkat(int dirfd, const char *pathname, int flags)
413 return (unlinkat(dirfd, pathname, flags));
415 #endif
416 #ifdef TARGET_NR_utimensat
417 static int sys_utimensat(int dirfd, const char *pathname,
418 const struct timespec times[2], int flags)
420 return (utimensat(dirfd, pathname, times, flags));
422 #endif
423 #else /* !CONFIG_ATFILE */
426 * Try direct syscalls instead
428 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
429 _syscall3(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode)
430 #endif
431 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
432 _syscall3(int,sys_fchmodat,int,dirfd,const char *,pathname, mode_t,mode)
433 #endif
434 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) && defined(USE_UID16)
435 _syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
436 uid_t,owner,gid_t,group,int,flags)
437 #endif
438 #if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
439 defined(__NR_fstatat64)
440 _syscall4(int,sys_fstatat64,int,dirfd,const char *,pathname,
441 struct stat *,buf,int,flags)
442 #endif
443 #if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
444 _syscall3(int,sys_futimesat,int,dirfd,const char *,pathname,
445 const struct timeval *,times)
446 #endif
447 #if (defined(TARGET_NR_newfstatat) || defined(TARGET_NR_fstatat64) ) && \
448 defined(__NR_newfstatat)
449 _syscall4(int,sys_newfstatat,int,dirfd,const char *,pathname,
450 struct stat *,buf,int,flags)
451 #endif
452 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
453 _syscall5(int,sys_linkat,int,olddirfd,const char *,oldpath,
454 int,newdirfd,const char *,newpath,int,flags)
455 #endif
456 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
457 _syscall3(int,sys_mkdirat,int,dirfd,const char *,pathname,mode_t,mode)
458 #endif
459 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
460 _syscall4(int,sys_mknodat,int,dirfd,const char *,pathname,
461 mode_t,mode,dev_t,dev)
462 #endif
463 #if defined(TARGET_NR_openat) && defined(__NR_openat)
464 _syscall4(int,sys_openat,int,dirfd,const char *,pathname,int,flags,mode_t,mode)
465 #endif
466 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
467 _syscall4(int,sys_readlinkat,int,dirfd,const char *,pathname,
468 char *,buf,size_t,bufsize)
469 #endif
470 #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
471 _syscall4(int,sys_renameat,int,olddirfd,const char *,oldpath,
472 int,newdirfd,const char *,newpath)
473 #endif
474 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
475 _syscall3(int,sys_symlinkat,const char *,oldpath,
476 int,newdirfd,const char *,newpath)
477 #endif
478 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
479 _syscall3(int,sys_unlinkat,int,dirfd,const char *,pathname,int,flags)
480 #endif
481 #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
482 _syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
483 const struct timespec *,tsp,int,flags)
484 #endif
486 #endif /* CONFIG_ATFILE */
488 #ifdef CONFIG_INOTIFY
489 #include <sys/inotify.h>
491 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
492 static int sys_inotify_init(void)
494 return (inotify_init());
496 #endif
497 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
498 static int sys_inotify_add_watch(int fd,const char *pathname, int32_t mask)
500 return (inotify_add_watch(fd, pathname, mask));
502 #endif
503 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
504 static int sys_inotify_rm_watch(int fd, int32_t wd)
506 return (inotify_rm_watch(fd, wd));
508 #endif
509 #else
510 /* Userspace can usually survive runtime without inotify */
511 #undef TARGET_NR_inotify_init
512 #undef TARGET_NR_inotify_add_watch
513 #undef TARGET_NR_inotify_rm_watch
514 #endif /* CONFIG_INOTIFY */
517 extern int personality(int);
518 extern int flock(int, int);
519 extern int setfsuid(int);
520 extern int setfsgid(int);
521 extern int setgroups(int, gid_t *);
523 #define ERRNO_TABLE_SIZE 1200
525 /* target_to_host_errno_table[] is initialized from
526 * host_to_target_errno_table[] in syscall_init(). */
527 static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
531 * This list is the union of errno values overridden in asm-<arch>/errno.h
532 * minus the errnos that are not actually generic to all archs.
534 static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
535 [EIDRM] = TARGET_EIDRM,
536 [ECHRNG] = TARGET_ECHRNG,
537 [EL2NSYNC] = TARGET_EL2NSYNC,
538 [EL3HLT] = TARGET_EL3HLT,
539 [EL3RST] = TARGET_EL3RST,
540 [ELNRNG] = TARGET_ELNRNG,
541 [EUNATCH] = TARGET_EUNATCH,
542 [ENOCSI] = TARGET_ENOCSI,
543 [EL2HLT] = TARGET_EL2HLT,
544 [EDEADLK] = TARGET_EDEADLK,
545 [ENOLCK] = TARGET_ENOLCK,
546 [EBADE] = TARGET_EBADE,
547 [EBADR] = TARGET_EBADR,
548 [EXFULL] = TARGET_EXFULL,
549 [ENOANO] = TARGET_ENOANO,
550 [EBADRQC] = TARGET_EBADRQC,
551 [EBADSLT] = TARGET_EBADSLT,
552 [EBFONT] = TARGET_EBFONT,
553 [ENOSTR] = TARGET_ENOSTR,
554 [ENODATA] = TARGET_ENODATA,
555 [ETIME] = TARGET_ETIME,
556 [ENOSR] = TARGET_ENOSR,
557 [ENONET] = TARGET_ENONET,
558 [ENOPKG] = TARGET_ENOPKG,
559 [EREMOTE] = TARGET_EREMOTE,
560 [ENOLINK] = TARGET_ENOLINK,
561 [EADV] = TARGET_EADV,
562 [ESRMNT] = TARGET_ESRMNT,
563 [ECOMM] = TARGET_ECOMM,
564 [EPROTO] = TARGET_EPROTO,
565 [EDOTDOT] = TARGET_EDOTDOT,
566 [EMULTIHOP] = TARGET_EMULTIHOP,
567 [EBADMSG] = TARGET_EBADMSG,
568 [ENAMETOOLONG] = TARGET_ENAMETOOLONG,
569 [EOVERFLOW] = TARGET_EOVERFLOW,
570 [ENOTUNIQ] = TARGET_ENOTUNIQ,
571 [EBADFD] = TARGET_EBADFD,
572 [EREMCHG] = TARGET_EREMCHG,
573 [ELIBACC] = TARGET_ELIBACC,
574 [ELIBBAD] = TARGET_ELIBBAD,
575 [ELIBSCN] = TARGET_ELIBSCN,
576 [ELIBMAX] = TARGET_ELIBMAX,
577 [ELIBEXEC] = TARGET_ELIBEXEC,
578 [EILSEQ] = TARGET_EILSEQ,
579 [ENOSYS] = TARGET_ENOSYS,
580 [ELOOP] = TARGET_ELOOP,
581 [ERESTART] = TARGET_ERESTART,
582 [ESTRPIPE] = TARGET_ESTRPIPE,
583 [ENOTEMPTY] = TARGET_ENOTEMPTY,
584 [EUSERS] = TARGET_EUSERS,
585 [ENOTSOCK] = TARGET_ENOTSOCK,
586 [EDESTADDRREQ] = TARGET_EDESTADDRREQ,
587 [EMSGSIZE] = TARGET_EMSGSIZE,
588 [EPROTOTYPE] = TARGET_EPROTOTYPE,
589 [ENOPROTOOPT] = TARGET_ENOPROTOOPT,
590 [EPROTONOSUPPORT] = TARGET_EPROTONOSUPPORT,
591 [ESOCKTNOSUPPORT] = TARGET_ESOCKTNOSUPPORT,
592 [EOPNOTSUPP] = TARGET_EOPNOTSUPP,
593 [EPFNOSUPPORT] = TARGET_EPFNOSUPPORT,
594 [EAFNOSUPPORT] = TARGET_EAFNOSUPPORT,
595 [EADDRINUSE] = TARGET_EADDRINUSE,
596 [EADDRNOTAVAIL] = TARGET_EADDRNOTAVAIL,
597 [ENETDOWN] = TARGET_ENETDOWN,
598 [ENETUNREACH] = TARGET_ENETUNREACH,
599 [ENETRESET] = TARGET_ENETRESET,
600 [ECONNABORTED] = TARGET_ECONNABORTED,
601 [ECONNRESET] = TARGET_ECONNRESET,
602 [ENOBUFS] = TARGET_ENOBUFS,
603 [EISCONN] = TARGET_EISCONN,
604 [ENOTCONN] = TARGET_ENOTCONN,
605 [EUCLEAN] = TARGET_EUCLEAN,
606 [ENOTNAM] = TARGET_ENOTNAM,
607 [ENAVAIL] = TARGET_ENAVAIL,
608 [EISNAM] = TARGET_EISNAM,
609 [EREMOTEIO] = TARGET_EREMOTEIO,
610 [ESHUTDOWN] = TARGET_ESHUTDOWN,
611 [ETOOMANYREFS] = TARGET_ETOOMANYREFS,
612 [ETIMEDOUT] = TARGET_ETIMEDOUT,
613 [ECONNREFUSED] = TARGET_ECONNREFUSED,
614 [EHOSTDOWN] = TARGET_EHOSTDOWN,
615 [EHOSTUNREACH] = TARGET_EHOSTUNREACH,
616 [EALREADY] = TARGET_EALREADY,
617 [EINPROGRESS] = TARGET_EINPROGRESS,
618 [ESTALE] = TARGET_ESTALE,
619 [ECANCELED] = TARGET_ECANCELED,
620 [ENOMEDIUM] = TARGET_ENOMEDIUM,
621 [EMEDIUMTYPE] = TARGET_EMEDIUMTYPE,
622 #ifdef ENOKEY
623 [ENOKEY] = TARGET_ENOKEY,
624 #endif
625 #ifdef EKEYEXPIRED
626 [EKEYEXPIRED] = TARGET_EKEYEXPIRED,
627 #endif
628 #ifdef EKEYREVOKED
629 [EKEYREVOKED] = TARGET_EKEYREVOKED,
630 #endif
631 #ifdef EKEYREJECTED
632 [EKEYREJECTED] = TARGET_EKEYREJECTED,
633 #endif
634 #ifdef EOWNERDEAD
635 [EOWNERDEAD] = TARGET_EOWNERDEAD,
636 #endif
637 #ifdef ENOTRECOVERABLE
638 [ENOTRECOVERABLE] = TARGET_ENOTRECOVERABLE,
639 #endif
642 static inline int host_to_target_errno(int err)
644 if(host_to_target_errno_table[err])
645 return host_to_target_errno_table[err];
646 return err;
649 static inline int target_to_host_errno(int err)
651 if (target_to_host_errno_table[err])
652 return target_to_host_errno_table[err];
653 return err;
656 static inline abi_long get_errno(abi_long ret)
658 if (ret == -1)
659 return -host_to_target_errno(errno);
660 else
661 return ret;
664 static inline int is_error(abi_long ret)
666 return (abi_ulong)ret >= (abi_ulong)(-4096);
669 char *target_strerror(int err)
671 return strerror(target_to_host_errno(err));
674 static abi_ulong target_brk;
675 static abi_ulong target_original_brk;
677 void target_set_brk(abi_ulong new_brk)
679 target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
682 /* do_brk() must return target values and target errnos. */
683 abi_long do_brk(abi_ulong new_brk)
685 abi_ulong brk_page;
686 abi_long mapped_addr;
687 int new_alloc_size;
689 if (!new_brk)
690 return target_brk;
691 if (new_brk < target_original_brk)
692 return target_brk;
694 brk_page = HOST_PAGE_ALIGN(target_brk);
696 /* If the new brk is less than this, set it and we're done... */
697 if (new_brk < brk_page) {
698 target_brk = new_brk;
699 return target_brk;
702 /* We need to allocate more memory after the brk... */
703 new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
704 mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
705 PROT_READ|PROT_WRITE,
706 MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
708 if (!is_error(mapped_addr))
709 target_brk = new_brk;
711 return target_brk;
714 static inline abi_long copy_from_user_fdset(fd_set *fds,
715 abi_ulong target_fds_addr,
716 int n)
718 int i, nw, j, k;
719 abi_ulong b, *target_fds;
721 nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
722 if (!(target_fds = lock_user(VERIFY_READ,
723 target_fds_addr,
724 sizeof(abi_ulong) * nw,
725 1)))
726 return -TARGET_EFAULT;
728 FD_ZERO(fds);
729 k = 0;
730 for (i = 0; i < nw; i++) {
731 /* grab the abi_ulong */
732 __get_user(b, &target_fds[i]);
733 for (j = 0; j < TARGET_ABI_BITS; j++) {
734 /* check the bit inside the abi_ulong */
735 if ((b >> j) & 1)
736 FD_SET(k, fds);
737 k++;
741 unlock_user(target_fds, target_fds_addr, 0);
743 return 0;
746 static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
747 const fd_set *fds,
748 int n)
750 int i, nw, j, k;
751 abi_long v;
752 abi_ulong *target_fds;
754 nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
755 if (!(target_fds = lock_user(VERIFY_WRITE,
756 target_fds_addr,
757 sizeof(abi_ulong) * nw,
758 0)))
759 return -TARGET_EFAULT;
761 k = 0;
762 for (i = 0; i < nw; i++) {
763 v = 0;
764 for (j = 0; j < TARGET_ABI_BITS; j++) {
765 v |= ((FD_ISSET(k, fds) != 0) << j);
766 k++;
768 __put_user(v, &target_fds[i]);
771 unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
773 return 0;
776 #if defined(__alpha__)
777 #define HOST_HZ 1024
778 #else
779 #define HOST_HZ 100
780 #endif
782 static inline abi_long host_to_target_clock_t(long ticks)
784 #if HOST_HZ == TARGET_HZ
785 return ticks;
786 #else
787 return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
788 #endif
791 static inline abi_long host_to_target_rusage(abi_ulong target_addr,
792 const struct rusage *rusage)
794 struct target_rusage *target_rusage;
796 if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
797 return -TARGET_EFAULT;
798 target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
799 target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
800 target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
801 target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec);
802 target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss);
803 target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss);
804 target_rusage->ru_idrss = tswapl(rusage->ru_idrss);
805 target_rusage->ru_isrss = tswapl(rusage->ru_isrss);
806 target_rusage->ru_minflt = tswapl(rusage->ru_minflt);
807 target_rusage->ru_majflt = tswapl(rusage->ru_majflt);
808 target_rusage->ru_nswap = tswapl(rusage->ru_nswap);
809 target_rusage->ru_inblock = tswapl(rusage->ru_inblock);
810 target_rusage->ru_oublock = tswapl(rusage->ru_oublock);
811 target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd);
812 target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv);
813 target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);
814 target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
815 target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
816 unlock_user_struct(target_rusage, target_addr, 1);
818 return 0;
821 static inline abi_long copy_from_user_timeval(struct timeval *tv,
822 abi_ulong target_tv_addr)
824 struct target_timeval *target_tv;
826 if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
827 return -TARGET_EFAULT;
829 __get_user(tv->tv_sec, &target_tv->tv_sec);
830 __get_user(tv->tv_usec, &target_tv->tv_usec);
832 unlock_user_struct(target_tv, target_tv_addr, 0);
834 return 0;
837 static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
838 const struct timeval *tv)
840 struct target_timeval *target_tv;
842 if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
843 return -TARGET_EFAULT;
845 __put_user(tv->tv_sec, &target_tv->tv_sec);
846 __put_user(tv->tv_usec, &target_tv->tv_usec);
848 unlock_user_struct(target_tv, target_tv_addr, 1);
850 return 0;
853 static inline abi_long copy_from_user_mq_attr(struct mq_attr *attr,
854 abi_ulong target_mq_attr_addr)
856 struct target_mq_attr *target_mq_attr;
858 if (!lock_user_struct(VERIFY_READ, target_mq_attr,
859 target_mq_attr_addr, 1))
860 return -TARGET_EFAULT;
862 __get_user(attr->mq_flags, &target_mq_attr->mq_flags);
863 __get_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
864 __get_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
865 __get_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
867 unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0);
869 return 0;
872 static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr,
873 const struct mq_attr *attr)
875 struct target_mq_attr *target_mq_attr;
877 if (!lock_user_struct(VERIFY_WRITE, target_mq_attr,
878 target_mq_attr_addr, 0))
879 return -TARGET_EFAULT;
881 __put_user(attr->mq_flags, &target_mq_attr->mq_flags);
882 __put_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
883 __put_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
884 __put_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
886 unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1);
888 return 0;
891 /* do_select() must return target values and target errnos. */
892 static abi_long do_select(int n,
893 abi_ulong rfd_addr, abi_ulong wfd_addr,
894 abi_ulong efd_addr, abi_ulong target_tv_addr)
896 fd_set rfds, wfds, efds;
897 fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
898 struct timeval tv, *tv_ptr;
899 abi_long ret;
901 if (rfd_addr) {
902 if (copy_from_user_fdset(&rfds, rfd_addr, n))
903 return -TARGET_EFAULT;
904 rfds_ptr = &rfds;
905 } else {
906 rfds_ptr = NULL;
908 if (wfd_addr) {
909 if (copy_from_user_fdset(&wfds, wfd_addr, n))
910 return -TARGET_EFAULT;
911 wfds_ptr = &wfds;
912 } else {
913 wfds_ptr = NULL;
915 if (efd_addr) {
916 if (copy_from_user_fdset(&efds, efd_addr, n))
917 return -TARGET_EFAULT;
918 efds_ptr = &efds;
919 } else {
920 efds_ptr = NULL;
923 if (target_tv_addr) {
924 if (copy_from_user_timeval(&tv, target_tv_addr))
925 return -TARGET_EFAULT;
926 tv_ptr = &tv;
927 } else {
928 tv_ptr = NULL;
931 ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
933 if (!is_error(ret)) {
934 if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
935 return -TARGET_EFAULT;
936 if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
937 return -TARGET_EFAULT;
938 if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
939 return -TARGET_EFAULT;
941 if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
942 return -TARGET_EFAULT;
945 return ret;
948 static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
949 abi_ulong target_addr,
950 socklen_t len)
952 const socklen_t unix_maxlen = sizeof (struct sockaddr_un);
953 sa_family_t sa_family;
954 struct target_sockaddr *target_saddr;
956 target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
957 if (!target_saddr)
958 return -TARGET_EFAULT;
960 sa_family = tswap16(target_saddr->sa_family);
962 /* Oops. The caller might send a incomplete sun_path; sun_path
963 * must be terminated by \0 (see the manual page), but
964 * unfortunately it is quite common to specify sockaddr_un
965 * length as "strlen(x->sun_path)" while it should be
966 * "strlen(...) + 1". We'll fix that here if needed.
967 * Linux kernel has a similar feature.
970 if (sa_family == AF_UNIX) {
971 if (len < unix_maxlen && len > 0) {
972 char *cp = (char*)target_saddr;
974 if ( cp[len-1] && !cp[len] )
975 len++;
977 if (len > unix_maxlen)
978 len = unix_maxlen;
981 memcpy(addr, target_saddr, len);
982 addr->sa_family = sa_family;
983 unlock_user(target_saddr, target_addr, 0);
985 return 0;
988 static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
989 struct sockaddr *addr,
990 socklen_t len)
992 struct target_sockaddr *target_saddr;
994 target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
995 if (!target_saddr)
996 return -TARGET_EFAULT;
997 memcpy(target_saddr, addr, len);
998 target_saddr->sa_family = tswap16(addr->sa_family);
999 unlock_user(target_saddr, target_addr, len);
1001 return 0;
1004 /* ??? Should this also swap msgh->name? */
1005 static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
1006 struct target_msghdr *target_msgh)
1008 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1009 abi_long msg_controllen;
1010 abi_ulong target_cmsg_addr;
1011 struct target_cmsghdr *target_cmsg;
1012 socklen_t space = 0;
1014 msg_controllen = tswapl(target_msgh->msg_controllen);
1015 if (msg_controllen < sizeof (struct target_cmsghdr))
1016 goto the_end;
1017 target_cmsg_addr = tswapl(target_msgh->msg_control);
1018 target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
1019 if (!target_cmsg)
1020 return -TARGET_EFAULT;
1022 while (cmsg && target_cmsg) {
1023 void *data = CMSG_DATA(cmsg);
1024 void *target_data = TARGET_CMSG_DATA(target_cmsg);
1026 int len = tswapl(target_cmsg->cmsg_len)
1027 - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
1029 space += CMSG_SPACE(len);
1030 if (space > msgh->msg_controllen) {
1031 space -= CMSG_SPACE(len);
1032 gemu_log("Host cmsg overflow\n");
1033 break;
1036 cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
1037 cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
1038 cmsg->cmsg_len = CMSG_LEN(len);
1040 if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1041 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1042 memcpy(data, target_data, len);
1043 } else {
1044 int *fd = (int *)data;
1045 int *target_fd = (int *)target_data;
1046 int i, numfds = len / sizeof(int);
1048 for (i = 0; i < numfds; i++)
1049 fd[i] = tswap32(target_fd[i]);
1052 cmsg = CMSG_NXTHDR(msgh, cmsg);
1053 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1055 unlock_user(target_cmsg, target_cmsg_addr, 0);
1056 the_end:
1057 msgh->msg_controllen = space;
1058 return 0;
1061 /* ??? Should this also swap msgh->name? */
1062 static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
1063 struct msghdr *msgh)
1065 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1066 abi_long msg_controllen;
1067 abi_ulong target_cmsg_addr;
1068 struct target_cmsghdr *target_cmsg;
1069 socklen_t space = 0;
1071 msg_controllen = tswapl(target_msgh->msg_controllen);
1072 if (msg_controllen < sizeof (struct target_cmsghdr))
1073 goto the_end;
1074 target_cmsg_addr = tswapl(target_msgh->msg_control);
1075 target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
1076 if (!target_cmsg)
1077 return -TARGET_EFAULT;
1079 while (cmsg && target_cmsg) {
1080 void *data = CMSG_DATA(cmsg);
1081 void *target_data = TARGET_CMSG_DATA(target_cmsg);
1083 int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
1085 space += TARGET_CMSG_SPACE(len);
1086 if (space > msg_controllen) {
1087 space -= TARGET_CMSG_SPACE(len);
1088 gemu_log("Target cmsg overflow\n");
1089 break;
1092 target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
1093 target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
1094 target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
1096 if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1097 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1098 memcpy(target_data, data, len);
1099 } else {
1100 int *fd = (int *)data;
1101 int *target_fd = (int *)target_data;
1102 int i, numfds = len / sizeof(int);
1104 for (i = 0; i < numfds; i++)
1105 target_fd[i] = tswap32(fd[i]);
1108 cmsg = CMSG_NXTHDR(msgh, cmsg);
1109 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1111 unlock_user(target_cmsg, target_cmsg_addr, space);
1112 the_end:
1113 target_msgh->msg_controllen = tswapl(space);
1114 return 0;
1117 /* do_setsockopt() Must return target values and target errnos. */
1118 static abi_long do_setsockopt(int sockfd, int level, int optname,
1119 abi_ulong optval_addr, socklen_t optlen)
1121 abi_long ret;
1122 int val;
1124 switch(level) {
1125 case SOL_TCP:
1126 /* TCP options all take an 'int' value. */
1127 if (optlen < sizeof(uint32_t))
1128 return -TARGET_EINVAL;
1130 if (get_user_u32(val, optval_addr))
1131 return -TARGET_EFAULT;
1132 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1133 break;
1134 case SOL_IP:
1135 switch(optname) {
1136 case IP_TOS:
1137 case IP_TTL:
1138 case IP_HDRINCL:
1139 case IP_ROUTER_ALERT:
1140 case IP_RECVOPTS:
1141 case IP_RETOPTS:
1142 case IP_PKTINFO:
1143 case IP_MTU_DISCOVER:
1144 case IP_RECVERR:
1145 case IP_RECVTOS:
1146 #ifdef IP_FREEBIND
1147 case IP_FREEBIND:
1148 #endif
1149 case IP_MULTICAST_TTL:
1150 case IP_MULTICAST_LOOP:
1151 val = 0;
1152 if (optlen >= sizeof(uint32_t)) {
1153 if (get_user_u32(val, optval_addr))
1154 return -TARGET_EFAULT;
1155 } else if (optlen >= 1) {
1156 if (get_user_u8(val, optval_addr))
1157 return -TARGET_EFAULT;
1159 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1160 break;
1161 default:
1162 goto unimplemented;
1164 break;
1165 case TARGET_SOL_SOCKET:
1166 switch (optname) {
1167 /* Options with 'int' argument. */
1168 case TARGET_SO_DEBUG:
1169 optname = SO_DEBUG;
1170 break;
1171 case TARGET_SO_REUSEADDR:
1172 optname = SO_REUSEADDR;
1173 break;
1174 case TARGET_SO_TYPE:
1175 optname = SO_TYPE;
1176 break;
1177 case TARGET_SO_ERROR:
1178 optname = SO_ERROR;
1179 break;
1180 case TARGET_SO_DONTROUTE:
1181 optname = SO_DONTROUTE;
1182 break;
1183 case TARGET_SO_BROADCAST:
1184 optname = SO_BROADCAST;
1185 break;
1186 case TARGET_SO_SNDBUF:
1187 optname = SO_SNDBUF;
1188 break;
1189 case TARGET_SO_RCVBUF:
1190 optname = SO_RCVBUF;
1191 break;
1192 case TARGET_SO_KEEPALIVE:
1193 optname = SO_KEEPALIVE;
1194 break;
1195 case TARGET_SO_OOBINLINE:
1196 optname = SO_OOBINLINE;
1197 break;
1198 case TARGET_SO_NO_CHECK:
1199 optname = SO_NO_CHECK;
1200 break;
1201 case TARGET_SO_PRIORITY:
1202 optname = SO_PRIORITY;
1203 break;
1204 #ifdef SO_BSDCOMPAT
1205 case TARGET_SO_BSDCOMPAT:
1206 optname = SO_BSDCOMPAT;
1207 break;
1208 #endif
1209 case TARGET_SO_PASSCRED:
1210 optname = SO_PASSCRED;
1211 break;
1212 case TARGET_SO_TIMESTAMP:
1213 optname = SO_TIMESTAMP;
1214 break;
1215 case TARGET_SO_RCVLOWAT:
1216 optname = SO_RCVLOWAT;
1217 break;
1218 case TARGET_SO_RCVTIMEO:
1219 optname = SO_RCVTIMEO;
1220 break;
1221 case TARGET_SO_SNDTIMEO:
1222 optname = SO_SNDTIMEO;
1223 break;
1224 break;
1225 default:
1226 goto unimplemented;
1228 if (optlen < sizeof(uint32_t))
1229 return -TARGET_EINVAL;
1231 if (get_user_u32(val, optval_addr))
1232 return -TARGET_EFAULT;
1233 ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
1234 break;
1235 default:
1236 unimplemented:
1237 gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
1238 ret = -TARGET_ENOPROTOOPT;
1240 return ret;
1243 /* do_getsockopt() Must return target values and target errnos. */
1244 static abi_long do_getsockopt(int sockfd, int level, int optname,
1245 abi_ulong optval_addr, abi_ulong optlen)
1247 abi_long ret;
1248 int len, val;
1249 socklen_t lv;
1251 switch(level) {
1252 case TARGET_SOL_SOCKET:
1253 level = SOL_SOCKET;
1254 switch (optname) {
1255 case TARGET_SO_LINGER:
1256 case TARGET_SO_RCVTIMEO:
1257 case TARGET_SO_SNDTIMEO:
1258 case TARGET_SO_PEERCRED:
1259 case TARGET_SO_PEERNAME:
1260 /* These don't just return a single integer */
1261 goto unimplemented;
1262 default:
1263 goto int_case;
1265 break;
1266 case SOL_TCP:
1267 /* TCP options all take an 'int' value. */
1268 int_case:
1269 if (get_user_u32(len, optlen))
1270 return -TARGET_EFAULT;
1271 if (len < 0)
1272 return -TARGET_EINVAL;
1273 lv = sizeof(int);
1274 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1275 if (ret < 0)
1276 return ret;
1277 val = tswap32(val);
1278 if (len > lv)
1279 len = lv;
1280 if (len == 4) {
1281 if (put_user_u32(val, optval_addr))
1282 return -TARGET_EFAULT;
1283 } else {
1284 if (put_user_u8(val, optval_addr))
1285 return -TARGET_EFAULT;
1287 if (put_user_u32(len, optlen))
1288 return -TARGET_EFAULT;
1289 break;
1290 case SOL_IP:
1291 switch(optname) {
1292 case IP_TOS:
1293 case IP_TTL:
1294 case IP_HDRINCL:
1295 case IP_ROUTER_ALERT:
1296 case IP_RECVOPTS:
1297 case IP_RETOPTS:
1298 case IP_PKTINFO:
1299 case IP_MTU_DISCOVER:
1300 case IP_RECVERR:
1301 case IP_RECVTOS:
1302 #ifdef IP_FREEBIND
1303 case IP_FREEBIND:
1304 #endif
1305 case IP_MULTICAST_TTL:
1306 case IP_MULTICAST_LOOP:
1307 if (get_user_u32(len, optlen))
1308 return -TARGET_EFAULT;
1309 if (len < 0)
1310 return -TARGET_EINVAL;
1311 lv = sizeof(int);
1312 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1313 if (ret < 0)
1314 return ret;
1315 if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
1316 len = 1;
1317 if (put_user_u32(len, optlen)
1318 || put_user_u8(val, optval_addr))
1319 return -TARGET_EFAULT;
1320 } else {
1321 if (len > sizeof(int))
1322 len = sizeof(int);
1323 if (put_user_u32(len, optlen)
1324 || put_user_u32(val, optval_addr))
1325 return -TARGET_EFAULT;
1327 break;
1328 default:
1329 ret = -TARGET_ENOPROTOOPT;
1330 break;
1332 break;
1333 default:
1334 unimplemented:
1335 gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1336 level, optname);
1337 ret = -TARGET_EOPNOTSUPP;
1338 break;
1340 return ret;
1343 /* FIXME
1344 * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1345 * other lock functions have a return code of 0 for failure.
1347 static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1348 int count, int copy)
1350 struct target_iovec *target_vec;
1351 abi_ulong base;
1352 int i;
1354 target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1355 if (!target_vec)
1356 return -TARGET_EFAULT;
1357 for(i = 0;i < count; i++) {
1358 base = tswapl(target_vec[i].iov_base);
1359 vec[i].iov_len = tswapl(target_vec[i].iov_len);
1360 if (vec[i].iov_len != 0) {
1361 vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
1362 /* Don't check lock_user return value. We must call writev even
1363 if a element has invalid base address. */
1364 } else {
1365 /* zero length pointer is ignored */
1366 vec[i].iov_base = NULL;
1369 unlock_user (target_vec, target_addr, 0);
1370 return 0;
1373 static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1374 int count, int copy)
1376 struct target_iovec *target_vec;
1377 abi_ulong base;
1378 int i;
1380 target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1381 if (!target_vec)
1382 return -TARGET_EFAULT;
1383 for(i = 0;i < count; i++) {
1384 if (target_vec[i].iov_base) {
1385 base = tswapl(target_vec[i].iov_base);
1386 unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1389 unlock_user (target_vec, target_addr, 0);
1391 return 0;
1394 /* do_socket() Must return target values and target errnos. */
1395 static abi_long do_socket(int domain, int type, int protocol)
1397 #if defined(TARGET_MIPS)
1398 switch(type) {
1399 case TARGET_SOCK_DGRAM:
1400 type = SOCK_DGRAM;
1401 break;
1402 case TARGET_SOCK_STREAM:
1403 type = SOCK_STREAM;
1404 break;
1405 case TARGET_SOCK_RAW:
1406 type = SOCK_RAW;
1407 break;
1408 case TARGET_SOCK_RDM:
1409 type = SOCK_RDM;
1410 break;
1411 case TARGET_SOCK_SEQPACKET:
1412 type = SOCK_SEQPACKET;
1413 break;
1414 case TARGET_SOCK_PACKET:
1415 type = SOCK_PACKET;
1416 break;
1418 #endif
1419 if (domain == PF_NETLINK)
1420 return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1421 return get_errno(socket(domain, type, protocol));
1424 /* do_bind() Must return target values and target errnos. */
1425 static abi_long do_bind(int sockfd, abi_ulong target_addr,
1426 socklen_t addrlen)
1428 void *addr;
1430 if (addrlen < 0)
1431 return -TARGET_EINVAL;
1433 addr = alloca(addrlen+1);
1435 target_to_host_sockaddr(addr, target_addr, addrlen);
1436 return get_errno(bind(sockfd, addr, addrlen));
1439 /* do_connect() Must return target values and target errnos. */
1440 static abi_long do_connect(int sockfd, abi_ulong target_addr,
1441 socklen_t addrlen)
1443 void *addr;
1445 if (addrlen < 0)
1446 return -TARGET_EINVAL;
1448 addr = alloca(addrlen);
1450 target_to_host_sockaddr(addr, target_addr, addrlen);
1451 return get_errno(connect(sockfd, addr, addrlen));
1454 /* do_sendrecvmsg() Must return target values and target errnos. */
1455 static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1456 int flags, int send)
1458 abi_long ret, len;
1459 struct target_msghdr *msgp;
1460 struct msghdr msg;
1461 int count;
1462 struct iovec *vec;
1463 abi_ulong target_vec;
1465 /* FIXME */
1466 if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1467 msgp,
1468 target_msg,
1469 send ? 1 : 0))
1470 return -TARGET_EFAULT;
1471 if (msgp->msg_name) {
1472 msg.msg_namelen = tswap32(msgp->msg_namelen);
1473 msg.msg_name = alloca(msg.msg_namelen);
1474 target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
1475 msg.msg_namelen);
1476 } else {
1477 msg.msg_name = NULL;
1478 msg.msg_namelen = 0;
1480 msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
1481 msg.msg_control = alloca(msg.msg_controllen);
1482 msg.msg_flags = tswap32(msgp->msg_flags);
1484 count = tswapl(msgp->msg_iovlen);
1485 vec = alloca(count * sizeof(struct iovec));
1486 target_vec = tswapl(msgp->msg_iov);
1487 lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1488 msg.msg_iovlen = count;
1489 msg.msg_iov = vec;
1491 if (send) {
1492 ret = target_to_host_cmsg(&msg, msgp);
1493 if (ret == 0)
1494 ret = get_errno(sendmsg(fd, &msg, flags));
1495 } else {
1496 ret = get_errno(recvmsg(fd, &msg, flags));
1497 if (!is_error(ret)) {
1498 len = ret;
1499 ret = host_to_target_cmsg(msgp, &msg);
1500 if (!is_error(ret))
1501 ret = len;
1504 unlock_iovec(vec, target_vec, count, !send);
1505 unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1506 return ret;
1509 /* do_accept() Must return target values and target errnos. */
1510 static abi_long do_accept(int fd, abi_ulong target_addr,
1511 abi_ulong target_addrlen_addr)
1513 socklen_t addrlen;
1514 void *addr;
1515 abi_long ret;
1517 if (get_user_u32(addrlen, target_addrlen_addr))
1518 return -TARGET_EFAULT;
1520 if (addrlen < 0)
1521 return -TARGET_EINVAL;
1523 addr = alloca(addrlen);
1525 ret = get_errno(accept(fd, addr, &addrlen));
1526 if (!is_error(ret)) {
1527 host_to_target_sockaddr(target_addr, addr, addrlen);
1528 if (put_user_u32(addrlen, target_addrlen_addr))
1529 ret = -TARGET_EFAULT;
1531 return ret;
1534 /* do_getpeername() Must return target values and target errnos. */
1535 static abi_long do_getpeername(int fd, abi_ulong target_addr,
1536 abi_ulong target_addrlen_addr)
1538 socklen_t addrlen;
1539 void *addr;
1540 abi_long ret;
1542 if (get_user_u32(addrlen, target_addrlen_addr))
1543 return -TARGET_EFAULT;
1545 if (addrlen < 0)
1546 return -TARGET_EINVAL;
1548 addr = alloca(addrlen);
1550 ret = get_errno(getpeername(fd, addr, &addrlen));
1551 if (!is_error(ret)) {
1552 host_to_target_sockaddr(target_addr, addr, addrlen);
1553 if (put_user_u32(addrlen, target_addrlen_addr))
1554 ret = -TARGET_EFAULT;
1556 return ret;
1559 /* do_getsockname() Must return target values and target errnos. */
1560 static abi_long do_getsockname(int fd, abi_ulong target_addr,
1561 abi_ulong target_addrlen_addr)
1563 socklen_t addrlen;
1564 void *addr;
1565 abi_long ret;
1567 if (target_addr == 0)
1568 return get_errno(accept(fd, NULL, NULL));
1570 if (get_user_u32(addrlen, target_addrlen_addr))
1571 return -TARGET_EFAULT;
1573 if (addrlen < 0)
1574 return -TARGET_EINVAL;
1576 addr = alloca(addrlen);
1578 ret = get_errno(getsockname(fd, addr, &addrlen));
1579 if (!is_error(ret)) {
1580 host_to_target_sockaddr(target_addr, addr, addrlen);
1581 if (put_user_u32(addrlen, target_addrlen_addr))
1582 ret = -TARGET_EFAULT;
1584 return ret;
1587 /* do_socketpair() Must return target values and target errnos. */
1588 static abi_long do_socketpair(int domain, int type, int protocol,
1589 abi_ulong target_tab_addr)
1591 int tab[2];
1592 abi_long ret;
1594 ret = get_errno(socketpair(domain, type, protocol, tab));
1595 if (!is_error(ret)) {
1596 if (put_user_s32(tab[0], target_tab_addr)
1597 || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1598 ret = -TARGET_EFAULT;
1600 return ret;
1603 /* do_sendto() Must return target values and target errnos. */
1604 static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
1605 abi_ulong target_addr, socklen_t addrlen)
1607 void *addr;
1608 void *host_msg;
1609 abi_long ret;
1611 if (addrlen < 0)
1612 return -TARGET_EINVAL;
1614 host_msg = lock_user(VERIFY_READ, msg, len, 1);
1615 if (!host_msg)
1616 return -TARGET_EFAULT;
1617 if (target_addr) {
1618 addr = alloca(addrlen);
1619 target_to_host_sockaddr(addr, target_addr, addrlen);
1620 ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
1621 } else {
1622 ret = get_errno(send(fd, host_msg, len, flags));
1624 unlock_user(host_msg, msg, 0);
1625 return ret;
1628 /* do_recvfrom() Must return target values and target errnos. */
1629 static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
1630 abi_ulong target_addr,
1631 abi_ulong target_addrlen)
1633 socklen_t addrlen;
1634 void *addr;
1635 void *host_msg;
1636 abi_long ret;
1638 host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
1639 if (!host_msg)
1640 return -TARGET_EFAULT;
1641 if (target_addr) {
1642 if (get_user_u32(addrlen, target_addrlen)) {
1643 ret = -TARGET_EFAULT;
1644 goto fail;
1646 if (addrlen < 0) {
1647 ret = -TARGET_EINVAL;
1648 goto fail;
1650 addr = alloca(addrlen);
1651 ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
1652 } else {
1653 addr = NULL; /* To keep compiler quiet. */
1654 ret = get_errno(recv(fd, host_msg, len, flags));
1656 if (!is_error(ret)) {
1657 if (target_addr) {
1658 host_to_target_sockaddr(target_addr, addr, addrlen);
1659 if (put_user_u32(addrlen, target_addrlen)) {
1660 ret = -TARGET_EFAULT;
1661 goto fail;
1664 unlock_user(host_msg, msg, len);
1665 } else {
1666 fail:
1667 unlock_user(host_msg, msg, 0);
1669 return ret;
1672 #ifdef TARGET_NR_socketcall
1673 /* do_socketcall() Must return target values and target errnos. */
1674 static abi_long do_socketcall(int num, abi_ulong vptr)
1676 abi_long ret;
1677 const int n = sizeof(abi_ulong);
1679 switch(num) {
1680 case SOCKOP_socket:
1682 int domain, type, protocol;
1684 if (get_user_s32(domain, vptr)
1685 || get_user_s32(type, vptr + n)
1686 || get_user_s32(protocol, vptr + 2 * n))
1687 return -TARGET_EFAULT;
1689 ret = do_socket(domain, type, protocol);
1691 break;
1692 case SOCKOP_bind:
1694 int sockfd;
1695 abi_ulong target_addr;
1696 socklen_t addrlen;
1698 if (get_user_s32(sockfd, vptr)
1699 || get_user_ual(target_addr, vptr + n)
1700 || get_user_u32(addrlen, vptr + 2 * n))
1701 return -TARGET_EFAULT;
1703 ret = do_bind(sockfd, target_addr, addrlen);
1705 break;
1706 case SOCKOP_connect:
1708 int sockfd;
1709 abi_ulong target_addr;
1710 socklen_t addrlen;
1712 if (get_user_s32(sockfd, vptr)
1713 || get_user_ual(target_addr, vptr + n)
1714 || get_user_u32(addrlen, vptr + 2 * n))
1715 return -TARGET_EFAULT;
1717 ret = do_connect(sockfd, target_addr, addrlen);
1719 break;
1720 case SOCKOP_listen:
1722 int sockfd, backlog;
1724 if (get_user_s32(sockfd, vptr)
1725 || get_user_s32(backlog, vptr + n))
1726 return -TARGET_EFAULT;
1728 ret = get_errno(listen(sockfd, backlog));
1730 break;
1731 case SOCKOP_accept:
1733 int sockfd;
1734 abi_ulong target_addr, target_addrlen;
1736 if (get_user_s32(sockfd, vptr)
1737 || get_user_ual(target_addr, vptr + n)
1738 || get_user_u32(target_addrlen, vptr + 2 * n))
1739 return -TARGET_EFAULT;
1741 ret = do_accept(sockfd, target_addr, target_addrlen);
1743 break;
1744 case SOCKOP_getsockname:
1746 int sockfd;
1747 abi_ulong target_addr, target_addrlen;
1749 if (get_user_s32(sockfd, vptr)
1750 || get_user_ual(target_addr, vptr + n)
1751 || get_user_u32(target_addrlen, vptr + 2 * n))
1752 return -TARGET_EFAULT;
1754 ret = do_getsockname(sockfd, target_addr, target_addrlen);
1756 break;
1757 case SOCKOP_getpeername:
1759 int sockfd;
1760 abi_ulong target_addr, target_addrlen;
1762 if (get_user_s32(sockfd, vptr)
1763 || get_user_ual(target_addr, vptr + n)
1764 || get_user_u32(target_addrlen, vptr + 2 * n))
1765 return -TARGET_EFAULT;
1767 ret = do_getpeername(sockfd, target_addr, target_addrlen);
1769 break;
1770 case SOCKOP_socketpair:
1772 int domain, type, protocol;
1773 abi_ulong tab;
1775 if (get_user_s32(domain, vptr)
1776 || get_user_s32(type, vptr + n)
1777 || get_user_s32(protocol, vptr + 2 * n)
1778 || get_user_ual(tab, vptr + 3 * n))
1779 return -TARGET_EFAULT;
1781 ret = do_socketpair(domain, type, protocol, tab);
1783 break;
1784 case SOCKOP_send:
1786 int sockfd;
1787 abi_ulong msg;
1788 size_t len;
1789 int flags;
1791 if (get_user_s32(sockfd, vptr)
1792 || get_user_ual(msg, vptr + n)
1793 || get_user_ual(len, vptr + 2 * n)
1794 || get_user_s32(flags, vptr + 3 * n))
1795 return -TARGET_EFAULT;
1797 ret = do_sendto(sockfd, msg, len, flags, 0, 0);
1799 break;
1800 case SOCKOP_recv:
1802 int sockfd;
1803 abi_ulong msg;
1804 size_t len;
1805 int flags;
1807 if (get_user_s32(sockfd, vptr)
1808 || get_user_ual(msg, vptr + n)
1809 || get_user_ual(len, vptr + 2 * n)
1810 || get_user_s32(flags, vptr + 3 * n))
1811 return -TARGET_EFAULT;
1813 ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
1815 break;
1816 case SOCKOP_sendto:
1818 int sockfd;
1819 abi_ulong msg;
1820 size_t len;
1821 int flags;
1822 abi_ulong addr;
1823 socklen_t addrlen;
1825 if (get_user_s32(sockfd, vptr)
1826 || get_user_ual(msg, vptr + n)
1827 || get_user_ual(len, vptr + 2 * n)
1828 || get_user_s32(flags, vptr + 3 * n)
1829 || get_user_ual(addr, vptr + 4 * n)
1830 || get_user_u32(addrlen, vptr + 5 * n))
1831 return -TARGET_EFAULT;
1833 ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
1835 break;
1836 case SOCKOP_recvfrom:
1838 int sockfd;
1839 abi_ulong msg;
1840 size_t len;
1841 int flags;
1842 abi_ulong addr;
1843 socklen_t addrlen;
1845 if (get_user_s32(sockfd, vptr)
1846 || get_user_ual(msg, vptr + n)
1847 || get_user_ual(len, vptr + 2 * n)
1848 || get_user_s32(flags, vptr + 3 * n)
1849 || get_user_ual(addr, vptr + 4 * n)
1850 || get_user_u32(addrlen, vptr + 5 * n))
1851 return -TARGET_EFAULT;
1853 ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
1855 break;
1856 case SOCKOP_shutdown:
1858 int sockfd, how;
1860 if (get_user_s32(sockfd, vptr)
1861 || get_user_s32(how, vptr + n))
1862 return -TARGET_EFAULT;
1864 ret = get_errno(shutdown(sockfd, how));
1866 break;
1867 case SOCKOP_sendmsg:
1868 case SOCKOP_recvmsg:
1870 int fd;
1871 abi_ulong target_msg;
1872 int flags;
1874 if (get_user_s32(fd, vptr)
1875 || get_user_ual(target_msg, vptr + n)
1876 || get_user_s32(flags, vptr + 2 * n))
1877 return -TARGET_EFAULT;
1879 ret = do_sendrecvmsg(fd, target_msg, flags,
1880 (num == SOCKOP_sendmsg));
1882 break;
1883 case SOCKOP_setsockopt:
1885 int sockfd;
1886 int level;
1887 int optname;
1888 abi_ulong optval;
1889 socklen_t optlen;
1891 if (get_user_s32(sockfd, vptr)
1892 || get_user_s32(level, vptr + n)
1893 || get_user_s32(optname, vptr + 2 * n)
1894 || get_user_ual(optval, vptr + 3 * n)
1895 || get_user_u32(optlen, vptr + 4 * n))
1896 return -TARGET_EFAULT;
1898 ret = do_setsockopt(sockfd, level, optname, optval, optlen);
1900 break;
1901 case SOCKOP_getsockopt:
1903 int sockfd;
1904 int level;
1905 int optname;
1906 abi_ulong optval;
1907 socklen_t optlen;
1909 if (get_user_s32(sockfd, vptr)
1910 || get_user_s32(level, vptr + n)
1911 || get_user_s32(optname, vptr + 2 * n)
1912 || get_user_ual(optval, vptr + 3 * n)
1913 || get_user_u32(optlen, vptr + 4 * n))
1914 return -TARGET_EFAULT;
1916 ret = do_getsockopt(sockfd, level, optname, optval, optlen);
1918 break;
1919 default:
1920 gemu_log("Unsupported socketcall: %d\n", num);
1921 ret = -TARGET_ENOSYS;
1922 break;
1924 return ret;
1926 #endif
1928 #ifdef TARGET_NR_ipc
1929 #define N_SHM_REGIONS 32
1931 static struct shm_region {
1932 abi_ulong start;
1933 abi_ulong size;
1934 } shm_regions[N_SHM_REGIONS];
1935 #endif
1937 struct target_ipc_perm
1939 abi_long __key;
1940 abi_ulong uid;
1941 abi_ulong gid;
1942 abi_ulong cuid;
1943 abi_ulong cgid;
1944 unsigned short int mode;
1945 unsigned short int __pad1;
1946 unsigned short int __seq;
1947 unsigned short int __pad2;
1948 abi_ulong __unused1;
1949 abi_ulong __unused2;
1952 struct target_semid_ds
1954 struct target_ipc_perm sem_perm;
1955 abi_ulong sem_otime;
1956 abi_ulong __unused1;
1957 abi_ulong sem_ctime;
1958 abi_ulong __unused2;
1959 abi_ulong sem_nsems;
1960 abi_ulong __unused3;
1961 abi_ulong __unused4;
1964 static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
1965 abi_ulong target_addr)
1967 struct target_ipc_perm *target_ip;
1968 struct target_semid_ds *target_sd;
1970 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
1971 return -TARGET_EFAULT;
1972 target_ip=&(target_sd->sem_perm);
1973 host_ip->__key = tswapl(target_ip->__key);
1974 host_ip->uid = tswapl(target_ip->uid);
1975 host_ip->gid = tswapl(target_ip->gid);
1976 host_ip->cuid = tswapl(target_ip->cuid);
1977 host_ip->cgid = tswapl(target_ip->cgid);
1978 host_ip->mode = tswapl(target_ip->mode);
1979 unlock_user_struct(target_sd, target_addr, 0);
1980 return 0;
1983 static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
1984 struct ipc_perm *host_ip)
1986 struct target_ipc_perm *target_ip;
1987 struct target_semid_ds *target_sd;
1989 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
1990 return -TARGET_EFAULT;
1991 target_ip = &(target_sd->sem_perm);
1992 target_ip->__key = tswapl(host_ip->__key);
1993 target_ip->uid = tswapl(host_ip->uid);
1994 target_ip->gid = tswapl(host_ip->gid);
1995 target_ip->cuid = tswapl(host_ip->cuid);
1996 target_ip->cgid = tswapl(host_ip->cgid);
1997 target_ip->mode = tswapl(host_ip->mode);
1998 unlock_user_struct(target_sd, target_addr, 1);
1999 return 0;
2002 static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
2003 abi_ulong target_addr)
2005 struct target_semid_ds *target_sd;
2007 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2008 return -TARGET_EFAULT;
2009 if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr))
2010 return -TARGET_EFAULT;
2011 host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
2012 host_sd->sem_otime = tswapl(target_sd->sem_otime);
2013 host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
2014 unlock_user_struct(target_sd, target_addr, 0);
2015 return 0;
2018 static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
2019 struct semid_ds *host_sd)
2021 struct target_semid_ds *target_sd;
2023 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2024 return -TARGET_EFAULT;
2025 if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
2026 return -TARGET_EFAULT;;
2027 target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
2028 target_sd->sem_otime = tswapl(host_sd->sem_otime);
2029 target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
2030 unlock_user_struct(target_sd, target_addr, 1);
2031 return 0;
2034 struct target_seminfo {
2035 int semmap;
2036 int semmni;
2037 int semmns;
2038 int semmnu;
2039 int semmsl;
2040 int semopm;
2041 int semume;
2042 int semusz;
2043 int semvmx;
2044 int semaem;
2047 static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
2048 struct seminfo *host_seminfo)
2050 struct target_seminfo *target_seminfo;
2051 if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
2052 return -TARGET_EFAULT;
2053 __put_user(host_seminfo->semmap, &target_seminfo->semmap);
2054 __put_user(host_seminfo->semmni, &target_seminfo->semmni);
2055 __put_user(host_seminfo->semmns, &target_seminfo->semmns);
2056 __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
2057 __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
2058 __put_user(host_seminfo->semopm, &target_seminfo->semopm);
2059 __put_user(host_seminfo->semume, &target_seminfo->semume);
2060 __put_user(host_seminfo->semusz, &target_seminfo->semusz);
2061 __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
2062 __put_user(host_seminfo->semaem, &target_seminfo->semaem);
2063 unlock_user_struct(target_seminfo, target_addr, 1);
2064 return 0;
2067 union semun {
2068 int val;
2069 struct semid_ds *buf;
2070 unsigned short *array;
2071 struct seminfo *__buf;
2074 union target_semun {
2075 int val;
2076 abi_ulong buf;
2077 abi_ulong array;
2078 abi_ulong __buf;
2081 static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
2082 abi_ulong target_addr)
2084 int nsems;
2085 unsigned short *array;
2086 union semun semun;
2087 struct semid_ds semid_ds;
2088 int i, ret;
2090 semun.buf = &semid_ds;
2092 ret = semctl(semid, 0, IPC_STAT, semun);
2093 if (ret == -1)
2094 return get_errno(ret);
2096 nsems = semid_ds.sem_nsems;
2098 *host_array = malloc(nsems*sizeof(unsigned short));
2099 array = lock_user(VERIFY_READ, target_addr,
2100 nsems*sizeof(unsigned short), 1);
2101 if (!array)
2102 return -TARGET_EFAULT;
2104 for(i=0; i<nsems; i++) {
2105 __get_user((*host_array)[i], &array[i]);
2107 unlock_user(array, target_addr, 0);
2109 return 0;
2112 static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
2113 unsigned short **host_array)
2115 int nsems;
2116 unsigned short *array;
2117 union semun semun;
2118 struct semid_ds semid_ds;
2119 int i, ret;
2121 semun.buf = &semid_ds;
2123 ret = semctl(semid, 0, IPC_STAT, semun);
2124 if (ret == -1)
2125 return get_errno(ret);
2127 nsems = semid_ds.sem_nsems;
2129 array = lock_user(VERIFY_WRITE, target_addr,
2130 nsems*sizeof(unsigned short), 0);
2131 if (!array)
2132 return -TARGET_EFAULT;
2134 for(i=0; i<nsems; i++) {
2135 __put_user((*host_array)[i], &array[i]);
2137 free(*host_array);
2138 unlock_user(array, target_addr, 1);
2140 return 0;
2143 static inline abi_long do_semctl(int semid, int semnum, int cmd,
2144 union target_semun target_su)
2146 union semun arg;
2147 struct semid_ds dsarg;
2148 unsigned short *array;
2149 struct seminfo seminfo;
2150 abi_long ret = -TARGET_EINVAL;
2151 abi_long err;
2152 cmd &= 0xff;
2154 switch( cmd ) {
2155 case GETVAL:
2156 case SETVAL:
2157 arg.val = tswapl(target_su.val);
2158 ret = get_errno(semctl(semid, semnum, cmd, arg));
2159 target_su.val = tswapl(arg.val);
2160 break;
2161 case GETALL:
2162 case SETALL:
2163 err = target_to_host_semarray(semid, &array, target_su.array);
2164 if (err)
2165 return err;
2166 arg.array = array;
2167 ret = get_errno(semctl(semid, semnum, cmd, arg));
2168 err = host_to_target_semarray(semid, target_su.array, &array);
2169 if (err)
2170 return err;
2171 break;
2172 case IPC_STAT:
2173 case IPC_SET:
2174 case SEM_STAT:
2175 err = target_to_host_semid_ds(&dsarg, target_su.buf);
2176 if (err)
2177 return err;
2178 arg.buf = &dsarg;
2179 ret = get_errno(semctl(semid, semnum, cmd, arg));
2180 err = host_to_target_semid_ds(target_su.buf, &dsarg);
2181 if (err)
2182 return err;
2183 break;
2184 case IPC_INFO:
2185 case SEM_INFO:
2186 arg.__buf = &seminfo;
2187 ret = get_errno(semctl(semid, semnum, cmd, arg));
2188 err = host_to_target_seminfo(target_su.__buf, &seminfo);
2189 if (err)
2190 return err;
2191 break;
2192 case IPC_RMID:
2193 case GETPID:
2194 case GETNCNT:
2195 case GETZCNT:
2196 ret = get_errno(semctl(semid, semnum, cmd, NULL));
2197 break;
2200 return ret;
2203 struct target_sembuf {
2204 unsigned short sem_num;
2205 short sem_op;
2206 short sem_flg;
2209 static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
2210 abi_ulong target_addr,
2211 unsigned nsops)
2213 struct target_sembuf *target_sembuf;
2214 int i;
2216 target_sembuf = lock_user(VERIFY_READ, target_addr,
2217 nsops*sizeof(struct target_sembuf), 1);
2218 if (!target_sembuf)
2219 return -TARGET_EFAULT;
2221 for(i=0; i<nsops; i++) {
2222 __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
2223 __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
2224 __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
2227 unlock_user(target_sembuf, target_addr, 0);
2229 return 0;
2232 static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
2234 struct sembuf sops[nsops];
2236 if (target_to_host_sembuf(sops, ptr, nsops))
2237 return -TARGET_EFAULT;
2239 return semop(semid, sops, nsops);
2242 struct target_msqid_ds
2244 struct target_ipc_perm msg_perm;
2245 abi_ulong msg_stime;
2246 #if TARGET_ABI_BITS == 32
2247 abi_ulong __unused1;
2248 #endif
2249 abi_ulong msg_rtime;
2250 #if TARGET_ABI_BITS == 32
2251 abi_ulong __unused2;
2252 #endif
2253 abi_ulong msg_ctime;
2254 #if TARGET_ABI_BITS == 32
2255 abi_ulong __unused3;
2256 #endif
2257 abi_ulong __msg_cbytes;
2258 abi_ulong msg_qnum;
2259 abi_ulong msg_qbytes;
2260 abi_ulong msg_lspid;
2261 abi_ulong msg_lrpid;
2262 abi_ulong __unused4;
2263 abi_ulong __unused5;
2266 static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
2267 abi_ulong target_addr)
2269 struct target_msqid_ds *target_md;
2271 if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
2272 return -TARGET_EFAULT;
2273 if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
2274 return -TARGET_EFAULT;
2275 host_md->msg_stime = tswapl(target_md->msg_stime);
2276 host_md->msg_rtime = tswapl(target_md->msg_rtime);
2277 host_md->msg_ctime = tswapl(target_md->msg_ctime);
2278 host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
2279 host_md->msg_qnum = tswapl(target_md->msg_qnum);
2280 host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
2281 host_md->msg_lspid = tswapl(target_md->msg_lspid);
2282 host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
2283 unlock_user_struct(target_md, target_addr, 0);
2284 return 0;
2287 static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
2288 struct msqid_ds *host_md)
2290 struct target_msqid_ds *target_md;
2292 if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
2293 return -TARGET_EFAULT;
2294 if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
2295 return -TARGET_EFAULT;
2296 target_md->msg_stime = tswapl(host_md->msg_stime);
2297 target_md->msg_rtime = tswapl(host_md->msg_rtime);
2298 target_md->msg_ctime = tswapl(host_md->msg_ctime);
2299 target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
2300 target_md->msg_qnum = tswapl(host_md->msg_qnum);
2301 target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
2302 target_md->msg_lspid = tswapl(host_md->msg_lspid);
2303 target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
2304 unlock_user_struct(target_md, target_addr, 1);
2305 return 0;
2308 struct target_msginfo {
2309 int msgpool;
2310 int msgmap;
2311 int msgmax;
2312 int msgmnb;
2313 int msgmni;
2314 int msgssz;
2315 int msgtql;
2316 unsigned short int msgseg;
2319 static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
2320 struct msginfo *host_msginfo)
2322 struct target_msginfo *target_msginfo;
2323 if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
2324 return -TARGET_EFAULT;
2325 __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
2326 __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
2327 __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
2328 __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
2329 __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
2330 __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
2331 __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
2332 __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
2333 unlock_user_struct(target_msginfo, target_addr, 1);
2334 return 0;
2337 static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
2339 struct msqid_ds dsarg;
2340 struct msginfo msginfo;
2341 abi_long ret = -TARGET_EINVAL;
2343 cmd &= 0xff;
2345 switch (cmd) {
2346 case IPC_STAT:
2347 case IPC_SET:
2348 case MSG_STAT:
2349 if (target_to_host_msqid_ds(&dsarg,ptr))
2350 return -TARGET_EFAULT;
2351 ret = get_errno(msgctl(msgid, cmd, &dsarg));
2352 if (host_to_target_msqid_ds(ptr,&dsarg))
2353 return -TARGET_EFAULT;
2354 break;
2355 case IPC_RMID:
2356 ret = get_errno(msgctl(msgid, cmd, NULL));
2357 break;
2358 case IPC_INFO:
2359 case MSG_INFO:
2360 ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
2361 if (host_to_target_msginfo(ptr, &msginfo))
2362 return -TARGET_EFAULT;
2363 break;
2366 return ret;
2369 struct target_msgbuf {
2370 abi_long mtype;
2371 char mtext[1];
2374 static inline abi_long do_msgsnd(int msqid, abi_long msgp,
2375 unsigned int msgsz, int msgflg)
2377 struct target_msgbuf *target_mb;
2378 struct msgbuf *host_mb;
2379 abi_long ret = 0;
2381 if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
2382 return -TARGET_EFAULT;
2383 host_mb = malloc(msgsz+sizeof(long));
2384 host_mb->mtype = (abi_long) tswapl(target_mb->mtype);
2385 memcpy(host_mb->mtext, target_mb->mtext, msgsz);
2386 ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
2387 free(host_mb);
2388 unlock_user_struct(target_mb, msgp, 0);
2390 return ret;
2393 static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2394 unsigned int msgsz, abi_long msgtyp,
2395 int msgflg)
2397 struct target_msgbuf *target_mb;
2398 char *target_mtext;
2399 struct msgbuf *host_mb;
2400 abi_long ret = 0;
2402 if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2403 return -TARGET_EFAULT;
2405 host_mb = malloc(msgsz+sizeof(long));
2406 ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapl(msgtyp), msgflg));
2408 if (ret > 0) {
2409 abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2410 target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2411 if (!target_mtext) {
2412 ret = -TARGET_EFAULT;
2413 goto end;
2415 memcpy(target_mb->mtext, host_mb->mtext, ret);
2416 unlock_user(target_mtext, target_mtext_addr, ret);
2419 target_mb->mtype = tswapl(host_mb->mtype);
2420 free(host_mb);
2422 end:
2423 if (target_mb)
2424 unlock_user_struct(target_mb, msgp, 1);
2425 return ret;
2428 #ifdef TARGET_NR_ipc
2429 /* ??? This only works with linear mappings. */
2430 /* do_ipc() must return target values and target errnos. */
2431 static abi_long do_ipc(unsigned int call, int first,
2432 int second, int third,
2433 abi_long ptr, abi_long fifth)
2435 int version;
2436 abi_long ret = 0;
2437 struct shmid_ds shm_info;
2438 int i;
2440 version = call >> 16;
2441 call &= 0xffff;
2443 switch (call) {
2444 case IPCOP_semop:
2445 ret = do_semop(first, ptr, second);
2446 break;
2448 case IPCOP_semget:
2449 ret = get_errno(semget(first, second, third));
2450 break;
2452 case IPCOP_semctl:
2453 ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr);
2454 break;
2456 case IPCOP_msgget:
2457 ret = get_errno(msgget(first, second));
2458 break;
2460 case IPCOP_msgsnd:
2461 ret = do_msgsnd(first, ptr, second, third);
2462 break;
2464 case IPCOP_msgctl:
2465 ret = do_msgctl(first, second, ptr);
2466 break;
2468 case IPCOP_msgrcv:
2469 switch (version) {
2470 case 0:
2472 struct target_ipc_kludge {
2473 abi_long msgp;
2474 abi_long msgtyp;
2475 } *tmp;
2477 if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
2478 ret = -TARGET_EFAULT;
2479 break;
2482 ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
2484 unlock_user_struct(tmp, ptr, 0);
2485 break;
2487 default:
2488 ret = do_msgrcv(first, ptr, second, fifth, third);
2490 break;
2492 case IPCOP_shmat:
2494 abi_ulong raddr;
2495 void *host_addr;
2496 /* SHM_* flags are the same on all linux platforms */
2497 host_addr = shmat(first, (void *)g2h(ptr), second);
2498 if (host_addr == (void *)-1) {
2499 ret = get_errno((long)host_addr);
2500 break;
2502 raddr = h2g((unsigned long)host_addr);
2503 /* find out the length of the shared memory segment */
2505 ret = get_errno(shmctl(first, IPC_STAT, &shm_info));
2506 if (is_error(ret)) {
2507 /* can't get length, bail out */
2508 shmdt(host_addr);
2509 break;
2511 page_set_flags(raddr, raddr + shm_info.shm_segsz,
2512 PAGE_VALID | PAGE_READ |
2513 ((second & SHM_RDONLY)? 0: PAGE_WRITE));
2514 for (i = 0; i < N_SHM_REGIONS; ++i) {
2515 if (shm_regions[i].start == 0) {
2516 shm_regions[i].start = raddr;
2517 shm_regions[i].size = shm_info.shm_segsz;
2518 break;
2521 if (put_user_ual(raddr, third))
2522 return -TARGET_EFAULT;
2523 ret = 0;
2525 break;
2526 case IPCOP_shmdt:
2527 for (i = 0; i < N_SHM_REGIONS; ++i) {
2528 if (shm_regions[i].start == ptr) {
2529 shm_regions[i].start = 0;
2530 page_set_flags(ptr, shm_regions[i].size, 0);
2531 break;
2534 ret = get_errno(shmdt((void *)g2h(ptr)));
2535 break;
2537 case IPCOP_shmget:
2538 /* IPC_* flag values are the same on all linux platforms */
2539 ret = get_errno(shmget(first, second, third));
2540 break;
2542 /* IPC_* and SHM_* command values are the same on all linux platforms */
2543 case IPCOP_shmctl:
2544 switch(second) {
2545 case IPC_RMID:
2546 case SHM_LOCK:
2547 case SHM_UNLOCK:
2548 ret = get_errno(shmctl(first, second, NULL));
2549 break;
2550 default:
2551 goto unimplemented;
2553 break;
2554 default:
2555 unimplemented:
2556 gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2557 ret = -TARGET_ENOSYS;
2558 break;
2560 return ret;
2562 #endif
2564 /* kernel structure types definitions */
2565 #define IFNAMSIZ 16
2567 #define STRUCT(name, ...) STRUCT_ ## name,
2568 #define STRUCT_SPECIAL(name) STRUCT_ ## name,
2569 enum {
2570 #include "syscall_types.h"
2572 #undef STRUCT
2573 #undef STRUCT_SPECIAL
2575 #define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = { __VA_ARGS__, TYPE_NULL };
2576 #define STRUCT_SPECIAL(name)
2577 #include "syscall_types.h"
2578 #undef STRUCT
2579 #undef STRUCT_SPECIAL
2581 typedef struct IOCTLEntry {
2582 unsigned int target_cmd;
2583 unsigned int host_cmd;
2584 const char *name;
2585 int access;
2586 const argtype arg_type[5];
2587 } IOCTLEntry;
2589 #define IOC_R 0x0001
2590 #define IOC_W 0x0002
2591 #define IOC_RW (IOC_R | IOC_W)
2593 #define MAX_STRUCT_SIZE 4096
2595 static IOCTLEntry ioctl_entries[] = {
2596 #define IOCTL(cmd, access, ...) \
2597 { TARGET_ ## cmd, cmd, #cmd, access, { __VA_ARGS__ } },
2598 #include "ioctls.h"
2599 { 0, 0, },
2602 /* ??? Implement proper locking for ioctls. */
2603 /* do_ioctl() Must return target values and target errnos. */
2604 static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
2606 const IOCTLEntry *ie;
2607 const argtype *arg_type;
2608 abi_long ret;
2609 uint8_t buf_temp[MAX_STRUCT_SIZE];
2610 int target_size;
2611 void *argptr;
2613 ie = ioctl_entries;
2614 for(;;) {
2615 if (ie->target_cmd == 0) {
2616 gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
2617 return -TARGET_ENOSYS;
2619 if (ie->target_cmd == cmd)
2620 break;
2621 ie++;
2623 arg_type = ie->arg_type;
2624 #if defined(DEBUG)
2625 gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
2626 #endif
2627 switch(arg_type[0]) {
2628 case TYPE_NULL:
2629 /* no argument */
2630 ret = get_errno(ioctl(fd, ie->host_cmd));
2631 break;
2632 case TYPE_PTRVOID:
2633 case TYPE_INT:
2634 /* int argment */
2635 ret = get_errno(ioctl(fd, ie->host_cmd, arg));
2636 break;
2637 case TYPE_PTR:
2638 arg_type++;
2639 target_size = thunk_type_size(arg_type, 0);
2640 switch(ie->access) {
2641 case IOC_R:
2642 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2643 if (!is_error(ret)) {
2644 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2645 if (!argptr)
2646 return -TARGET_EFAULT;
2647 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2648 unlock_user(argptr, arg, target_size);
2650 break;
2651 case IOC_W:
2652 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2653 if (!argptr)
2654 return -TARGET_EFAULT;
2655 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2656 unlock_user(argptr, arg, 0);
2657 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2658 break;
2659 default:
2660 case IOC_RW:
2661 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2662 if (!argptr)
2663 return -TARGET_EFAULT;
2664 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2665 unlock_user(argptr, arg, 0);
2666 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2667 if (!is_error(ret)) {
2668 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2669 if (!argptr)
2670 return -TARGET_EFAULT;
2671 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2672 unlock_user(argptr, arg, target_size);
2674 break;
2676 break;
2677 default:
2678 gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
2679 (long)cmd, arg_type[0]);
2680 ret = -TARGET_ENOSYS;
2681 break;
2683 return ret;
2686 static const bitmask_transtbl iflag_tbl[] = {
2687 { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
2688 { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
2689 { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
2690 { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
2691 { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
2692 { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
2693 { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
2694 { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
2695 { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
2696 { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
2697 { TARGET_IXON, TARGET_IXON, IXON, IXON },
2698 { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
2699 { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
2700 { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
2701 { 0, 0, 0, 0 }
2704 static const bitmask_transtbl oflag_tbl[] = {
2705 { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
2706 { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
2707 { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
2708 { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
2709 { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
2710 { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
2711 { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
2712 { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
2713 { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
2714 { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
2715 { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
2716 { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
2717 { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
2718 { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
2719 { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
2720 { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
2721 { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
2722 { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
2723 { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
2724 { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
2725 { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
2726 { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
2727 { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
2728 { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
2729 { 0, 0, 0, 0 }
2732 static const bitmask_transtbl cflag_tbl[] = {
2733 { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
2734 { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
2735 { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
2736 { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
2737 { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
2738 { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
2739 { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
2740 { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
2741 { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
2742 { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
2743 { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
2744 { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
2745 { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
2746 { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
2747 { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
2748 { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
2749 { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
2750 { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
2751 { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
2752 { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
2753 { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
2754 { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
2755 { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
2756 { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
2757 { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
2758 { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
2759 { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
2760 { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
2761 { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
2762 { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
2763 { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
2764 { 0, 0, 0, 0 }
2767 static const bitmask_transtbl lflag_tbl[] = {
2768 { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
2769 { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
2770 { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
2771 { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
2772 { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
2773 { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
2774 { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
2775 { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
2776 { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
2777 { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
2778 { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
2779 { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
2780 { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
2781 { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
2782 { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
2783 { 0, 0, 0, 0 }
2786 static void target_to_host_termios (void *dst, const void *src)
2788 struct host_termios *host = dst;
2789 const struct target_termios *target = src;
2791 host->c_iflag =
2792 target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
2793 host->c_oflag =
2794 target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
2795 host->c_cflag =
2796 target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
2797 host->c_lflag =
2798 target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
2799 host->c_line = target->c_line;
2801 host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
2802 host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
2803 host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
2804 host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
2805 host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
2806 host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
2807 host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
2808 host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
2809 host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
2810 host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
2811 host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
2812 host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
2813 host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
2814 host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
2815 host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
2816 host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
2817 host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
2820 static void host_to_target_termios (void *dst, const void *src)
2822 struct target_termios *target = dst;
2823 const struct host_termios *host = src;
2825 target->c_iflag =
2826 tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
2827 target->c_oflag =
2828 tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
2829 target->c_cflag =
2830 tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
2831 target->c_lflag =
2832 tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
2833 target->c_line = host->c_line;
2835 target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
2836 target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
2837 target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
2838 target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
2839 target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
2840 target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
2841 target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
2842 target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
2843 target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
2844 target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
2845 target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
2846 target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
2847 target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
2848 target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
2849 target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
2850 target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
2851 target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
2854 static const StructEntry struct_termios_def = {
2855 .convert = { host_to_target_termios, target_to_host_termios },
2856 .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
2857 .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
2860 static bitmask_transtbl mmap_flags_tbl[] = {
2861 { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
2862 { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
2863 { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
2864 { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
2865 { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
2866 { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
2867 { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
2868 { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
2869 { 0, 0, 0, 0 }
2872 #if defined(TARGET_I386)
2874 /* NOTE: there is really one LDT for all the threads */
2875 static uint8_t *ldt_table;
2877 static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
2879 int size;
2880 void *p;
2882 if (!ldt_table)
2883 return 0;
2884 size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
2885 if (size > bytecount)
2886 size = bytecount;
2887 p = lock_user(VERIFY_WRITE, ptr, size, 0);
2888 if (!p)
2889 return -TARGET_EFAULT;
2890 /* ??? Should this by byteswapped? */
2891 memcpy(p, ldt_table, size);
2892 unlock_user(p, ptr, size);
2893 return size;
2896 /* XXX: add locking support */
2897 static abi_long write_ldt(CPUX86State *env,
2898 abi_ulong ptr, unsigned long bytecount, int oldmode)
2900 struct target_modify_ldt_ldt_s ldt_info;
2901 struct target_modify_ldt_ldt_s *target_ldt_info;
2902 int seg_32bit, contents, read_exec_only, limit_in_pages;
2903 int seg_not_present, useable, lm;
2904 uint32_t *lp, entry_1, entry_2;
2906 if (bytecount != sizeof(ldt_info))
2907 return -TARGET_EINVAL;
2908 if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
2909 return -TARGET_EFAULT;
2910 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2911 ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2912 ldt_info.limit = tswap32(target_ldt_info->limit);
2913 ldt_info.flags = tswap32(target_ldt_info->flags);
2914 unlock_user_struct(target_ldt_info, ptr, 0);
2916 if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
2917 return -TARGET_EINVAL;
2918 seg_32bit = ldt_info.flags & 1;
2919 contents = (ldt_info.flags >> 1) & 3;
2920 read_exec_only = (ldt_info.flags >> 3) & 1;
2921 limit_in_pages = (ldt_info.flags >> 4) & 1;
2922 seg_not_present = (ldt_info.flags >> 5) & 1;
2923 useable = (ldt_info.flags >> 6) & 1;
2924 #ifdef TARGET_ABI32
2925 lm = 0;
2926 #else
2927 lm = (ldt_info.flags >> 7) & 1;
2928 #endif
2929 if (contents == 3) {
2930 if (oldmode)
2931 return -TARGET_EINVAL;
2932 if (seg_not_present == 0)
2933 return -TARGET_EINVAL;
2935 /* allocate the LDT */
2936 if (!ldt_table) {
2937 env->ldt.base = target_mmap(0,
2938 TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
2939 PROT_READ|PROT_WRITE,
2940 MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
2941 if (env->ldt.base == -1)
2942 return -TARGET_ENOMEM;
2943 memset(g2h(env->ldt.base), 0,
2944 TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
2945 env->ldt.limit = 0xffff;
2946 ldt_table = g2h(env->ldt.base);
2949 /* NOTE: same code as Linux kernel */
2950 /* Allow LDTs to be cleared by the user. */
2951 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2952 if (oldmode ||
2953 (contents == 0 &&
2954 read_exec_only == 1 &&
2955 seg_32bit == 0 &&
2956 limit_in_pages == 0 &&
2957 seg_not_present == 1 &&
2958 useable == 0 )) {
2959 entry_1 = 0;
2960 entry_2 = 0;
2961 goto install;
2965 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2966 (ldt_info.limit & 0x0ffff);
2967 entry_2 = (ldt_info.base_addr & 0xff000000) |
2968 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2969 (ldt_info.limit & 0xf0000) |
2970 ((read_exec_only ^ 1) << 9) |
2971 (contents << 10) |
2972 ((seg_not_present ^ 1) << 15) |
2973 (seg_32bit << 22) |
2974 (limit_in_pages << 23) |
2975 (lm << 21) |
2976 0x7000;
2977 if (!oldmode)
2978 entry_2 |= (useable << 20);
2980 /* Install the new entry ... */
2981 install:
2982 lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
2983 lp[0] = tswap32(entry_1);
2984 lp[1] = tswap32(entry_2);
2985 return 0;
2988 /* specific and weird i386 syscalls */
2989 static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
2990 unsigned long bytecount)
2992 abi_long ret;
2994 switch (func) {
2995 case 0:
2996 ret = read_ldt(ptr, bytecount);
2997 break;
2998 case 1:
2999 ret = write_ldt(env, ptr, bytecount, 1);
3000 break;
3001 case 0x11:
3002 ret = write_ldt(env, ptr, bytecount, 0);
3003 break;
3004 default:
3005 ret = -TARGET_ENOSYS;
3006 break;
3008 return ret;
3011 #if defined(TARGET_I386) && defined(TARGET_ABI32)
3012 static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
3014 uint64_t *gdt_table = g2h(env->gdt.base);
3015 struct target_modify_ldt_ldt_s ldt_info;
3016 struct target_modify_ldt_ldt_s *target_ldt_info;
3017 int seg_32bit, contents, read_exec_only, limit_in_pages;
3018 int seg_not_present, useable, lm;
3019 uint32_t *lp, entry_1, entry_2;
3020 int i;
3022 lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3023 if (!target_ldt_info)
3024 return -TARGET_EFAULT;
3025 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3026 ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
3027 ldt_info.limit = tswap32(target_ldt_info->limit);
3028 ldt_info.flags = tswap32(target_ldt_info->flags);
3029 if (ldt_info.entry_number == -1) {
3030 for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
3031 if (gdt_table[i] == 0) {
3032 ldt_info.entry_number = i;
3033 target_ldt_info->entry_number = tswap32(i);
3034 break;
3038 unlock_user_struct(target_ldt_info, ptr, 1);
3040 if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN ||
3041 ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
3042 return -TARGET_EINVAL;
3043 seg_32bit = ldt_info.flags & 1;
3044 contents = (ldt_info.flags >> 1) & 3;
3045 read_exec_only = (ldt_info.flags >> 3) & 1;
3046 limit_in_pages = (ldt_info.flags >> 4) & 1;
3047 seg_not_present = (ldt_info.flags >> 5) & 1;
3048 useable = (ldt_info.flags >> 6) & 1;
3049 #ifdef TARGET_ABI32
3050 lm = 0;
3051 #else
3052 lm = (ldt_info.flags >> 7) & 1;
3053 #endif
3055 if (contents == 3) {
3056 if (seg_not_present == 0)
3057 return -TARGET_EINVAL;
3060 /* NOTE: same code as Linux kernel */
3061 /* Allow LDTs to be cleared by the user. */
3062 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3063 if ((contents == 0 &&
3064 read_exec_only == 1 &&
3065 seg_32bit == 0 &&
3066 limit_in_pages == 0 &&
3067 seg_not_present == 1 &&
3068 useable == 0 )) {
3069 entry_1 = 0;
3070 entry_2 = 0;
3071 goto install;
3075 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
3076 (ldt_info.limit & 0x0ffff);
3077 entry_2 = (ldt_info.base_addr & 0xff000000) |
3078 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3079 (ldt_info.limit & 0xf0000) |
3080 ((read_exec_only ^ 1) << 9) |
3081 (contents << 10) |
3082 ((seg_not_present ^ 1) << 15) |
3083 (seg_32bit << 22) |
3084 (limit_in_pages << 23) |
3085 (useable << 20) |
3086 (lm << 21) |
3087 0x7000;
3089 /* Install the new entry ... */
3090 install:
3091 lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
3092 lp[0] = tswap32(entry_1);
3093 lp[1] = tswap32(entry_2);
3094 return 0;
3097 static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
3099 struct target_modify_ldt_ldt_s *target_ldt_info;
3100 uint64_t *gdt_table = g2h(env->gdt.base);
3101 uint32_t base_addr, limit, flags;
3102 int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
3103 int seg_not_present, useable, lm;
3104 uint32_t *lp, entry_1, entry_2;
3106 lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3107 if (!target_ldt_info)
3108 return -TARGET_EFAULT;
3109 idx = tswap32(target_ldt_info->entry_number);
3110 if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
3111 idx > TARGET_GDT_ENTRY_TLS_MAX) {
3112 unlock_user_struct(target_ldt_info, ptr, 1);
3113 return -TARGET_EINVAL;
3115 lp = (uint32_t *)(gdt_table + idx);
3116 entry_1 = tswap32(lp[0]);
3117 entry_2 = tswap32(lp[1]);
3119 read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
3120 contents = (entry_2 >> 10) & 3;
3121 seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
3122 seg_32bit = (entry_2 >> 22) & 1;
3123 limit_in_pages = (entry_2 >> 23) & 1;
3124 useable = (entry_2 >> 20) & 1;
3125 #ifdef TARGET_ABI32
3126 lm = 0;
3127 #else
3128 lm = (entry_2 >> 21) & 1;
3129 #endif
3130 flags = (seg_32bit << 0) | (contents << 1) |
3131 (read_exec_only << 3) | (limit_in_pages << 4) |
3132 (seg_not_present << 5) | (useable << 6) | (lm << 7);
3133 limit = (entry_1 & 0xffff) | (entry_2 & 0xf0000);
3134 base_addr = (entry_1 >> 16) |
3135 (entry_2 & 0xff000000) |
3136 ((entry_2 & 0xff) << 16);
3137 target_ldt_info->base_addr = tswapl(base_addr);
3138 target_ldt_info->limit = tswap32(limit);
3139 target_ldt_info->flags = tswap32(flags);
3140 unlock_user_struct(target_ldt_info, ptr, 1);
3141 return 0;
3143 #endif /* TARGET_I386 && TARGET_ABI32 */
3145 #ifndef TARGET_ABI32
3146 static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
3148 abi_long ret;
3149 abi_ulong val;
3150 int idx;
3152 switch(code) {
3153 case TARGET_ARCH_SET_GS:
3154 case TARGET_ARCH_SET_FS:
3155 if (code == TARGET_ARCH_SET_GS)
3156 idx = R_GS;
3157 else
3158 idx = R_FS;
3159 cpu_x86_load_seg(env, idx, 0);
3160 env->segs[idx].base = addr;
3161 break;
3162 case TARGET_ARCH_GET_GS:
3163 case TARGET_ARCH_GET_FS:
3164 if (code == TARGET_ARCH_GET_GS)
3165 idx = R_GS;
3166 else
3167 idx = R_FS;
3168 val = env->segs[idx].base;
3169 if (put_user(val, addr, abi_ulong))
3170 return -TARGET_EFAULT;
3171 break;
3172 default:
3173 ret = -TARGET_EINVAL;
3174 break;
3176 return 0;
3178 #endif
3180 #endif /* defined(TARGET_I386) */
3182 #if defined(USE_NPTL)
3184 #define NEW_STACK_SIZE PTHREAD_STACK_MIN
3186 static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
3187 typedef struct {
3188 CPUState *env;
3189 pthread_mutex_t mutex;
3190 pthread_cond_t cond;
3191 pthread_t thread;
3192 uint32_t tid;
3193 abi_ulong child_tidptr;
3194 abi_ulong parent_tidptr;
3195 sigset_t sigmask;
3196 } new_thread_info;
3198 static void *clone_func(void *arg)
3200 new_thread_info *info = arg;
3201 CPUState *env;
3203 env = info->env;
3204 thread_env = env;
3205 info->tid = gettid();
3206 env->host_tid = info->tid;
3207 if (info->child_tidptr)
3208 put_user_u32(info->tid, info->child_tidptr);
3209 if (info->parent_tidptr)
3210 put_user_u32(info->tid, info->parent_tidptr);
3211 /* Enable signals. */
3212 sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
3213 /* Signal to the parent that we're ready. */
3214 pthread_mutex_lock(&info->mutex);
3215 pthread_cond_broadcast(&info->cond);
3216 pthread_mutex_unlock(&info->mutex);
3217 /* Wait until the parent has finshed initializing the tls state. */
3218 pthread_mutex_lock(&clone_lock);
3219 pthread_mutex_unlock(&clone_lock);
3220 cpu_loop(env);
3221 /* never exits */
3222 return NULL;
3224 #else
3225 /* this stack is the equivalent of the kernel stack associated with a
3226 thread/process */
3227 #define NEW_STACK_SIZE 8192
3229 static int clone_func(void *arg)
3231 CPUState *env = arg;
3232 cpu_loop(env);
3233 /* never exits */
3234 return 0;
3236 #endif
3238 /* do_fork() Must return host values and target errnos (unlike most
3239 do_*() functions). */
3240 static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
3241 abi_ulong parent_tidptr, target_ulong newtls,
3242 abi_ulong child_tidptr)
3244 int ret;
3245 TaskState *ts;
3246 uint8_t *new_stack;
3247 CPUState *new_env;
3248 #if defined(USE_NPTL)
3249 unsigned int nptl_flags;
3250 sigset_t sigmask;
3251 #endif
3253 /* Emulate vfork() with fork() */
3254 if (flags & CLONE_VFORK)
3255 flags &= ~(CLONE_VFORK | CLONE_VM);
3257 if (flags & CLONE_VM) {
3258 #if defined(USE_NPTL)
3259 new_thread_info info;
3260 pthread_attr_t attr;
3261 #endif
3262 ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
3263 init_task_state(ts);
3264 new_stack = ts->stack;
3265 /* we create a new CPU instance. */
3266 new_env = cpu_copy(env);
3267 /* Init regs that differ from the parent. */
3268 cpu_clone_regs(new_env, newsp);
3269 new_env->opaque = ts;
3270 #if defined(USE_NPTL)
3271 nptl_flags = flags;
3272 flags &= ~CLONE_NPTL_FLAGS2;
3274 if (nptl_flags & CLONE_CHILD_CLEARTID) {
3275 ts->child_tidptr = child_tidptr;
3278 if (nptl_flags & CLONE_SETTLS)
3279 cpu_set_tls (new_env, newtls);
3281 /* Grab a mutex so that thread setup appears atomic. */
3282 pthread_mutex_lock(&clone_lock);
3284 memset(&info, 0, sizeof(info));
3285 pthread_mutex_init(&info.mutex, NULL);
3286 pthread_mutex_lock(&info.mutex);
3287 pthread_cond_init(&info.cond, NULL);
3288 info.env = new_env;
3289 if (nptl_flags & CLONE_CHILD_SETTID)
3290 info.child_tidptr = child_tidptr;
3291 if (nptl_flags & CLONE_PARENT_SETTID)
3292 info.parent_tidptr = parent_tidptr;
3294 ret = pthread_attr_init(&attr);
3295 ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE);
3296 /* It is not safe to deliver signals until the child has finished
3297 initializing, so temporarily block all signals. */
3298 sigfillset(&sigmask);
3299 sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
3301 ret = pthread_create(&info.thread, &attr, clone_func, &info);
3302 /* TODO: Free new CPU state if thread creation failed. */
3304 sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
3305 pthread_attr_destroy(&attr);
3306 if (ret == 0) {
3307 /* Wait for the child to initialize. */
3308 pthread_cond_wait(&info.cond, &info.mutex);
3309 ret = info.tid;
3310 if (flags & CLONE_PARENT_SETTID)
3311 put_user_u32(ret, parent_tidptr);
3312 } else {
3313 ret = -1;
3315 pthread_mutex_unlock(&info.mutex);
3316 pthread_cond_destroy(&info.cond);
3317 pthread_mutex_destroy(&info.mutex);
3318 pthread_mutex_unlock(&clone_lock);
3319 #else
3320 if (flags & CLONE_NPTL_FLAGS2)
3321 return -EINVAL;
3322 /* This is probably going to die very quickly, but do it anyway. */
3323 #ifdef __ia64__
3324 ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
3325 #else
3326 ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
3327 #endif
3328 #endif
3329 } else {
3330 /* if no CLONE_VM, we consider it is a fork */
3331 if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
3332 return -EINVAL;
3333 fork_start();
3334 ret = fork();
3335 if (ret == 0) {
3336 /* Child Process. */
3337 cpu_clone_regs(env, newsp);
3338 fork_end(1);
3339 #if defined(USE_NPTL)
3340 /* There is a race condition here. The parent process could
3341 theoretically read the TID in the child process before the child
3342 tid is set. This would require using either ptrace
3343 (not implemented) or having *_tidptr to point at a shared memory
3344 mapping. We can't repeat the spinlock hack used above because
3345 the child process gets its own copy of the lock. */
3346 if (flags & CLONE_CHILD_SETTID)
3347 put_user_u32(gettid(), child_tidptr);
3348 if (flags & CLONE_PARENT_SETTID)
3349 put_user_u32(gettid(), parent_tidptr);
3350 ts = (TaskState *)env->opaque;
3351 if (flags & CLONE_SETTLS)
3352 cpu_set_tls (env, newtls);
3353 if (flags & CLONE_CHILD_CLEARTID)
3354 ts->child_tidptr = child_tidptr;
3355 #endif
3356 } else {
3357 fork_end(0);
3360 return ret;
3363 static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
3365 struct flock fl;
3366 struct target_flock *target_fl;
3367 struct flock64 fl64;
3368 struct target_flock64 *target_fl64;
3369 abi_long ret;
3371 switch(cmd) {
3372 case TARGET_F_GETLK:
3373 if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3374 return -TARGET_EFAULT;
3375 fl.l_type = tswap16(target_fl->l_type);
3376 fl.l_whence = tswap16(target_fl->l_whence);
3377 fl.l_start = tswapl(target_fl->l_start);
3378 fl.l_len = tswapl(target_fl->l_len);
3379 fl.l_pid = tswapl(target_fl->l_pid);
3380 unlock_user_struct(target_fl, arg, 0);
3381 ret = get_errno(fcntl(fd, cmd, &fl));
3382 if (ret == 0) {
3383 if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
3384 return -TARGET_EFAULT;
3385 target_fl->l_type = tswap16(fl.l_type);
3386 target_fl->l_whence = tswap16(fl.l_whence);
3387 target_fl->l_start = tswapl(fl.l_start);
3388 target_fl->l_len = tswapl(fl.l_len);
3389 target_fl->l_pid = tswapl(fl.l_pid);
3390 unlock_user_struct(target_fl, arg, 1);
3392 break;
3394 case TARGET_F_SETLK:
3395 case TARGET_F_SETLKW:
3396 if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3397 return -TARGET_EFAULT;
3398 fl.l_type = tswap16(target_fl->l_type);
3399 fl.l_whence = tswap16(target_fl->l_whence);
3400 fl.l_start = tswapl(target_fl->l_start);
3401 fl.l_len = tswapl(target_fl->l_len);
3402 fl.l_pid = tswapl(target_fl->l_pid);
3403 unlock_user_struct(target_fl, arg, 0);
3404 ret = get_errno(fcntl(fd, cmd, &fl));
3405 break;
3407 case TARGET_F_GETLK64:
3408 if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3409 return -TARGET_EFAULT;
3410 fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3411 fl64.l_whence = tswap16(target_fl64->l_whence);
3412 fl64.l_start = tswapl(target_fl64->l_start);
3413 fl64.l_len = tswapl(target_fl64->l_len);
3414 fl64.l_pid = tswap16(target_fl64->l_pid);
3415 unlock_user_struct(target_fl64, arg, 0);
3416 ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
3417 if (ret == 0) {
3418 if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
3419 return -TARGET_EFAULT;
3420 target_fl64->l_type = tswap16(fl64.l_type) >> 1;
3421 target_fl64->l_whence = tswap16(fl64.l_whence);
3422 target_fl64->l_start = tswapl(fl64.l_start);
3423 target_fl64->l_len = tswapl(fl64.l_len);
3424 target_fl64->l_pid = tswapl(fl64.l_pid);
3425 unlock_user_struct(target_fl64, arg, 1);
3427 break;
3428 case TARGET_F_SETLK64:
3429 case TARGET_F_SETLKW64:
3430 if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3431 return -TARGET_EFAULT;
3432 fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3433 fl64.l_whence = tswap16(target_fl64->l_whence);
3434 fl64.l_start = tswapl(target_fl64->l_start);
3435 fl64.l_len = tswapl(target_fl64->l_len);
3436 fl64.l_pid = tswap16(target_fl64->l_pid);
3437 unlock_user_struct(target_fl64, arg, 0);
3438 ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
3439 break;
3441 case F_GETFL:
3442 ret = get_errno(fcntl(fd, cmd, arg));
3443 if (ret >= 0) {
3444 ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
3446 break;
3448 case F_SETFL:
3449 ret = get_errno(fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
3450 break;
3452 default:
3453 ret = get_errno(fcntl(fd, cmd, arg));
3454 break;
3456 return ret;
3459 #ifdef USE_UID16
3461 static inline int high2lowuid(int uid)
3463 if (uid > 65535)
3464 return 65534;
3465 else
3466 return uid;
3469 static inline int high2lowgid(int gid)
3471 if (gid > 65535)
3472 return 65534;
3473 else
3474 return gid;
3477 static inline int low2highuid(int uid)
3479 if ((int16_t)uid == -1)
3480 return -1;
3481 else
3482 return uid;
3485 static inline int low2highgid(int gid)
3487 if ((int16_t)gid == -1)
3488 return -1;
3489 else
3490 return gid;
3493 #endif /* USE_UID16 */
3495 void syscall_init(void)
3497 IOCTLEntry *ie;
3498 const argtype *arg_type;
3499 int size;
3500 int i;
3502 #define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3503 #define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3504 #include "syscall_types.h"
3505 #undef STRUCT
3506 #undef STRUCT_SPECIAL
3508 /* we patch the ioctl size if necessary. We rely on the fact that
3509 no ioctl has all the bits at '1' in the size field */
3510 ie = ioctl_entries;
3511 while (ie->target_cmd != 0) {
3512 if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
3513 TARGET_IOC_SIZEMASK) {
3514 arg_type = ie->arg_type;
3515 if (arg_type[0] != TYPE_PTR) {
3516 fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
3517 ie->target_cmd);
3518 exit(1);
3520 arg_type++;
3521 size = thunk_type_size(arg_type, 0);
3522 ie->target_cmd = (ie->target_cmd &
3523 ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
3524 (size << TARGET_IOC_SIZESHIFT);
3527 /* Build target_to_host_errno_table[] table from
3528 * host_to_target_errno_table[]. */
3529 for (i=0; i < ERRNO_TABLE_SIZE; i++)
3530 target_to_host_errno_table[host_to_target_errno_table[i]] = i;
3532 /* automatic consistency check if same arch */
3533 #if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
3534 (defined(__x86_64__) && defined(TARGET_X86_64))
3535 if (unlikely(ie->target_cmd != ie->host_cmd)) {
3536 fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
3537 ie->name, ie->target_cmd, ie->host_cmd);
3539 #endif
3540 ie++;
3544 #if TARGET_ABI_BITS == 32
3545 static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
3547 #ifdef TARGET_WORDS_BIGENDIAN
3548 return ((uint64_t)word0 << 32) | word1;
3549 #else
3550 return ((uint64_t)word1 << 32) | word0;
3551 #endif
3553 #else /* TARGET_ABI_BITS == 32 */
3554 static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
3556 return word0;
3558 #endif /* TARGET_ABI_BITS != 32 */
3560 #ifdef TARGET_NR_truncate64
3561 static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
3562 abi_long arg2,
3563 abi_long arg3,
3564 abi_long arg4)
3566 #ifdef TARGET_ARM
3567 if (((CPUARMState *)cpu_env)->eabi)
3569 arg2 = arg3;
3570 arg3 = arg4;
3572 #endif
3573 return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
3575 #endif
3577 #ifdef TARGET_NR_ftruncate64
3578 static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
3579 abi_long arg2,
3580 abi_long arg3,
3581 abi_long arg4)
3583 #ifdef TARGET_ARM
3584 if (((CPUARMState *)cpu_env)->eabi)
3586 arg2 = arg3;
3587 arg3 = arg4;
3589 #endif
3590 return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
3592 #endif
3594 static inline abi_long target_to_host_timespec(struct timespec *host_ts,
3595 abi_ulong target_addr)
3597 struct target_timespec *target_ts;
3599 if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
3600 return -TARGET_EFAULT;
3601 host_ts->tv_sec = tswapl(target_ts->tv_sec);
3602 host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
3603 unlock_user_struct(target_ts, target_addr, 0);
3604 return 0;
3607 static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3608 struct timespec *host_ts)
3610 struct target_timespec *target_ts;
3612 if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
3613 return -TARGET_EFAULT;
3614 target_ts->tv_sec = tswapl(host_ts->tv_sec);
3615 target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
3616 unlock_user_struct(target_ts, target_addr, 1);
3617 return 0;
3620 #if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
3621 static inline abi_long host_to_target_stat64(void *cpu_env,
3622 abi_ulong target_addr,
3623 struct stat *host_st)
3625 #ifdef TARGET_ARM
3626 if (((CPUARMState *)cpu_env)->eabi) {
3627 struct target_eabi_stat64 *target_st;
3629 if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3630 return -TARGET_EFAULT;
3631 memset(target_st, 0, sizeof(struct target_eabi_stat64));
3632 __put_user(host_st->st_dev, &target_st->st_dev);
3633 __put_user(host_st->st_ino, &target_st->st_ino);
3634 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3635 __put_user(host_st->st_ino, &target_st->__st_ino);
3636 #endif
3637 __put_user(host_st->st_mode, &target_st->st_mode);
3638 __put_user(host_st->st_nlink, &target_st->st_nlink);
3639 __put_user(host_st->st_uid, &target_st->st_uid);
3640 __put_user(host_st->st_gid, &target_st->st_gid);
3641 __put_user(host_st->st_rdev, &target_st->st_rdev);
3642 __put_user(host_st->st_size, &target_st->st_size);
3643 __put_user(host_st->st_blksize, &target_st->st_blksize);
3644 __put_user(host_st->st_blocks, &target_st->st_blocks);
3645 __put_user(host_st->st_atime, &target_st->target_st_atime);
3646 __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3647 __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3648 unlock_user_struct(target_st, target_addr, 1);
3649 } else
3650 #endif
3652 #if TARGET_LONG_BITS == 64
3653 struct target_stat *target_st;
3654 #else
3655 struct target_stat64 *target_st;
3656 #endif
3658 if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3659 return -TARGET_EFAULT;
3660 memset(target_st, 0, sizeof(*target_st));
3661 __put_user(host_st->st_dev, &target_st->st_dev);
3662 __put_user(host_st->st_ino, &target_st->st_ino);
3663 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3664 __put_user(host_st->st_ino, &target_st->__st_ino);
3665 #endif
3666 __put_user(host_st->st_mode, &target_st->st_mode);
3667 __put_user(host_st->st_nlink, &target_st->st_nlink);
3668 __put_user(host_st->st_uid, &target_st->st_uid);
3669 __put_user(host_st->st_gid, &target_st->st_gid);
3670 __put_user(host_st->st_rdev, &target_st->st_rdev);
3671 /* XXX: better use of kernel struct */
3672 __put_user(host_st->st_size, &target_st->st_size);
3673 __put_user(host_st->st_blksize, &target_st->st_blksize);
3674 __put_user(host_st->st_blocks, &target_st->st_blocks);
3675 __put_user(host_st->st_atime, &target_st->target_st_atime);
3676 __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3677 __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3678 unlock_user_struct(target_st, target_addr, 1);
3681 return 0;
3683 #endif
3685 #if defined(USE_NPTL)
3686 /* ??? Using host futex calls even when target atomic operations
3687 are not really atomic probably breaks things. However implementing
3688 futexes locally would make futexes shared between multiple processes
3689 tricky. However they're probably useless because guest atomic
3690 operations won't work either. */
3691 static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
3692 target_ulong uaddr2, int val3)
3694 struct timespec ts, *pts;
3696 /* ??? We assume FUTEX_* constants are the same on both host
3697 and target. */
3698 switch (op) {
3699 case FUTEX_WAIT:
3700 if (timeout) {
3701 pts = &ts;
3702 target_to_host_timespec(pts, timeout);
3703 } else {
3704 pts = NULL;
3706 return get_errno(sys_futex(g2h(uaddr), FUTEX_WAIT, tswap32(val),
3707 pts, NULL, 0));
3708 case FUTEX_WAKE:
3709 return get_errno(sys_futex(g2h(uaddr), FUTEX_WAKE, val, NULL, NULL, 0));
3710 case FUTEX_FD:
3711 return get_errno(sys_futex(g2h(uaddr), FUTEX_FD, val, NULL, NULL, 0));
3712 case FUTEX_REQUEUE:
3713 return get_errno(sys_futex(g2h(uaddr), FUTEX_REQUEUE, val,
3714 NULL, g2h(uaddr2), 0));
3715 case FUTEX_CMP_REQUEUE:
3716 return get_errno(sys_futex(g2h(uaddr), FUTEX_CMP_REQUEUE, val,
3717 NULL, g2h(uaddr2), tswap32(val3)));
3718 default:
3719 return -TARGET_ENOSYS;
3722 #endif
3724 /* Map host to target signal numbers for the wait family of syscalls.
3725 Assume all other status bits are the same. */
3726 static int host_to_target_waitstatus(int status)
3728 if (WIFSIGNALED(status)) {
3729 return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f);
3731 if (WIFSTOPPED(status)) {
3732 return (host_to_target_signal(WSTOPSIG(status)) << 8)
3733 | (status & 0xff);
3735 return status;
3738 int get_osversion(void)
3740 static int osversion;
3741 struct new_utsname buf;
3742 const char *s;
3743 int i, n, tmp;
3744 if (osversion)
3745 return osversion;
3746 if (qemu_uname_release && *qemu_uname_release) {
3747 s = qemu_uname_release;
3748 } else {
3749 if (sys_uname(&buf))
3750 return 0;
3751 s = buf.release;
3753 tmp = 0;
3754 for (i = 0; i < 3; i++) {
3755 n = 0;
3756 while (*s >= '0' && *s <= '9') {
3757 n *= 10;
3758 n += *s - '0';
3759 s++;
3761 tmp = (tmp << 8) + n;
3762 if (*s == '.')
3763 s++;
3765 osversion = tmp;
3766 return osversion;
3769 /* do_syscall() should always have a single exit point at the end so
3770 that actions, such as logging of syscall results, can be performed.
3771 All errnos that do_syscall() returns must be -TARGET_<errcode>. */
3772 abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3773 abi_long arg2, abi_long arg3, abi_long arg4,
3774 abi_long arg5, abi_long arg6)
3776 abi_long ret;
3777 struct stat st;
3778 struct statfs stfs;
3779 void *p;
3781 #ifdef DEBUG
3782 gemu_log("syscall %d", num);
3783 #endif
3784 if(do_strace)
3785 print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
3787 switch(num) {
3788 case TARGET_NR_exit:
3789 #ifdef USE_NPTL
3790 /* In old applications this may be used to implement _exit(2).
3791 However in threaded applictions it is used for thread termination,
3792 and _exit_group is used for application termination.
3793 Do thread termination if we have more then one thread. */
3794 /* FIXME: This probably breaks if a signal arrives. We should probably
3795 be disabling signals. */
3796 if (first_cpu->next_cpu) {
3797 TaskState *ts;
3798 CPUState **lastp;
3799 CPUState *p;
3801 cpu_list_lock();
3802 lastp = &first_cpu;
3803 p = first_cpu;
3804 while (p && p != (CPUState *)cpu_env) {
3805 lastp = &p->next_cpu;
3806 p = p->next_cpu;
3808 /* If we didn't find the CPU for this thread then something is
3809 horribly wrong. */
3810 if (!p)
3811 abort();
3812 /* Remove the CPU from the list. */
3813 *lastp = p->next_cpu;
3814 cpu_list_unlock();
3815 ts = ((CPUState *)cpu_env)->opaque;
3816 if (ts->child_tidptr) {
3817 put_user_u32(0, ts->child_tidptr);
3818 sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
3819 NULL, NULL, 0);
3821 /* TODO: Free CPU state. */
3822 pthread_exit(NULL);
3824 #endif
3825 #ifdef HAVE_GPROF
3826 _mcleanup();
3827 #endif
3828 gdb_exit(cpu_env, arg1);
3829 _exit(arg1);
3830 ret = 0; /* avoid warning */
3831 break;
3832 case TARGET_NR_read:
3833 if (arg3 == 0)
3834 ret = 0;
3835 else {
3836 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
3837 goto efault;
3838 ret = get_errno(read(arg1, p, arg3));
3839 unlock_user(p, arg2, ret);
3841 break;
3842 case TARGET_NR_write:
3843 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
3844 goto efault;
3845 ret = get_errno(write(arg1, p, arg3));
3846 unlock_user(p, arg2, 0);
3847 break;
3848 case TARGET_NR_open:
3849 if (!(p = lock_user_string(arg1)))
3850 goto efault;
3851 ret = get_errno(open(path(p),
3852 target_to_host_bitmask(arg2, fcntl_flags_tbl),
3853 arg3));
3854 unlock_user(p, arg1, 0);
3855 break;
3856 #if defined(TARGET_NR_openat) && defined(__NR_openat)
3857 case TARGET_NR_openat:
3858 if (!(p = lock_user_string(arg2)))
3859 goto efault;
3860 ret = get_errno(sys_openat(arg1,
3861 path(p),
3862 target_to_host_bitmask(arg3, fcntl_flags_tbl),
3863 arg4));
3864 unlock_user(p, arg2, 0);
3865 break;
3866 #endif
3867 case TARGET_NR_close:
3868 ret = get_errno(close(arg1));
3869 break;
3870 case TARGET_NR_brk:
3871 ret = do_brk(arg1);
3872 break;
3873 case TARGET_NR_fork:
3874 ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
3875 break;
3876 #ifdef TARGET_NR_waitpid
3877 case TARGET_NR_waitpid:
3879 int status;
3880 ret = get_errno(waitpid(arg1, &status, arg3));
3881 if (!is_error(ret) && arg2
3882 && put_user_s32(host_to_target_waitstatus(status), arg2))
3883 goto efault;
3885 break;
3886 #endif
3887 #ifdef TARGET_NR_waitid
3888 case TARGET_NR_waitid:
3890 siginfo_t info;
3891 info.si_pid = 0;
3892 ret = get_errno(waitid(arg1, arg2, &info, arg4));
3893 if (!is_error(ret) && arg3 && info.si_pid != 0) {
3894 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
3895 goto efault;
3896 host_to_target_siginfo(p, &info);
3897 unlock_user(p, arg3, sizeof(target_siginfo_t));
3900 break;
3901 #endif
3902 #ifdef TARGET_NR_creat /* not on alpha */
3903 case TARGET_NR_creat:
3904 if (!(p = lock_user_string(arg1)))
3905 goto efault;
3906 ret = get_errno(creat(p, arg2));
3907 unlock_user(p, arg1, 0);
3908 break;
3909 #endif
3910 case TARGET_NR_link:
3912 void * p2;
3913 p = lock_user_string(arg1);
3914 p2 = lock_user_string(arg2);
3915 if (!p || !p2)
3916 ret = -TARGET_EFAULT;
3917 else
3918 ret = get_errno(link(p, p2));
3919 unlock_user(p2, arg2, 0);
3920 unlock_user(p, arg1, 0);
3922 break;
3923 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
3924 case TARGET_NR_linkat:
3926 void * p2 = NULL;
3927 if (!arg2 || !arg4)
3928 goto efault;
3929 p = lock_user_string(arg2);
3930 p2 = lock_user_string(arg4);
3931 if (!p || !p2)
3932 ret = -TARGET_EFAULT;
3933 else
3934 ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
3935 unlock_user(p, arg2, 0);
3936 unlock_user(p2, arg4, 0);
3938 break;
3939 #endif
3940 case TARGET_NR_unlink:
3941 if (!(p = lock_user_string(arg1)))
3942 goto efault;
3943 ret = get_errno(unlink(p));
3944 unlock_user(p, arg1, 0);
3945 break;
3946 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
3947 case TARGET_NR_unlinkat:
3948 if (!(p = lock_user_string(arg2)))
3949 goto efault;
3950 ret = get_errno(sys_unlinkat(arg1, p, arg3));
3951 unlock_user(p, arg2, 0);
3952 break;
3953 #endif
3954 case TARGET_NR_execve:
3956 char **argp, **envp;
3957 int argc, envc;
3958 abi_ulong gp;
3959 abi_ulong guest_argp;
3960 abi_ulong guest_envp;
3961 abi_ulong addr;
3962 char **q;
3964 argc = 0;
3965 guest_argp = arg2;
3966 for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
3967 if (get_user_ual(addr, gp))
3968 goto efault;
3969 if (!addr)
3970 break;
3971 argc++;
3973 envc = 0;
3974 guest_envp = arg3;
3975 for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
3976 if (get_user_ual(addr, gp))
3977 goto efault;
3978 if (!addr)
3979 break;
3980 envc++;
3983 argp = alloca((argc + 1) * sizeof(void *));
3984 envp = alloca((envc + 1) * sizeof(void *));
3986 for (gp = guest_argp, q = argp; gp;
3987 gp += sizeof(abi_ulong), q++) {
3988 if (get_user_ual(addr, gp))
3989 goto execve_efault;
3990 if (!addr)
3991 break;
3992 if (!(*q = lock_user_string(addr)))
3993 goto execve_efault;
3995 *q = NULL;
3997 for (gp = guest_envp, q = envp; gp;
3998 gp += sizeof(abi_ulong), q++) {
3999 if (get_user_ual(addr, gp))
4000 goto execve_efault;
4001 if (!addr)
4002 break;
4003 if (!(*q = lock_user_string(addr)))
4004 goto execve_efault;
4006 *q = NULL;
4008 if (!(p = lock_user_string(arg1)))
4009 goto execve_efault;
4010 ret = get_errno(execve(p, argp, envp));
4011 unlock_user(p, arg1, 0);
4013 goto execve_end;
4015 execve_efault:
4016 ret = -TARGET_EFAULT;
4018 execve_end:
4019 for (gp = guest_argp, q = argp; *q;
4020 gp += sizeof(abi_ulong), q++) {
4021 if (get_user_ual(addr, gp)
4022 || !addr)
4023 break;
4024 unlock_user(*q, addr, 0);
4026 for (gp = guest_envp, q = envp; *q;
4027 gp += sizeof(abi_ulong), q++) {
4028 if (get_user_ual(addr, gp)
4029 || !addr)
4030 break;
4031 unlock_user(*q, addr, 0);
4034 break;
4035 case TARGET_NR_chdir:
4036 if (!(p = lock_user_string(arg1)))
4037 goto efault;
4038 ret = get_errno(chdir(p));
4039 unlock_user(p, arg1, 0);
4040 break;
4041 #ifdef TARGET_NR_time
4042 case TARGET_NR_time:
4044 time_t host_time;
4045 ret = get_errno(time(&host_time));
4046 if (!is_error(ret)
4047 && arg1
4048 && put_user_sal(host_time, arg1))
4049 goto efault;
4051 break;
4052 #endif
4053 case TARGET_NR_mknod:
4054 if (!(p = lock_user_string(arg1)))
4055 goto efault;
4056 ret = get_errno(mknod(p, arg2, arg3));
4057 unlock_user(p, arg1, 0);
4058 break;
4059 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
4060 case TARGET_NR_mknodat:
4061 if (!(p = lock_user_string(arg2)))
4062 goto efault;
4063 ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
4064 unlock_user(p, arg2, 0);
4065 break;
4066 #endif
4067 case TARGET_NR_chmod:
4068 if (!(p = lock_user_string(arg1)))
4069 goto efault;
4070 ret = get_errno(chmod(p, arg2));
4071 unlock_user(p, arg1, 0);
4072 break;
4073 #ifdef TARGET_NR_break
4074 case TARGET_NR_break:
4075 goto unimplemented;
4076 #endif
4077 #ifdef TARGET_NR_oldstat
4078 case TARGET_NR_oldstat:
4079 goto unimplemented;
4080 #endif
4081 case TARGET_NR_lseek:
4082 ret = get_errno(lseek(arg1, arg2, arg3));
4083 break;
4084 #ifdef TARGET_NR_getxpid
4085 case TARGET_NR_getxpid:
4086 #else
4087 case TARGET_NR_getpid:
4088 #endif
4089 ret = get_errno(getpid());
4090 break;
4091 case TARGET_NR_mount:
4093 /* need to look at the data field */
4094 void *p2, *p3;
4095 p = lock_user_string(arg1);
4096 p2 = lock_user_string(arg2);
4097 p3 = lock_user_string(arg3);
4098 if (!p || !p2 || !p3)
4099 ret = -TARGET_EFAULT;
4100 else
4101 /* FIXME - arg5 should be locked, but it isn't clear how to
4102 * do that since it's not guaranteed to be a NULL-terminated
4103 * string.
4105 ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
4106 unlock_user(p, arg1, 0);
4107 unlock_user(p2, arg2, 0);
4108 unlock_user(p3, arg3, 0);
4109 break;
4111 #ifdef TARGET_NR_umount
4112 case TARGET_NR_umount:
4113 if (!(p = lock_user_string(arg1)))
4114 goto efault;
4115 ret = get_errno(umount(p));
4116 unlock_user(p, arg1, 0);
4117 break;
4118 #endif
4119 #ifdef TARGET_NR_stime /* not on alpha */
4120 case TARGET_NR_stime:
4122 time_t host_time;
4123 if (get_user_sal(host_time, arg1))
4124 goto efault;
4125 ret = get_errno(stime(&host_time));
4127 break;
4128 #endif
4129 case TARGET_NR_ptrace:
4130 goto unimplemented;
4131 #ifdef TARGET_NR_alarm /* not on alpha */
4132 case TARGET_NR_alarm:
4133 ret = alarm(arg1);
4134 break;
4135 #endif
4136 #ifdef TARGET_NR_oldfstat
4137 case TARGET_NR_oldfstat:
4138 goto unimplemented;
4139 #endif
4140 #ifdef TARGET_NR_pause /* not on alpha */
4141 case TARGET_NR_pause:
4142 ret = get_errno(pause());
4143 break;
4144 #endif
4145 #ifdef TARGET_NR_utime
4146 case TARGET_NR_utime:
4148 struct utimbuf tbuf, *host_tbuf;
4149 struct target_utimbuf *target_tbuf;
4150 if (arg2) {
4151 if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
4152 goto efault;
4153 tbuf.actime = tswapl(target_tbuf->actime);
4154 tbuf.modtime = tswapl(target_tbuf->modtime);
4155 unlock_user_struct(target_tbuf, arg2, 0);
4156 host_tbuf = &tbuf;
4157 } else {
4158 host_tbuf = NULL;
4160 if (!(p = lock_user_string(arg1)))
4161 goto efault;
4162 ret = get_errno(utime(p, host_tbuf));
4163 unlock_user(p, arg1, 0);
4165 break;
4166 #endif
4167 #ifdef TARGET_NR_utimes
4168 case TARGET_NR_utimes:
4170 struct timeval *tvp, tv[2];
4171 if (arg2) {
4172 if (copy_from_user_timeval(&tv[0], arg2)
4173 || copy_from_user_timeval(&tv[1],
4174 arg2 + sizeof(struct target_timeval)))
4175 goto efault;
4176 tvp = tv;
4177 } else {
4178 tvp = NULL;
4180 if (!(p = lock_user_string(arg1)))
4181 goto efault;
4182 ret = get_errno(utimes(p, tvp));
4183 unlock_user(p, arg1, 0);
4185 break;
4186 #endif
4187 #if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
4188 case TARGET_NR_futimesat:
4190 struct timeval *tvp, tv[2];
4191 if (arg3) {
4192 if (copy_from_user_timeval(&tv[0], arg3)
4193 || copy_from_user_timeval(&tv[1],
4194 arg3 + sizeof(struct target_timeval)))
4195 goto efault;
4196 tvp = tv;
4197 } else {
4198 tvp = NULL;
4200 if (!(p = lock_user_string(arg2)))
4201 goto efault;
4202 ret = get_errno(sys_futimesat(arg1, path(p), tvp));
4203 unlock_user(p, arg2, 0);
4205 break;
4206 #endif
4207 #ifdef TARGET_NR_stty
4208 case TARGET_NR_stty:
4209 goto unimplemented;
4210 #endif
4211 #ifdef TARGET_NR_gtty
4212 case TARGET_NR_gtty:
4213 goto unimplemented;
4214 #endif
4215 case TARGET_NR_access:
4216 if (!(p = lock_user_string(arg1)))
4217 goto efault;
4218 ret = get_errno(access(p, arg2));
4219 unlock_user(p, arg1, 0);
4220 break;
4221 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
4222 case TARGET_NR_faccessat:
4223 if (!(p = lock_user_string(arg2)))
4224 goto efault;
4225 ret = get_errno(sys_faccessat(arg1, p, arg3));
4226 unlock_user(p, arg2, 0);
4227 break;
4228 #endif
4229 #ifdef TARGET_NR_nice /* not on alpha */
4230 case TARGET_NR_nice:
4231 ret = get_errno(nice(arg1));
4232 break;
4233 #endif
4234 #ifdef TARGET_NR_ftime
4235 case TARGET_NR_ftime:
4236 goto unimplemented;
4237 #endif
4238 case TARGET_NR_sync:
4239 sync();
4240 ret = 0;
4241 break;
4242 case TARGET_NR_kill:
4243 ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
4244 break;
4245 case TARGET_NR_rename:
4247 void *p2;
4248 p = lock_user_string(arg1);
4249 p2 = lock_user_string(arg2);
4250 if (!p || !p2)
4251 ret = -TARGET_EFAULT;
4252 else
4253 ret = get_errno(rename(p, p2));
4254 unlock_user(p2, arg2, 0);
4255 unlock_user(p, arg1, 0);
4257 break;
4258 #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
4259 case TARGET_NR_renameat:
4261 void *p2;
4262 p = lock_user_string(arg2);
4263 p2 = lock_user_string(arg4);
4264 if (!p || !p2)
4265 ret = -TARGET_EFAULT;
4266 else
4267 ret = get_errno(sys_renameat(arg1, p, arg3, p2));
4268 unlock_user(p2, arg4, 0);
4269 unlock_user(p, arg2, 0);
4271 break;
4272 #endif
4273 case TARGET_NR_mkdir:
4274 if (!(p = lock_user_string(arg1)))
4275 goto efault;
4276 ret = get_errno(mkdir(p, arg2));
4277 unlock_user(p, arg1, 0);
4278 break;
4279 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
4280 case TARGET_NR_mkdirat:
4281 if (!(p = lock_user_string(arg2)))
4282 goto efault;
4283 ret = get_errno(sys_mkdirat(arg1, p, arg3));
4284 unlock_user(p, arg2, 0);
4285 break;
4286 #endif
4287 case TARGET_NR_rmdir:
4288 if (!(p = lock_user_string(arg1)))
4289 goto efault;
4290 ret = get_errno(rmdir(p));
4291 unlock_user(p, arg1, 0);
4292 break;
4293 case TARGET_NR_dup:
4294 ret = get_errno(dup(arg1));
4295 break;
4296 case TARGET_NR_pipe:
4298 int host_pipe[2];
4299 ret = get_errno(pipe(host_pipe));
4300 if (!is_error(ret)) {
4301 #if defined(TARGET_MIPS)
4302 CPUMIPSState *env = (CPUMIPSState*)cpu_env;
4303 env->active_tc.gpr[3] = host_pipe[1];
4304 ret = host_pipe[0];
4305 #elif defined(TARGET_SH4)
4306 ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
4307 ret = host_pipe[0];
4308 #else
4309 if (put_user_s32(host_pipe[0], arg1)
4310 || put_user_s32(host_pipe[1], arg1 + sizeof(host_pipe[0])))
4311 goto efault;
4312 #endif
4315 break;
4316 case TARGET_NR_times:
4318 struct target_tms *tmsp;
4319 struct tms tms;
4320 ret = get_errno(times(&tms));
4321 if (arg1) {
4322 tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
4323 if (!tmsp)
4324 goto efault;
4325 tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
4326 tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
4327 tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
4328 tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime));
4330 if (!is_error(ret))
4331 ret = host_to_target_clock_t(ret);
4333 break;
4334 #ifdef TARGET_NR_prof
4335 case TARGET_NR_prof:
4336 goto unimplemented;
4337 #endif
4338 #ifdef TARGET_NR_signal
4339 case TARGET_NR_signal:
4340 goto unimplemented;
4341 #endif
4342 case TARGET_NR_acct:
4343 if (arg1 == 0) {
4344 ret = get_errno(acct(NULL));
4345 } else {
4346 if (!(p = lock_user_string(arg1)))
4347 goto efault;
4348 ret = get_errno(acct(path(p)));
4349 unlock_user(p, arg1, 0);
4351 break;
4352 #ifdef TARGET_NR_umount2 /* not on alpha */
4353 case TARGET_NR_umount2:
4354 if (!(p = lock_user_string(arg1)))
4355 goto efault;
4356 ret = get_errno(umount2(p, arg2));
4357 unlock_user(p, arg1, 0);
4358 break;
4359 #endif
4360 #ifdef TARGET_NR_lock
4361 case TARGET_NR_lock:
4362 goto unimplemented;
4363 #endif
4364 case TARGET_NR_ioctl:
4365 ret = do_ioctl(arg1, arg2, arg3);
4366 break;
4367 case TARGET_NR_fcntl:
4368 ret = do_fcntl(arg1, arg2, arg3);
4369 break;
4370 #ifdef TARGET_NR_mpx
4371 case TARGET_NR_mpx:
4372 goto unimplemented;
4373 #endif
4374 case TARGET_NR_setpgid:
4375 ret = get_errno(setpgid(arg1, arg2));
4376 break;
4377 #ifdef TARGET_NR_ulimit
4378 case TARGET_NR_ulimit:
4379 goto unimplemented;
4380 #endif
4381 #ifdef TARGET_NR_oldolduname
4382 case TARGET_NR_oldolduname:
4383 goto unimplemented;
4384 #endif
4385 case TARGET_NR_umask:
4386 ret = get_errno(umask(arg1));
4387 break;
4388 case TARGET_NR_chroot:
4389 if (!(p = lock_user_string(arg1)))
4390 goto efault;
4391 ret = get_errno(chroot(p));
4392 unlock_user(p, arg1, 0);
4393 break;
4394 case TARGET_NR_ustat:
4395 goto unimplemented;
4396 case TARGET_NR_dup2:
4397 ret = get_errno(dup2(arg1, arg2));
4398 break;
4399 #ifdef TARGET_NR_getppid /* not on alpha */
4400 case TARGET_NR_getppid:
4401 ret = get_errno(getppid());
4402 break;
4403 #endif
4404 case TARGET_NR_getpgrp:
4405 ret = get_errno(getpgrp());
4406 break;
4407 case TARGET_NR_setsid:
4408 ret = get_errno(setsid());
4409 break;
4410 #ifdef TARGET_NR_sigaction
4411 case TARGET_NR_sigaction:
4413 #if !defined(TARGET_MIPS)
4414 struct target_old_sigaction *old_act;
4415 struct target_sigaction act, oact, *pact;
4416 if (arg2) {
4417 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4418 goto efault;
4419 act._sa_handler = old_act->_sa_handler;
4420 target_siginitset(&act.sa_mask, old_act->sa_mask);
4421 act.sa_flags = old_act->sa_flags;
4422 act.sa_restorer = old_act->sa_restorer;
4423 unlock_user_struct(old_act, arg2, 0);
4424 pact = &act;
4425 } else {
4426 pact = NULL;
4428 ret = get_errno(do_sigaction(arg1, pact, &oact));
4429 if (!is_error(ret) && arg3) {
4430 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4431 goto efault;
4432 old_act->_sa_handler = oact._sa_handler;
4433 old_act->sa_mask = oact.sa_mask.sig[0];
4434 old_act->sa_flags = oact.sa_flags;
4435 old_act->sa_restorer = oact.sa_restorer;
4436 unlock_user_struct(old_act, arg3, 1);
4438 #else
4439 struct target_sigaction act, oact, *pact, *old_act;
4441 if (arg2) {
4442 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4443 goto efault;
4444 act._sa_handler = old_act->_sa_handler;
4445 target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
4446 act.sa_flags = old_act->sa_flags;
4447 unlock_user_struct(old_act, arg2, 0);
4448 pact = &act;
4449 } else {
4450 pact = NULL;
4453 ret = get_errno(do_sigaction(arg1, pact, &oact));
4455 if (!is_error(ret) && arg3) {
4456 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4457 goto efault;
4458 old_act->_sa_handler = oact._sa_handler;
4459 old_act->sa_flags = oact.sa_flags;
4460 old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
4461 old_act->sa_mask.sig[1] = 0;
4462 old_act->sa_mask.sig[2] = 0;
4463 old_act->sa_mask.sig[3] = 0;
4464 unlock_user_struct(old_act, arg3, 1);
4466 #endif
4468 break;
4469 #endif
4470 case TARGET_NR_rt_sigaction:
4472 struct target_sigaction *act;
4473 struct target_sigaction *oact;
4475 if (arg2) {
4476 if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
4477 goto efault;
4478 } else
4479 act = NULL;
4480 if (arg3) {
4481 if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
4482 ret = -TARGET_EFAULT;
4483 goto rt_sigaction_fail;
4485 } else
4486 oact = NULL;
4487 ret = get_errno(do_sigaction(arg1, act, oact));
4488 rt_sigaction_fail:
4489 if (act)
4490 unlock_user_struct(act, arg2, 0);
4491 if (oact)
4492 unlock_user_struct(oact, arg3, 1);
4494 break;
4495 #ifdef TARGET_NR_sgetmask /* not on alpha */
4496 case TARGET_NR_sgetmask:
4498 sigset_t cur_set;
4499 abi_ulong target_set;
4500 sigprocmask(0, NULL, &cur_set);
4501 host_to_target_old_sigset(&target_set, &cur_set);
4502 ret = target_set;
4504 break;
4505 #endif
4506 #ifdef TARGET_NR_ssetmask /* not on alpha */
4507 case TARGET_NR_ssetmask:
4509 sigset_t set, oset, cur_set;
4510 abi_ulong target_set = arg1;
4511 sigprocmask(0, NULL, &cur_set);
4512 target_to_host_old_sigset(&set, &target_set);
4513 sigorset(&set, &set, &cur_set);
4514 sigprocmask(SIG_SETMASK, &set, &oset);
4515 host_to_target_old_sigset(&target_set, &oset);
4516 ret = target_set;
4518 break;
4519 #endif
4520 #ifdef TARGET_NR_sigprocmask
4521 case TARGET_NR_sigprocmask:
4523 int how = arg1;
4524 sigset_t set, oldset, *set_ptr;
4526 if (arg2) {
4527 switch(how) {
4528 case TARGET_SIG_BLOCK:
4529 how = SIG_BLOCK;
4530 break;
4531 case TARGET_SIG_UNBLOCK:
4532 how = SIG_UNBLOCK;
4533 break;
4534 case TARGET_SIG_SETMASK:
4535 how = SIG_SETMASK;
4536 break;
4537 default:
4538 ret = -TARGET_EINVAL;
4539 goto fail;
4541 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4542 goto efault;
4543 target_to_host_old_sigset(&set, p);
4544 unlock_user(p, arg2, 0);
4545 set_ptr = &set;
4546 } else {
4547 how = 0;
4548 set_ptr = NULL;
4550 ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
4551 if (!is_error(ret) && arg3) {
4552 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4553 goto efault;
4554 host_to_target_old_sigset(p, &oldset);
4555 unlock_user(p, arg3, sizeof(target_sigset_t));
4558 break;
4559 #endif
4560 case TARGET_NR_rt_sigprocmask:
4562 int how = arg1;
4563 sigset_t set, oldset, *set_ptr;
4565 if (arg2) {
4566 switch(how) {
4567 case TARGET_SIG_BLOCK:
4568 how = SIG_BLOCK;
4569 break;
4570 case TARGET_SIG_UNBLOCK:
4571 how = SIG_UNBLOCK;
4572 break;
4573 case TARGET_SIG_SETMASK:
4574 how = SIG_SETMASK;
4575 break;
4576 default:
4577 ret = -TARGET_EINVAL;
4578 goto fail;
4580 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4581 goto efault;
4582 target_to_host_sigset(&set, p);
4583 unlock_user(p, arg2, 0);
4584 set_ptr = &set;
4585 } else {
4586 how = 0;
4587 set_ptr = NULL;
4589 ret = get_errno(sigprocmask(how, set_ptr, &oldset));
4590 if (!is_error(ret) && arg3) {
4591 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4592 goto efault;
4593 host_to_target_sigset(p, &oldset);
4594 unlock_user(p, arg3, sizeof(target_sigset_t));
4597 break;
4598 #ifdef TARGET_NR_sigpending
4599 case TARGET_NR_sigpending:
4601 sigset_t set;
4602 ret = get_errno(sigpending(&set));
4603 if (!is_error(ret)) {
4604 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4605 goto efault;
4606 host_to_target_old_sigset(p, &set);
4607 unlock_user(p, arg1, sizeof(target_sigset_t));
4610 break;
4611 #endif
4612 case TARGET_NR_rt_sigpending:
4614 sigset_t set;
4615 ret = get_errno(sigpending(&set));
4616 if (!is_error(ret)) {
4617 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4618 goto efault;
4619 host_to_target_sigset(p, &set);
4620 unlock_user(p, arg1, sizeof(target_sigset_t));
4623 break;
4624 #ifdef TARGET_NR_sigsuspend
4625 case TARGET_NR_sigsuspend:
4627 sigset_t set;
4628 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4629 goto efault;
4630 target_to_host_old_sigset(&set, p);
4631 unlock_user(p, arg1, 0);
4632 ret = get_errno(sigsuspend(&set));
4634 break;
4635 #endif
4636 case TARGET_NR_rt_sigsuspend:
4638 sigset_t set;
4639 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4640 goto efault;
4641 target_to_host_sigset(&set, p);
4642 unlock_user(p, arg1, 0);
4643 ret = get_errno(sigsuspend(&set));
4645 break;
4646 case TARGET_NR_rt_sigtimedwait:
4648 sigset_t set;
4649 struct timespec uts, *puts;
4650 siginfo_t uinfo;
4652 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4653 goto efault;
4654 target_to_host_sigset(&set, p);
4655 unlock_user(p, arg1, 0);
4656 if (arg3) {
4657 puts = &uts;
4658 target_to_host_timespec(puts, arg3);
4659 } else {
4660 puts = NULL;
4662 ret = get_errno(sigtimedwait(&set, &uinfo, puts));
4663 if (!is_error(ret) && arg2) {
4664 if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
4665 goto efault;
4666 host_to_target_siginfo(p, &uinfo);
4667 unlock_user(p, arg2, sizeof(target_siginfo_t));
4670 break;
4671 case TARGET_NR_rt_sigqueueinfo:
4673 siginfo_t uinfo;
4674 if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
4675 goto efault;
4676 target_to_host_siginfo(&uinfo, p);
4677 unlock_user(p, arg1, 0);
4678 ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
4680 break;
4681 #ifdef TARGET_NR_sigreturn
4682 case TARGET_NR_sigreturn:
4683 /* NOTE: ret is eax, so not transcoding must be done */
4684 ret = do_sigreturn(cpu_env);
4685 break;
4686 #endif
4687 case TARGET_NR_rt_sigreturn:
4688 /* NOTE: ret is eax, so not transcoding must be done */
4689 ret = do_rt_sigreturn(cpu_env);
4690 break;
4691 case TARGET_NR_sethostname:
4692 if (!(p = lock_user_string(arg1)))
4693 goto efault;
4694 ret = get_errno(sethostname(p, arg2));
4695 unlock_user(p, arg1, 0);
4696 break;
4697 case TARGET_NR_setrlimit:
4699 /* XXX: convert resource ? */
4700 int resource = arg1;
4701 struct target_rlimit *target_rlim;
4702 struct rlimit rlim;
4703 if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
4704 goto efault;
4705 rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4706 rlim.rlim_max = tswapl(target_rlim->rlim_max);
4707 unlock_user_struct(target_rlim, arg2, 0);
4708 ret = get_errno(setrlimit(resource, &rlim));
4710 break;
4711 case TARGET_NR_getrlimit:
4713 /* XXX: convert resource ? */
4714 int resource = arg1;
4715 struct target_rlimit *target_rlim;
4716 struct rlimit rlim;
4718 ret = get_errno(getrlimit(resource, &rlim));
4719 if (!is_error(ret)) {
4720 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
4721 goto efault;
4722 rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4723 rlim.rlim_max = tswapl(target_rlim->rlim_max);
4724 unlock_user_struct(target_rlim, arg2, 1);
4727 break;
4728 case TARGET_NR_getrusage:
4730 struct rusage rusage;
4731 ret = get_errno(getrusage(arg1, &rusage));
4732 if (!is_error(ret)) {
4733 host_to_target_rusage(arg2, &rusage);
4736 break;
4737 case TARGET_NR_gettimeofday:
4739 struct timeval tv;
4740 ret = get_errno(gettimeofday(&tv, NULL));
4741 if (!is_error(ret)) {
4742 if (copy_to_user_timeval(arg1, &tv))
4743 goto efault;
4746 break;
4747 case TARGET_NR_settimeofday:
4749 struct timeval tv;
4750 if (copy_from_user_timeval(&tv, arg1))
4751 goto efault;
4752 ret = get_errno(settimeofday(&tv, NULL));
4754 break;
4755 #ifdef TARGET_NR_select
4756 case TARGET_NR_select:
4758 struct target_sel_arg_struct *sel;
4759 abi_ulong inp, outp, exp, tvp;
4760 long nsel;
4762 if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
4763 goto efault;
4764 nsel = tswapl(sel->n);
4765 inp = tswapl(sel->inp);
4766 outp = tswapl(sel->outp);
4767 exp = tswapl(sel->exp);
4768 tvp = tswapl(sel->tvp);
4769 unlock_user_struct(sel, arg1, 0);
4770 ret = do_select(nsel, inp, outp, exp, tvp);
4772 break;
4773 #endif
4774 case TARGET_NR_symlink:
4776 void *p2;
4777 p = lock_user_string(arg1);
4778 p2 = lock_user_string(arg2);
4779 if (!p || !p2)
4780 ret = -TARGET_EFAULT;
4781 else
4782 ret = get_errno(symlink(p, p2));
4783 unlock_user(p2, arg2, 0);
4784 unlock_user(p, arg1, 0);
4786 break;
4787 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
4788 case TARGET_NR_symlinkat:
4790 void *p2;
4791 p = lock_user_string(arg1);
4792 p2 = lock_user_string(arg3);
4793 if (!p || !p2)
4794 ret = -TARGET_EFAULT;
4795 else
4796 ret = get_errno(sys_symlinkat(p, arg2, p2));
4797 unlock_user(p2, arg3, 0);
4798 unlock_user(p, arg1, 0);
4800 break;
4801 #endif
4802 #ifdef TARGET_NR_oldlstat
4803 case TARGET_NR_oldlstat:
4804 goto unimplemented;
4805 #endif
4806 case TARGET_NR_readlink:
4808 void *p2, *temp;
4809 p = lock_user_string(arg1);
4810 p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
4811 if (!p || !p2)
4812 ret = -TARGET_EFAULT;
4813 else {
4814 if (strncmp((const char *)p, "/proc/self/exe", 14) == 0) {
4815 char real[PATH_MAX];
4816 temp = realpath(exec_path,real);
4817 ret = (temp==NULL) ? get_errno(-1) : strlen(real) ;
4818 snprintf((char *)p2, arg3, "%s", real);
4820 else
4821 ret = get_errno(readlink(path(p), p2, arg3));
4823 unlock_user(p2, arg2, ret);
4824 unlock_user(p, arg1, 0);
4826 break;
4827 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
4828 case TARGET_NR_readlinkat:
4830 void *p2;
4831 p = lock_user_string(arg2);
4832 p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
4833 if (!p || !p2)
4834 ret = -TARGET_EFAULT;
4835 else
4836 ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
4837 unlock_user(p2, arg3, ret);
4838 unlock_user(p, arg2, 0);
4840 break;
4841 #endif
4842 #ifdef TARGET_NR_uselib
4843 case TARGET_NR_uselib:
4844 goto unimplemented;
4845 #endif
4846 #ifdef TARGET_NR_swapon
4847 case TARGET_NR_swapon:
4848 if (!(p = lock_user_string(arg1)))
4849 goto efault;
4850 ret = get_errno(swapon(p, arg2));
4851 unlock_user(p, arg1, 0);
4852 break;
4853 #endif
4854 case TARGET_NR_reboot:
4855 goto unimplemented;
4856 #ifdef TARGET_NR_readdir
4857 case TARGET_NR_readdir:
4858 goto unimplemented;
4859 #endif
4860 #ifdef TARGET_NR_mmap
4861 case TARGET_NR_mmap:
4862 #if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE)
4864 abi_ulong *v;
4865 abi_ulong v1, v2, v3, v4, v5, v6;
4866 if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
4867 goto efault;
4868 v1 = tswapl(v[0]);
4869 v2 = tswapl(v[1]);
4870 v3 = tswapl(v[2]);
4871 v4 = tswapl(v[3]);
4872 v5 = tswapl(v[4]);
4873 v6 = tswapl(v[5]);
4874 unlock_user(v, arg1, 0);
4875 ret = get_errno(target_mmap(v1, v2, v3,
4876 target_to_host_bitmask(v4, mmap_flags_tbl),
4877 v5, v6));
4879 #else
4880 ret = get_errno(target_mmap(arg1, arg2, arg3,
4881 target_to_host_bitmask(arg4, mmap_flags_tbl),
4882 arg5,
4883 arg6));
4884 #endif
4885 break;
4886 #endif
4887 #ifdef TARGET_NR_mmap2
4888 case TARGET_NR_mmap2:
4889 #ifndef MMAP_SHIFT
4890 #define MMAP_SHIFT 12
4891 #endif
4892 ret = get_errno(target_mmap(arg1, arg2, arg3,
4893 target_to_host_bitmask(arg4, mmap_flags_tbl),
4894 arg5,
4895 arg6 << MMAP_SHIFT));
4896 break;
4897 #endif
4898 case TARGET_NR_munmap:
4899 ret = get_errno(target_munmap(arg1, arg2));
4900 break;
4901 case TARGET_NR_mprotect:
4902 ret = get_errno(target_mprotect(arg1, arg2, arg3));
4903 break;
4904 #ifdef TARGET_NR_mremap
4905 case TARGET_NR_mremap:
4906 ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
4907 break;
4908 #endif
4909 /* ??? msync/mlock/munlock are broken for softmmu. */
4910 #ifdef TARGET_NR_msync
4911 case TARGET_NR_msync:
4912 ret = get_errno(msync(g2h(arg1), arg2, arg3));
4913 break;
4914 #endif
4915 #ifdef TARGET_NR_mlock
4916 case TARGET_NR_mlock:
4917 ret = get_errno(mlock(g2h(arg1), arg2));
4918 break;
4919 #endif
4920 #ifdef TARGET_NR_munlock
4921 case TARGET_NR_munlock:
4922 ret = get_errno(munlock(g2h(arg1), arg2));
4923 break;
4924 #endif
4925 #ifdef TARGET_NR_mlockall
4926 case TARGET_NR_mlockall:
4927 ret = get_errno(mlockall(arg1));
4928 break;
4929 #endif
4930 #ifdef TARGET_NR_munlockall
4931 case TARGET_NR_munlockall:
4932 ret = get_errno(munlockall());
4933 break;
4934 #endif
4935 case TARGET_NR_truncate:
4936 if (!(p = lock_user_string(arg1)))
4937 goto efault;
4938 ret = get_errno(truncate(p, arg2));
4939 unlock_user(p, arg1, 0);
4940 break;
4941 case TARGET_NR_ftruncate:
4942 ret = get_errno(ftruncate(arg1, arg2));
4943 break;
4944 case TARGET_NR_fchmod:
4945 ret = get_errno(fchmod(arg1, arg2));
4946 break;
4947 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
4948 case TARGET_NR_fchmodat:
4949 if (!(p = lock_user_string(arg2)))
4950 goto efault;
4951 ret = get_errno(sys_fchmodat(arg1, p, arg3));
4952 unlock_user(p, arg2, 0);
4953 break;
4954 #endif
4955 case TARGET_NR_getpriority:
4956 /* libc does special remapping of the return value of
4957 * sys_getpriority() so it's just easiest to call
4958 * sys_getpriority() directly rather than through libc. */
4959 ret = sys_getpriority(arg1, arg2);
4960 break;
4961 case TARGET_NR_setpriority:
4962 ret = get_errno(setpriority(arg1, arg2, arg3));
4963 break;
4964 #ifdef TARGET_NR_profil
4965 case TARGET_NR_profil:
4966 goto unimplemented;
4967 #endif
4968 case TARGET_NR_statfs:
4969 if (!(p = lock_user_string(arg1)))
4970 goto efault;
4971 ret = get_errno(statfs(path(p), &stfs));
4972 unlock_user(p, arg1, 0);
4973 convert_statfs:
4974 if (!is_error(ret)) {
4975 struct target_statfs *target_stfs;
4977 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
4978 goto efault;
4979 __put_user(stfs.f_type, &target_stfs->f_type);
4980 __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4981 __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4982 __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4983 __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4984 __put_user(stfs.f_files, &target_stfs->f_files);
4985 __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4986 __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4987 __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4988 __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4989 unlock_user_struct(target_stfs, arg2, 1);
4991 break;
4992 case TARGET_NR_fstatfs:
4993 ret = get_errno(fstatfs(arg1, &stfs));
4994 goto convert_statfs;
4995 #ifdef TARGET_NR_statfs64
4996 case TARGET_NR_statfs64:
4997 if (!(p = lock_user_string(arg1)))
4998 goto efault;
4999 ret = get_errno(statfs(path(p), &stfs));
5000 unlock_user(p, arg1, 0);
5001 convert_statfs64:
5002 if (!is_error(ret)) {
5003 struct target_statfs64 *target_stfs;
5005 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
5006 goto efault;
5007 __put_user(stfs.f_type, &target_stfs->f_type);
5008 __put_user(stfs.f_bsize, &target_stfs->f_bsize);
5009 __put_user(stfs.f_blocks, &target_stfs->f_blocks);
5010 __put_user(stfs.f_bfree, &target_stfs->f_bfree);
5011 __put_user(stfs.f_bavail, &target_stfs->f_bavail);
5012 __put_user(stfs.f_files, &target_stfs->f_files);
5013 __put_user(stfs.f_ffree, &target_stfs->f_ffree);
5014 __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
5015 __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
5016 __put_user(stfs.f_namelen, &target_stfs->f_namelen);
5017 unlock_user_struct(target_stfs, arg3, 1);
5019 break;
5020 case TARGET_NR_fstatfs64:
5021 ret = get_errno(fstatfs(arg1, &stfs));
5022 goto convert_statfs64;
5023 #endif
5024 #ifdef TARGET_NR_ioperm
5025 case TARGET_NR_ioperm:
5026 goto unimplemented;
5027 #endif
5028 #ifdef TARGET_NR_socketcall
5029 case TARGET_NR_socketcall:
5030 ret = do_socketcall(arg1, arg2);
5031 break;
5032 #endif
5033 #ifdef TARGET_NR_accept
5034 case TARGET_NR_accept:
5035 ret = do_accept(arg1, arg2, arg3);
5036 break;
5037 #endif
5038 #ifdef TARGET_NR_bind
5039 case TARGET_NR_bind:
5040 ret = do_bind(arg1, arg2, arg3);
5041 break;
5042 #endif
5043 #ifdef TARGET_NR_connect
5044 case TARGET_NR_connect:
5045 ret = do_connect(arg1, arg2, arg3);
5046 break;
5047 #endif
5048 #ifdef TARGET_NR_getpeername
5049 case TARGET_NR_getpeername:
5050 ret = do_getpeername(arg1, arg2, arg3);
5051 break;
5052 #endif
5053 #ifdef TARGET_NR_getsockname
5054 case TARGET_NR_getsockname:
5055 ret = do_getsockname(arg1, arg2, arg3);
5056 break;
5057 #endif
5058 #ifdef TARGET_NR_getsockopt
5059 case TARGET_NR_getsockopt:
5060 ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
5061 break;
5062 #endif
5063 #ifdef TARGET_NR_listen
5064 case TARGET_NR_listen:
5065 ret = get_errno(listen(arg1, arg2));
5066 break;
5067 #endif
5068 #ifdef TARGET_NR_recv
5069 case TARGET_NR_recv:
5070 ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
5071 break;
5072 #endif
5073 #ifdef TARGET_NR_recvfrom
5074 case TARGET_NR_recvfrom:
5075 ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
5076 break;
5077 #endif
5078 #ifdef TARGET_NR_recvmsg
5079 case TARGET_NR_recvmsg:
5080 ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
5081 break;
5082 #endif
5083 #ifdef TARGET_NR_send
5084 case TARGET_NR_send:
5085 ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
5086 break;
5087 #endif
5088 #ifdef TARGET_NR_sendmsg
5089 case TARGET_NR_sendmsg:
5090 ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
5091 break;
5092 #endif
5093 #ifdef TARGET_NR_sendto
5094 case TARGET_NR_sendto:
5095 ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
5096 break;
5097 #endif
5098 #ifdef TARGET_NR_shutdown
5099 case TARGET_NR_shutdown:
5100 ret = get_errno(shutdown(arg1, arg2));
5101 break;
5102 #endif
5103 #ifdef TARGET_NR_socket
5104 case TARGET_NR_socket:
5105 ret = do_socket(arg1, arg2, arg3);
5106 break;
5107 #endif
5108 #ifdef TARGET_NR_socketpair
5109 case TARGET_NR_socketpair:
5110 ret = do_socketpair(arg1, arg2, arg3, arg4);
5111 break;
5112 #endif
5113 #ifdef TARGET_NR_setsockopt
5114 case TARGET_NR_setsockopt:
5115 ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
5116 break;
5117 #endif
5119 case TARGET_NR_syslog:
5120 if (!(p = lock_user_string(arg2)))
5121 goto efault;
5122 ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
5123 unlock_user(p, arg2, 0);
5124 break;
5126 case TARGET_NR_setitimer:
5128 struct itimerval value, ovalue, *pvalue;
5130 if (arg2) {
5131 pvalue = &value;
5132 if (copy_from_user_timeval(&pvalue->it_interval, arg2)
5133 || copy_from_user_timeval(&pvalue->it_value,
5134 arg2 + sizeof(struct target_timeval)))
5135 goto efault;
5136 } else {
5137 pvalue = NULL;
5139 ret = get_errno(setitimer(arg1, pvalue, &ovalue));
5140 if (!is_error(ret) && arg3) {
5141 if (copy_to_user_timeval(arg3,
5142 &ovalue.it_interval)
5143 || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
5144 &ovalue.it_value))
5145 goto efault;
5148 break;
5149 case TARGET_NR_getitimer:
5151 struct itimerval value;
5153 ret = get_errno(getitimer(arg1, &value));
5154 if (!is_error(ret) && arg2) {
5155 if (copy_to_user_timeval(arg2,
5156 &value.it_interval)
5157 || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
5158 &value.it_value))
5159 goto efault;
5162 break;
5163 case TARGET_NR_stat:
5164 if (!(p = lock_user_string(arg1)))
5165 goto efault;
5166 ret = get_errno(stat(path(p), &st));
5167 unlock_user(p, arg1, 0);
5168 goto do_stat;
5169 case TARGET_NR_lstat:
5170 if (!(p = lock_user_string(arg1)))
5171 goto efault;
5172 ret = get_errno(lstat(path(p), &st));
5173 unlock_user(p, arg1, 0);
5174 goto do_stat;
5175 case TARGET_NR_fstat:
5177 ret = get_errno(fstat(arg1, &st));
5178 do_stat:
5179 if (!is_error(ret)) {
5180 struct target_stat *target_st;
5182 if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
5183 goto efault;
5184 __put_user(st.st_dev, &target_st->st_dev);
5185 __put_user(st.st_ino, &target_st->st_ino);
5186 __put_user(st.st_mode, &target_st->st_mode);
5187 __put_user(st.st_uid, &target_st->st_uid);
5188 __put_user(st.st_gid, &target_st->st_gid);
5189 __put_user(st.st_nlink, &target_st->st_nlink);
5190 __put_user(st.st_rdev, &target_st->st_rdev);
5191 __put_user(st.st_size, &target_st->st_size);
5192 __put_user(st.st_blksize, &target_st->st_blksize);
5193 __put_user(st.st_blocks, &target_st->st_blocks);
5194 __put_user(st.st_atime, &target_st->target_st_atime);
5195 __put_user(st.st_mtime, &target_st->target_st_mtime);
5196 __put_user(st.st_ctime, &target_st->target_st_ctime);
5197 unlock_user_struct(target_st, arg2, 1);
5200 break;
5201 #ifdef TARGET_NR_olduname
5202 case TARGET_NR_olduname:
5203 goto unimplemented;
5204 #endif
5205 #ifdef TARGET_NR_iopl
5206 case TARGET_NR_iopl:
5207 goto unimplemented;
5208 #endif
5209 case TARGET_NR_vhangup:
5210 ret = get_errno(vhangup());
5211 break;
5212 #ifdef TARGET_NR_idle
5213 case TARGET_NR_idle:
5214 goto unimplemented;
5215 #endif
5216 #ifdef TARGET_NR_syscall
5217 case TARGET_NR_syscall:
5218 ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
5219 break;
5220 #endif
5221 case TARGET_NR_wait4:
5223 int status;
5224 abi_long status_ptr = arg2;
5225 struct rusage rusage, *rusage_ptr;
5226 abi_ulong target_rusage = arg4;
5227 if (target_rusage)
5228 rusage_ptr = &rusage;
5229 else
5230 rusage_ptr = NULL;
5231 ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
5232 if (!is_error(ret)) {
5233 if (status_ptr) {
5234 status = host_to_target_waitstatus(status);
5235 if (put_user_s32(status, status_ptr))
5236 goto efault;
5238 if (target_rusage)
5239 host_to_target_rusage(target_rusage, &rusage);
5242 break;
5243 #ifdef TARGET_NR_swapoff
5244 case TARGET_NR_swapoff:
5245 if (!(p = lock_user_string(arg1)))
5246 goto efault;
5247 ret = get_errno(swapoff(p));
5248 unlock_user(p, arg1, 0);
5249 break;
5250 #endif
5251 case TARGET_NR_sysinfo:
5253 struct target_sysinfo *target_value;
5254 struct sysinfo value;
5255 ret = get_errno(sysinfo(&value));
5256 if (!is_error(ret) && arg1)
5258 if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
5259 goto efault;
5260 __put_user(value.uptime, &target_value->uptime);
5261 __put_user(value.loads[0], &target_value->loads[0]);
5262 __put_user(value.loads[1], &target_value->loads[1]);
5263 __put_user(value.loads[2], &target_value->loads[2]);
5264 __put_user(value.totalram, &target_value->totalram);
5265 __put_user(value.freeram, &target_value->freeram);
5266 __put_user(value.sharedram, &target_value->sharedram);
5267 __put_user(value.bufferram, &target_value->bufferram);
5268 __put_user(value.totalswap, &target_value->totalswap);
5269 __put_user(value.freeswap, &target_value->freeswap);
5270 __put_user(value.procs, &target_value->procs);
5271 __put_user(value.totalhigh, &target_value->totalhigh);
5272 __put_user(value.freehigh, &target_value->freehigh);
5273 __put_user(value.mem_unit, &target_value->mem_unit);
5274 unlock_user_struct(target_value, arg1, 1);
5277 break;
5278 #ifdef TARGET_NR_ipc
5279 case TARGET_NR_ipc:
5280 ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
5281 break;
5282 #endif
5283 #ifdef TARGET_NR_semget
5284 case TARGET_NR_semget:
5285 ret = get_errno(semget(arg1, arg2, arg3));
5286 break;
5287 #endif
5288 #ifdef TARGET_NR_semop
5289 case TARGET_NR_semop:
5290 ret = get_errno(do_semop(arg1, arg2, arg3));
5291 break;
5292 #endif
5293 #ifdef TARGET_NR_semctl
5294 case TARGET_NR_semctl:
5295 ret = do_semctl(arg1, arg2, arg3, (union target_semun)(abi_ulong)arg4);
5296 break;
5297 #endif
5298 #ifdef TARGET_NR_msgctl
5299 case TARGET_NR_msgctl:
5300 ret = do_msgctl(arg1, arg2, arg3);
5301 break;
5302 #endif
5303 #ifdef TARGET_NR_msgget
5304 case TARGET_NR_msgget:
5305 ret = get_errno(msgget(arg1, arg2));
5306 break;
5307 #endif
5308 #ifdef TARGET_NR_msgrcv
5309 case TARGET_NR_msgrcv:
5310 ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
5311 break;
5312 #endif
5313 #ifdef TARGET_NR_msgsnd
5314 case TARGET_NR_msgsnd:
5315 ret = do_msgsnd(arg1, arg2, arg3, arg4);
5316 break;
5317 #endif
5318 case TARGET_NR_fsync:
5319 ret = get_errno(fsync(arg1));
5320 break;
5321 case TARGET_NR_clone:
5322 #if defined(TARGET_SH4)
5323 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
5324 #elif defined(TARGET_CRIS)
5325 ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg4, arg5));
5326 #else
5327 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
5328 #endif
5329 break;
5330 #ifdef __NR_exit_group
5331 /* new thread calls */
5332 case TARGET_NR_exit_group:
5333 #ifdef HAVE_GPROF
5334 _mcleanup();
5335 #endif
5336 gdb_exit(cpu_env, arg1);
5337 ret = get_errno(exit_group(arg1));
5338 break;
5339 #endif
5340 case TARGET_NR_setdomainname:
5341 if (!(p = lock_user_string(arg1)))
5342 goto efault;
5343 ret = get_errno(setdomainname(p, arg2));
5344 unlock_user(p, arg1, 0);
5345 break;
5346 case TARGET_NR_uname:
5347 /* no need to transcode because we use the linux syscall */
5349 struct new_utsname * buf;
5351 if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
5352 goto efault;
5353 ret = get_errno(sys_uname(buf));
5354 if (!is_error(ret)) {
5355 /* Overrite the native machine name with whatever is being
5356 emulated. */
5357 strcpy (buf->machine, UNAME_MACHINE);
5358 /* Allow the user to override the reported release. */
5359 if (qemu_uname_release && *qemu_uname_release)
5360 strcpy (buf->release, qemu_uname_release);
5362 unlock_user_struct(buf, arg1, 1);
5364 break;
5365 #ifdef TARGET_I386
5366 case TARGET_NR_modify_ldt:
5367 ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
5368 break;
5369 #if !defined(TARGET_X86_64)
5370 case TARGET_NR_vm86old:
5371 goto unimplemented;
5372 case TARGET_NR_vm86:
5373 ret = do_vm86(cpu_env, arg1, arg2);
5374 break;
5375 #endif
5376 #endif
5377 case TARGET_NR_adjtimex:
5378 goto unimplemented;
5379 #ifdef TARGET_NR_create_module
5380 case TARGET_NR_create_module:
5381 #endif
5382 case TARGET_NR_init_module:
5383 case TARGET_NR_delete_module:
5384 #ifdef TARGET_NR_get_kernel_syms
5385 case TARGET_NR_get_kernel_syms:
5386 #endif
5387 goto unimplemented;
5388 case TARGET_NR_quotactl:
5389 goto unimplemented;
5390 case TARGET_NR_getpgid:
5391 ret = get_errno(getpgid(arg1));
5392 break;
5393 case TARGET_NR_fchdir:
5394 ret = get_errno(fchdir(arg1));
5395 break;
5396 #ifdef TARGET_NR_bdflush /* not on x86_64 */
5397 case TARGET_NR_bdflush:
5398 goto unimplemented;
5399 #endif
5400 #ifdef TARGET_NR_sysfs
5401 case TARGET_NR_sysfs:
5402 goto unimplemented;
5403 #endif
5404 case TARGET_NR_personality:
5405 ret = get_errno(personality(arg1));
5406 break;
5407 #ifdef TARGET_NR_afs_syscall
5408 case TARGET_NR_afs_syscall:
5409 goto unimplemented;
5410 #endif
5411 #ifdef TARGET_NR__llseek /* Not on alpha */
5412 case TARGET_NR__llseek:
5414 #if defined (__x86_64__)
5415 ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
5416 if (put_user_s64(ret, arg4))
5417 goto efault;
5418 #else
5419 int64_t res;
5420 ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
5421 if (put_user_s64(res, arg4))
5422 goto efault;
5423 #endif
5425 break;
5426 #endif
5427 case TARGET_NR_getdents:
5428 #if TARGET_ABI_BITS != 32
5429 goto unimplemented;
5430 #elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
5432 struct target_dirent *target_dirp;
5433 struct linux_dirent *dirp;
5434 abi_long count = arg3;
5436 dirp = malloc(count);
5437 if (!dirp) {
5438 ret = -TARGET_ENOMEM;
5439 goto fail;
5442 ret = get_errno(sys_getdents(arg1, dirp, count));
5443 if (!is_error(ret)) {
5444 struct linux_dirent *de;
5445 struct target_dirent *tde;
5446 int len = ret;
5447 int reclen, treclen;
5448 int count1, tnamelen;
5450 count1 = 0;
5451 de = dirp;
5452 if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5453 goto efault;
5454 tde = target_dirp;
5455 while (len > 0) {
5456 reclen = de->d_reclen;
5457 treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
5458 tde->d_reclen = tswap16(treclen);
5459 tde->d_ino = tswapl(de->d_ino);
5460 tde->d_off = tswapl(de->d_off);
5461 tnamelen = treclen - (2 * sizeof(abi_long) + 2);
5462 if (tnamelen > 256)
5463 tnamelen = 256;
5464 /* XXX: may not be correct */
5465 pstrcpy(tde->d_name, tnamelen, de->d_name);
5466 de = (struct linux_dirent *)((char *)de + reclen);
5467 len -= reclen;
5468 tde = (struct target_dirent *)((char *)tde + treclen);
5469 count1 += treclen;
5471 ret = count1;
5472 unlock_user(target_dirp, arg2, ret);
5474 free(dirp);
5476 #else
5478 struct linux_dirent *dirp;
5479 abi_long count = arg3;
5481 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5482 goto efault;
5483 ret = get_errno(sys_getdents(arg1, dirp, count));
5484 if (!is_error(ret)) {
5485 struct linux_dirent *de;
5486 int len = ret;
5487 int reclen;
5488 de = dirp;
5489 while (len > 0) {
5490 reclen = de->d_reclen;
5491 if (reclen > len)
5492 break;
5493 de->d_reclen = tswap16(reclen);
5494 tswapls(&de->d_ino);
5495 tswapls(&de->d_off);
5496 de = (struct linux_dirent *)((char *)de + reclen);
5497 len -= reclen;
5500 unlock_user(dirp, arg2, ret);
5502 #endif
5503 break;
5504 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
5505 case TARGET_NR_getdents64:
5507 struct linux_dirent64 *dirp;
5508 abi_long count = arg3;
5509 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5510 goto efault;
5511 ret = get_errno(sys_getdents64(arg1, dirp, count));
5512 if (!is_error(ret)) {
5513 struct linux_dirent64 *de;
5514 int len = ret;
5515 int reclen;
5516 de = dirp;
5517 while (len > 0) {
5518 reclen = de->d_reclen;
5519 if (reclen > len)
5520 break;
5521 de->d_reclen = tswap16(reclen);
5522 tswap64s((uint64_t *)&de->d_ino);
5523 tswap64s((uint64_t *)&de->d_off);
5524 de = (struct linux_dirent64 *)((char *)de + reclen);
5525 len -= reclen;
5528 unlock_user(dirp, arg2, ret);
5530 break;
5531 #endif /* TARGET_NR_getdents64 */
5532 #ifdef TARGET_NR__newselect
5533 case TARGET_NR__newselect:
5534 ret = do_select(arg1, arg2, arg3, arg4, arg5);
5535 break;
5536 #endif
5537 #ifdef TARGET_NR_poll
5538 case TARGET_NR_poll:
5540 struct target_pollfd *target_pfd;
5541 unsigned int nfds = arg2;
5542 int timeout = arg3;
5543 struct pollfd *pfd;
5544 unsigned int i;
5546 target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
5547 if (!target_pfd)
5548 goto efault;
5549 pfd = alloca(sizeof(struct pollfd) * nfds);
5550 for(i = 0; i < nfds; i++) {
5551 pfd[i].fd = tswap32(target_pfd[i].fd);
5552 pfd[i].events = tswap16(target_pfd[i].events);
5554 ret = get_errno(poll(pfd, nfds, timeout));
5555 if (!is_error(ret)) {
5556 for(i = 0; i < nfds; i++) {
5557 target_pfd[i].revents = tswap16(pfd[i].revents);
5559 ret += nfds * (sizeof(struct target_pollfd)
5560 - sizeof(struct pollfd));
5562 unlock_user(target_pfd, arg1, ret);
5564 break;
5565 #endif
5566 case TARGET_NR_flock:
5567 /* NOTE: the flock constant seems to be the same for every
5568 Linux platform */
5569 ret = get_errno(flock(arg1, arg2));
5570 break;
5571 case TARGET_NR_readv:
5573 int count = arg3;
5574 struct iovec *vec;
5576 vec = alloca(count * sizeof(struct iovec));
5577 if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
5578 goto efault;
5579 ret = get_errno(readv(arg1, vec, count));
5580 unlock_iovec(vec, arg2, count, 1);
5582 break;
5583 case TARGET_NR_writev:
5585 int count = arg3;
5586 struct iovec *vec;
5588 vec = alloca(count * sizeof(struct iovec));
5589 if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
5590 goto efault;
5591 ret = get_errno(writev(arg1, vec, count));
5592 unlock_iovec(vec, arg2, count, 0);
5594 break;
5595 case TARGET_NR_getsid:
5596 ret = get_errno(getsid(arg1));
5597 break;
5598 #if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
5599 case TARGET_NR_fdatasync:
5600 ret = get_errno(fdatasync(arg1));
5601 break;
5602 #endif
5603 case TARGET_NR__sysctl:
5604 /* We don't implement this, but ENOTDIR is always a safe
5605 return value. */
5606 ret = -TARGET_ENOTDIR;
5607 break;
5608 case TARGET_NR_sched_setparam:
5610 struct sched_param *target_schp;
5611 struct sched_param schp;
5613 if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
5614 goto efault;
5615 schp.sched_priority = tswap32(target_schp->sched_priority);
5616 unlock_user_struct(target_schp, arg2, 0);
5617 ret = get_errno(sched_setparam(arg1, &schp));
5619 break;
5620 case TARGET_NR_sched_getparam:
5622 struct sched_param *target_schp;
5623 struct sched_param schp;
5624 ret = get_errno(sched_getparam(arg1, &schp));
5625 if (!is_error(ret)) {
5626 if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
5627 goto efault;
5628 target_schp->sched_priority = tswap32(schp.sched_priority);
5629 unlock_user_struct(target_schp, arg2, 1);
5632 break;
5633 case TARGET_NR_sched_setscheduler:
5635 struct sched_param *target_schp;
5636 struct sched_param schp;
5637 if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
5638 goto efault;
5639 schp.sched_priority = tswap32(target_schp->sched_priority);
5640 unlock_user_struct(target_schp, arg3, 0);
5641 ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
5643 break;
5644 case TARGET_NR_sched_getscheduler:
5645 ret = get_errno(sched_getscheduler(arg1));
5646 break;
5647 case TARGET_NR_sched_yield:
5648 ret = get_errno(sched_yield());
5649 break;
5650 case TARGET_NR_sched_get_priority_max:
5651 ret = get_errno(sched_get_priority_max(arg1));
5652 break;
5653 case TARGET_NR_sched_get_priority_min:
5654 ret = get_errno(sched_get_priority_min(arg1));
5655 break;
5656 case TARGET_NR_sched_rr_get_interval:
5658 struct timespec ts;
5659 ret = get_errno(sched_rr_get_interval(arg1, &ts));
5660 if (!is_error(ret)) {
5661 host_to_target_timespec(arg2, &ts);
5664 break;
5665 case TARGET_NR_nanosleep:
5667 struct timespec req, rem;
5668 target_to_host_timespec(&req, arg1);
5669 ret = get_errno(nanosleep(&req, &rem));
5670 if (is_error(ret) && arg2) {
5671 host_to_target_timespec(arg2, &rem);
5674 break;
5675 #ifdef TARGET_NR_query_module
5676 case TARGET_NR_query_module:
5677 goto unimplemented;
5678 #endif
5679 #ifdef TARGET_NR_nfsservctl
5680 case TARGET_NR_nfsservctl:
5681 goto unimplemented;
5682 #endif
5683 case TARGET_NR_prctl:
5684 switch (arg1)
5686 case PR_GET_PDEATHSIG:
5688 int deathsig;
5689 ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
5690 if (!is_error(ret) && arg2
5691 && put_user_ual(deathsig, arg2))
5692 goto efault;
5694 break;
5695 default:
5696 ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
5697 break;
5699 break;
5700 #ifdef TARGET_NR_arch_prctl
5701 case TARGET_NR_arch_prctl:
5702 #if defined(TARGET_I386) && !defined(TARGET_ABI32)
5703 ret = do_arch_prctl(cpu_env, arg1, arg2);
5704 break;
5705 #else
5706 goto unimplemented;
5707 #endif
5708 #endif
5709 #ifdef TARGET_NR_pread
5710 case TARGET_NR_pread:
5711 #ifdef TARGET_ARM
5712 if (((CPUARMState *)cpu_env)->eabi)
5713 arg4 = arg5;
5714 #endif
5715 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5716 goto efault;
5717 ret = get_errno(pread(arg1, p, arg3, arg4));
5718 unlock_user(p, arg2, ret);
5719 break;
5720 case TARGET_NR_pwrite:
5721 #ifdef TARGET_ARM
5722 if (((CPUARMState *)cpu_env)->eabi)
5723 arg4 = arg5;
5724 #endif
5725 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5726 goto efault;
5727 ret = get_errno(pwrite(arg1, p, arg3, arg4));
5728 unlock_user(p, arg2, 0);
5729 break;
5730 #endif
5731 #ifdef TARGET_NR_pread64
5732 case TARGET_NR_pread64:
5733 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5734 goto efault;
5735 ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
5736 unlock_user(p, arg2, ret);
5737 break;
5738 case TARGET_NR_pwrite64:
5739 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5740 goto efault;
5741 ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
5742 unlock_user(p, arg2, 0);
5743 break;
5744 #endif
5745 case TARGET_NR_getcwd:
5746 if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
5747 goto efault;
5748 ret = get_errno(sys_getcwd1(p, arg2));
5749 unlock_user(p, arg1, ret);
5750 break;
5751 case TARGET_NR_capget:
5752 goto unimplemented;
5753 case TARGET_NR_capset:
5754 goto unimplemented;
5755 case TARGET_NR_sigaltstack:
5756 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
5757 defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA)
5758 ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env));
5759 break;
5760 #else
5761 goto unimplemented;
5762 #endif
5763 case TARGET_NR_sendfile:
5764 goto unimplemented;
5765 #ifdef TARGET_NR_getpmsg
5766 case TARGET_NR_getpmsg:
5767 goto unimplemented;
5768 #endif
5769 #ifdef TARGET_NR_putpmsg
5770 case TARGET_NR_putpmsg:
5771 goto unimplemented;
5772 #endif
5773 #ifdef TARGET_NR_vfork
5774 case TARGET_NR_vfork:
5775 ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
5776 0, 0, 0, 0));
5777 break;
5778 #endif
5779 #ifdef TARGET_NR_ugetrlimit
5780 case TARGET_NR_ugetrlimit:
5782 struct rlimit rlim;
5783 ret = get_errno(getrlimit(arg1, &rlim));
5784 if (!is_error(ret)) {
5785 struct target_rlimit *target_rlim;
5786 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
5787 goto efault;
5788 target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
5789 target_rlim->rlim_max = tswapl(rlim.rlim_max);
5790 unlock_user_struct(target_rlim, arg2, 1);
5792 break;
5794 #endif
5795 #ifdef TARGET_NR_truncate64
5796 case TARGET_NR_truncate64:
5797 if (!(p = lock_user_string(arg1)))
5798 goto efault;
5799 ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
5800 unlock_user(p, arg1, 0);
5801 break;
5802 #endif
5803 #ifdef TARGET_NR_ftruncate64
5804 case TARGET_NR_ftruncate64:
5805 ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
5806 break;
5807 #endif
5808 #ifdef TARGET_NR_stat64
5809 case TARGET_NR_stat64:
5810 if (!(p = lock_user_string(arg1)))
5811 goto efault;
5812 ret = get_errno(stat(path(p), &st));
5813 unlock_user(p, arg1, 0);
5814 if (!is_error(ret))
5815 ret = host_to_target_stat64(cpu_env, arg2, &st);
5816 break;
5817 #endif
5818 #ifdef TARGET_NR_lstat64
5819 case TARGET_NR_lstat64:
5820 if (!(p = lock_user_string(arg1)))
5821 goto efault;
5822 ret = get_errno(lstat(path(p), &st));
5823 unlock_user(p, arg1, 0);
5824 if (!is_error(ret))
5825 ret = host_to_target_stat64(cpu_env, arg2, &st);
5826 break;
5827 #endif
5828 #ifdef TARGET_NR_fstat64
5829 case TARGET_NR_fstat64:
5830 ret = get_errno(fstat(arg1, &st));
5831 if (!is_error(ret))
5832 ret = host_to_target_stat64(cpu_env, arg2, &st);
5833 break;
5834 #endif
5835 #if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
5836 (defined(__NR_fstatat64) || defined(__NR_newfstatat))
5837 #ifdef TARGET_NR_fstatat64
5838 case TARGET_NR_fstatat64:
5839 #endif
5840 #ifdef TARGET_NR_newfstatat
5841 case TARGET_NR_newfstatat:
5842 #endif
5843 if (!(p = lock_user_string(arg2)))
5844 goto efault;
5845 #ifdef __NR_fstatat64
5846 ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
5847 #else
5848 ret = get_errno(sys_newfstatat(arg1, path(p), &st, arg4));
5849 #endif
5850 if (!is_error(ret))
5851 ret = host_to_target_stat64(cpu_env, arg3, &st);
5852 break;
5853 #endif
5854 #ifdef USE_UID16
5855 case TARGET_NR_lchown:
5856 if (!(p = lock_user_string(arg1)))
5857 goto efault;
5858 ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
5859 unlock_user(p, arg1, 0);
5860 break;
5861 case TARGET_NR_getuid:
5862 ret = get_errno(high2lowuid(getuid()));
5863 break;
5864 case TARGET_NR_getgid:
5865 ret = get_errno(high2lowgid(getgid()));
5866 break;
5867 case TARGET_NR_geteuid:
5868 ret = get_errno(high2lowuid(geteuid()));
5869 break;
5870 case TARGET_NR_getegid:
5871 ret = get_errno(high2lowgid(getegid()));
5872 break;
5873 case TARGET_NR_setreuid:
5874 ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
5875 break;
5876 case TARGET_NR_setregid:
5877 ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
5878 break;
5879 case TARGET_NR_getgroups:
5881 int gidsetsize = arg1;
5882 uint16_t *target_grouplist;
5883 gid_t *grouplist;
5884 int i;
5886 grouplist = alloca(gidsetsize * sizeof(gid_t));
5887 ret = get_errno(getgroups(gidsetsize, grouplist));
5888 if (gidsetsize == 0)
5889 break;
5890 if (!is_error(ret)) {
5891 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
5892 if (!target_grouplist)
5893 goto efault;
5894 for(i = 0;i < ret; i++)
5895 target_grouplist[i] = tswap16(grouplist[i]);
5896 unlock_user(target_grouplist, arg2, gidsetsize * 2);
5899 break;
5900 case TARGET_NR_setgroups:
5902 int gidsetsize = arg1;
5903 uint16_t *target_grouplist;
5904 gid_t *grouplist;
5905 int i;
5907 grouplist = alloca(gidsetsize * sizeof(gid_t));
5908 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
5909 if (!target_grouplist) {
5910 ret = -TARGET_EFAULT;
5911 goto fail;
5913 for(i = 0;i < gidsetsize; i++)
5914 grouplist[i] = tswap16(target_grouplist[i]);
5915 unlock_user(target_grouplist, arg2, 0);
5916 ret = get_errno(setgroups(gidsetsize, grouplist));
5918 break;
5919 case TARGET_NR_fchown:
5920 ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
5921 break;
5922 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
5923 case TARGET_NR_fchownat:
5924 if (!(p = lock_user_string(arg2)))
5925 goto efault;
5926 ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
5927 unlock_user(p, arg2, 0);
5928 break;
5929 #endif
5930 #ifdef TARGET_NR_setresuid
5931 case TARGET_NR_setresuid:
5932 ret = get_errno(setresuid(low2highuid(arg1),
5933 low2highuid(arg2),
5934 low2highuid(arg3)));
5935 break;
5936 #endif
5937 #ifdef TARGET_NR_getresuid
5938 case TARGET_NR_getresuid:
5940 uid_t ruid, euid, suid;
5941 ret = get_errno(getresuid(&ruid, &euid, &suid));
5942 if (!is_error(ret)) {
5943 if (put_user_u16(high2lowuid(ruid), arg1)
5944 || put_user_u16(high2lowuid(euid), arg2)
5945 || put_user_u16(high2lowuid(suid), arg3))
5946 goto efault;
5949 break;
5950 #endif
5951 #ifdef TARGET_NR_getresgid
5952 case TARGET_NR_setresgid:
5953 ret = get_errno(setresgid(low2highgid(arg1),
5954 low2highgid(arg2),
5955 low2highgid(arg3)));
5956 break;
5957 #endif
5958 #ifdef TARGET_NR_getresgid
5959 case TARGET_NR_getresgid:
5961 gid_t rgid, egid, sgid;
5962 ret = get_errno(getresgid(&rgid, &egid, &sgid));
5963 if (!is_error(ret)) {
5964 if (put_user_u16(high2lowgid(rgid), arg1)
5965 || put_user_u16(high2lowgid(egid), arg2)
5966 || put_user_u16(high2lowgid(sgid), arg3))
5967 goto efault;
5970 break;
5971 #endif
5972 case TARGET_NR_chown:
5973 if (!(p = lock_user_string(arg1)))
5974 goto efault;
5975 ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
5976 unlock_user(p, arg1, 0);
5977 break;
5978 case TARGET_NR_setuid:
5979 ret = get_errno(setuid(low2highuid(arg1)));
5980 break;
5981 case TARGET_NR_setgid:
5982 ret = get_errno(setgid(low2highgid(arg1)));
5983 break;
5984 case TARGET_NR_setfsuid:
5985 ret = get_errno(setfsuid(arg1));
5986 break;
5987 case TARGET_NR_setfsgid:
5988 ret = get_errno(setfsgid(arg1));
5989 break;
5990 #endif /* USE_UID16 */
5992 #ifdef TARGET_NR_lchown32
5993 case TARGET_NR_lchown32:
5994 if (!(p = lock_user_string(arg1)))
5995 goto efault;
5996 ret = get_errno(lchown(p, arg2, arg3));
5997 unlock_user(p, arg1, 0);
5998 break;
5999 #endif
6000 #ifdef TARGET_NR_getuid32
6001 case TARGET_NR_getuid32:
6002 ret = get_errno(getuid());
6003 break;
6004 #endif
6006 #if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
6007 /* Alpha specific */
6008 case TARGET_NR_getxuid:
6010 uid_t euid;
6011 euid=geteuid();
6012 ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
6014 ret = get_errno(getuid());
6015 break;
6016 #endif
6017 #if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
6018 /* Alpha specific */
6019 case TARGET_NR_getxgid:
6021 uid_t egid;
6022 egid=getegid();
6023 ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
6025 ret = get_errno(getgid());
6026 break;
6027 #endif
6029 #ifdef TARGET_NR_getgid32
6030 case TARGET_NR_getgid32:
6031 ret = get_errno(getgid());
6032 break;
6033 #endif
6034 #ifdef TARGET_NR_geteuid32
6035 case TARGET_NR_geteuid32:
6036 ret = get_errno(geteuid());
6037 break;
6038 #endif
6039 #ifdef TARGET_NR_getegid32
6040 case TARGET_NR_getegid32:
6041 ret = get_errno(getegid());
6042 break;
6043 #endif
6044 #ifdef TARGET_NR_setreuid32
6045 case TARGET_NR_setreuid32:
6046 ret = get_errno(setreuid(arg1, arg2));
6047 break;
6048 #endif
6049 #ifdef TARGET_NR_setregid32
6050 case TARGET_NR_setregid32:
6051 ret = get_errno(setregid(arg1, arg2));
6052 break;
6053 #endif
6054 #ifdef TARGET_NR_getgroups32
6055 case TARGET_NR_getgroups32:
6057 int gidsetsize = arg1;
6058 uint32_t *target_grouplist;
6059 gid_t *grouplist;
6060 int i;
6062 grouplist = alloca(gidsetsize * sizeof(gid_t));
6063 ret = get_errno(getgroups(gidsetsize, grouplist));
6064 if (gidsetsize == 0)
6065 break;
6066 if (!is_error(ret)) {
6067 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
6068 if (!target_grouplist) {
6069 ret = -TARGET_EFAULT;
6070 goto fail;
6072 for(i = 0;i < ret; i++)
6073 target_grouplist[i] = tswap32(grouplist[i]);
6074 unlock_user(target_grouplist, arg2, gidsetsize * 4);
6077 break;
6078 #endif
6079 #ifdef TARGET_NR_setgroups32
6080 case TARGET_NR_setgroups32:
6082 int gidsetsize = arg1;
6083 uint32_t *target_grouplist;
6084 gid_t *grouplist;
6085 int i;
6087 grouplist = alloca(gidsetsize * sizeof(gid_t));
6088 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
6089 if (!target_grouplist) {
6090 ret = -TARGET_EFAULT;
6091 goto fail;
6093 for(i = 0;i < gidsetsize; i++)
6094 grouplist[i] = tswap32(target_grouplist[i]);
6095 unlock_user(target_grouplist, arg2, 0);
6096 ret = get_errno(setgroups(gidsetsize, grouplist));
6098 break;
6099 #endif
6100 #ifdef TARGET_NR_fchown32
6101 case TARGET_NR_fchown32:
6102 ret = get_errno(fchown(arg1, arg2, arg3));
6103 break;
6104 #endif
6105 #ifdef TARGET_NR_setresuid32
6106 case TARGET_NR_setresuid32:
6107 ret = get_errno(setresuid(arg1, arg2, arg3));
6108 break;
6109 #endif
6110 #ifdef TARGET_NR_getresuid32
6111 case TARGET_NR_getresuid32:
6113 uid_t ruid, euid, suid;
6114 ret = get_errno(getresuid(&ruid, &euid, &suid));
6115 if (!is_error(ret)) {
6116 if (put_user_u32(ruid, arg1)
6117 || put_user_u32(euid, arg2)
6118 || put_user_u32(suid, arg3))
6119 goto efault;
6122 break;
6123 #endif
6124 #ifdef TARGET_NR_setresgid32
6125 case TARGET_NR_setresgid32:
6126 ret = get_errno(setresgid(arg1, arg2, arg3));
6127 break;
6128 #endif
6129 #ifdef TARGET_NR_getresgid32
6130 case TARGET_NR_getresgid32:
6132 gid_t rgid, egid, sgid;
6133 ret = get_errno(getresgid(&rgid, &egid, &sgid));
6134 if (!is_error(ret)) {
6135 if (put_user_u32(rgid, arg1)
6136 || put_user_u32(egid, arg2)
6137 || put_user_u32(sgid, arg3))
6138 goto efault;
6141 break;
6142 #endif
6143 #ifdef TARGET_NR_chown32
6144 case TARGET_NR_chown32:
6145 if (!(p = lock_user_string(arg1)))
6146 goto efault;
6147 ret = get_errno(chown(p, arg2, arg3));
6148 unlock_user(p, arg1, 0);
6149 break;
6150 #endif
6151 #ifdef TARGET_NR_setuid32
6152 case TARGET_NR_setuid32:
6153 ret = get_errno(setuid(arg1));
6154 break;
6155 #endif
6156 #ifdef TARGET_NR_setgid32
6157 case TARGET_NR_setgid32:
6158 ret = get_errno(setgid(arg1));
6159 break;
6160 #endif
6161 #ifdef TARGET_NR_setfsuid32
6162 case TARGET_NR_setfsuid32:
6163 ret = get_errno(setfsuid(arg1));
6164 break;
6165 #endif
6166 #ifdef TARGET_NR_setfsgid32
6167 case TARGET_NR_setfsgid32:
6168 ret = get_errno(setfsgid(arg1));
6169 break;
6170 #endif
6172 case TARGET_NR_pivot_root:
6173 goto unimplemented;
6174 #ifdef TARGET_NR_mincore
6175 case TARGET_NR_mincore:
6177 void *a;
6178 ret = -TARGET_EFAULT;
6179 if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
6180 goto efault;
6181 if (!(p = lock_user_string(arg3)))
6182 goto mincore_fail;
6183 ret = get_errno(mincore(a, arg2, p));
6184 unlock_user(p, arg3, ret);
6185 mincore_fail:
6186 unlock_user(a, arg1, 0);
6188 break;
6189 #endif
6190 #ifdef TARGET_NR_arm_fadvise64_64
6191 case TARGET_NR_arm_fadvise64_64:
6194 * arm_fadvise64_64 looks like fadvise64_64 but
6195 * with different argument order
6197 abi_long temp;
6198 temp = arg3;
6199 arg3 = arg4;
6200 arg4 = temp;
6202 #endif
6203 #if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64)
6204 #ifdef TARGET_NR_fadvise64_64
6205 case TARGET_NR_fadvise64_64:
6206 #endif
6207 /* This is a hint, so ignoring and returning success is ok. */
6208 ret = get_errno(0);
6209 break;
6210 #endif
6211 #ifdef TARGET_NR_madvise
6212 case TARGET_NR_madvise:
6213 /* A straight passthrough may not be safe because qemu sometimes
6214 turns private flie-backed mappings into anonymous mappings.
6215 This will break MADV_DONTNEED.
6216 This is a hint, so ignoring and returning success is ok. */
6217 ret = get_errno(0);
6218 break;
6219 #endif
6220 #if TARGET_ABI_BITS == 32
6221 case TARGET_NR_fcntl64:
6223 int cmd;
6224 struct flock64 fl;
6225 struct target_flock64 *target_fl;
6226 #ifdef TARGET_ARM
6227 struct target_eabi_flock64 *target_efl;
6228 #endif
6230 switch(arg2){
6231 case TARGET_F_GETLK64:
6232 cmd = F_GETLK64;
6233 break;
6234 case TARGET_F_SETLK64:
6235 cmd = F_SETLK64;
6236 break;
6237 case TARGET_F_SETLKW64:
6238 cmd = F_SETLK64;
6239 break;
6240 default:
6241 cmd = arg2;
6242 break;
6245 switch(arg2) {
6246 case TARGET_F_GETLK64:
6247 #ifdef TARGET_ARM
6248 if (((CPUARMState *)cpu_env)->eabi) {
6249 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1))
6250 goto efault;
6251 fl.l_type = tswap16(target_efl->l_type);
6252 fl.l_whence = tswap16(target_efl->l_whence);
6253 fl.l_start = tswap64(target_efl->l_start);
6254 fl.l_len = tswap64(target_efl->l_len);
6255 fl.l_pid = tswapl(target_efl->l_pid);
6256 unlock_user_struct(target_efl, arg3, 0);
6257 } else
6258 #endif
6260 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1))
6261 goto efault;
6262 fl.l_type = tswap16(target_fl->l_type);
6263 fl.l_whence = tswap16(target_fl->l_whence);
6264 fl.l_start = tswap64(target_fl->l_start);
6265 fl.l_len = tswap64(target_fl->l_len);
6266 fl.l_pid = tswapl(target_fl->l_pid);
6267 unlock_user_struct(target_fl, arg3, 0);
6269 ret = get_errno(fcntl(arg1, cmd, &fl));
6270 if (ret == 0) {
6271 #ifdef TARGET_ARM
6272 if (((CPUARMState *)cpu_env)->eabi) {
6273 if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0))
6274 goto efault;
6275 target_efl->l_type = tswap16(fl.l_type);
6276 target_efl->l_whence = tswap16(fl.l_whence);
6277 target_efl->l_start = tswap64(fl.l_start);
6278 target_efl->l_len = tswap64(fl.l_len);
6279 target_efl->l_pid = tswapl(fl.l_pid);
6280 unlock_user_struct(target_efl, arg3, 1);
6281 } else
6282 #endif
6284 if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0))
6285 goto efault;
6286 target_fl->l_type = tswap16(fl.l_type);
6287 target_fl->l_whence = tswap16(fl.l_whence);
6288 target_fl->l_start = tswap64(fl.l_start);
6289 target_fl->l_len = tswap64(fl.l_len);
6290 target_fl->l_pid = tswapl(fl.l_pid);
6291 unlock_user_struct(target_fl, arg3, 1);
6294 break;
6296 case TARGET_F_SETLK64:
6297 case TARGET_F_SETLKW64:
6298 #ifdef TARGET_ARM
6299 if (((CPUARMState *)cpu_env)->eabi) {
6300 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1))
6301 goto efault;
6302 fl.l_type = tswap16(target_efl->l_type);
6303 fl.l_whence = tswap16(target_efl->l_whence);
6304 fl.l_start = tswap64(target_efl->l_start);
6305 fl.l_len = tswap64(target_efl->l_len);
6306 fl.l_pid = tswapl(target_efl->l_pid);
6307 unlock_user_struct(target_efl, arg3, 0);
6308 } else
6309 #endif
6311 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1))
6312 goto efault;
6313 fl.l_type = tswap16(target_fl->l_type);
6314 fl.l_whence = tswap16(target_fl->l_whence);
6315 fl.l_start = tswap64(target_fl->l_start);
6316 fl.l_len = tswap64(target_fl->l_len);
6317 fl.l_pid = tswapl(target_fl->l_pid);
6318 unlock_user_struct(target_fl, arg3, 0);
6320 ret = get_errno(fcntl(arg1, cmd, &fl));
6321 break;
6322 default:
6323 ret = do_fcntl(arg1, cmd, arg3);
6324 break;
6326 break;
6328 #endif
6329 #ifdef TARGET_NR_cacheflush
6330 case TARGET_NR_cacheflush:
6331 /* self-modifying code is handled automatically, so nothing needed */
6332 ret = 0;
6333 break;
6334 #endif
6335 #ifdef TARGET_NR_security
6336 case TARGET_NR_security:
6337 goto unimplemented;
6338 #endif
6339 #ifdef TARGET_NR_getpagesize
6340 case TARGET_NR_getpagesize:
6341 ret = TARGET_PAGE_SIZE;
6342 break;
6343 #endif
6344 case TARGET_NR_gettid:
6345 ret = get_errno(gettid());
6346 break;
6347 #ifdef TARGET_NR_readahead
6348 case TARGET_NR_readahead:
6349 #if TARGET_ABI_BITS == 32
6350 #ifdef TARGET_ARM
6351 if (((CPUARMState *)cpu_env)->eabi)
6353 arg2 = arg3;
6354 arg3 = arg4;
6355 arg4 = arg5;
6357 #endif
6358 ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
6359 #else
6360 ret = get_errno(readahead(arg1, arg2, arg3));
6361 #endif
6362 break;
6363 #endif
6364 #ifdef TARGET_NR_setxattr
6365 case TARGET_NR_setxattr:
6366 case TARGET_NR_lsetxattr:
6367 case TARGET_NR_fsetxattr:
6368 case TARGET_NR_getxattr:
6369 case TARGET_NR_lgetxattr:
6370 case TARGET_NR_fgetxattr:
6371 case TARGET_NR_listxattr:
6372 case TARGET_NR_llistxattr:
6373 case TARGET_NR_flistxattr:
6374 case TARGET_NR_removexattr:
6375 case TARGET_NR_lremovexattr:
6376 case TARGET_NR_fremovexattr:
6377 goto unimplemented_nowarn;
6378 #endif
6379 #ifdef TARGET_NR_set_thread_area
6380 case TARGET_NR_set_thread_area:
6381 #if defined(TARGET_MIPS)
6382 ((CPUMIPSState *) cpu_env)->tls_value = arg1;
6383 ret = 0;
6384 break;
6385 #elif defined(TARGET_CRIS)
6386 if (arg1 & 0xff)
6387 ret = -TARGET_EINVAL;
6388 else {
6389 ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
6390 ret = 0;
6392 break;
6393 #elif defined(TARGET_I386) && defined(TARGET_ABI32)
6394 ret = do_set_thread_area(cpu_env, arg1);
6395 break;
6396 #else
6397 goto unimplemented_nowarn;
6398 #endif
6399 #endif
6400 #ifdef TARGET_NR_get_thread_area
6401 case TARGET_NR_get_thread_area:
6402 #if defined(TARGET_I386) && defined(TARGET_ABI32)
6403 ret = do_get_thread_area(cpu_env, arg1);
6404 #else
6405 goto unimplemented_nowarn;
6406 #endif
6407 #endif
6408 #ifdef TARGET_NR_getdomainname
6409 case TARGET_NR_getdomainname:
6410 goto unimplemented_nowarn;
6411 #endif
6413 #ifdef TARGET_NR_clock_gettime
6414 case TARGET_NR_clock_gettime:
6416 struct timespec ts;
6417 ret = get_errno(clock_gettime(arg1, &ts));
6418 if (!is_error(ret)) {
6419 host_to_target_timespec(arg2, &ts);
6421 break;
6423 #endif
6424 #ifdef TARGET_NR_clock_getres
6425 case TARGET_NR_clock_getres:
6427 struct timespec ts;
6428 ret = get_errno(clock_getres(arg1, &ts));
6429 if (!is_error(ret)) {
6430 host_to_target_timespec(arg2, &ts);
6432 break;
6434 #endif
6435 #ifdef TARGET_NR_clock_nanosleep
6436 case TARGET_NR_clock_nanosleep:
6438 struct timespec ts;
6439 target_to_host_timespec(&ts, arg3);
6440 ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
6441 if (arg4)
6442 host_to_target_timespec(arg4, &ts);
6443 break;
6445 #endif
6447 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
6448 case TARGET_NR_set_tid_address:
6449 ret = get_errno(set_tid_address((int *)g2h(arg1)));
6450 break;
6451 #endif
6453 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
6454 case TARGET_NR_tkill:
6455 ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
6456 break;
6457 #endif
6459 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
6460 case TARGET_NR_tgkill:
6461 ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
6462 target_to_host_signal(arg3)));
6463 break;
6464 #endif
6466 #ifdef TARGET_NR_set_robust_list
6467 case TARGET_NR_set_robust_list:
6468 goto unimplemented_nowarn;
6469 #endif
6471 #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
6472 case TARGET_NR_utimensat:
6474 struct timespec ts[2];
6475 target_to_host_timespec(ts, arg3);
6476 target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
6477 if (!arg2)
6478 ret = get_errno(sys_utimensat(arg1, NULL, ts, arg4));
6479 else {
6480 if (!(p = lock_user_string(arg2))) {
6481 ret = -TARGET_EFAULT;
6482 goto fail;
6484 ret = get_errno(sys_utimensat(arg1, path(p), ts, arg4));
6485 unlock_user(p, arg2, 0);
6488 break;
6489 #endif
6490 #if defined(USE_NPTL)
6491 case TARGET_NR_futex:
6492 ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
6493 break;
6494 #endif
6495 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
6496 case TARGET_NR_inotify_init:
6497 ret = get_errno(sys_inotify_init());
6498 break;
6499 #endif
6500 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
6501 case TARGET_NR_inotify_add_watch:
6502 p = lock_user_string(arg2);
6503 ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
6504 unlock_user(p, arg2, 0);
6505 break;
6506 #endif
6507 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
6508 case TARGET_NR_inotify_rm_watch:
6509 ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
6510 break;
6511 #endif
6513 #ifdef TARGET_NR_mq_open
6514 case TARGET_NR_mq_open:
6516 struct mq_attr posix_mq_attr;
6518 p = lock_user_string(arg1 - 1);
6519 if (arg4 != 0)
6520 copy_from_user_mq_attr (&posix_mq_attr, arg4);
6521 ret = get_errno(mq_open(p, arg2, arg3, &posix_mq_attr));
6522 unlock_user (p, arg1, 0);
6524 break;
6526 case TARGET_NR_mq_unlink:
6527 p = lock_user_string(arg1 - 1);
6528 ret = get_errno(mq_unlink(p));
6529 unlock_user (p, arg1, 0);
6530 break;
6532 case TARGET_NR_mq_timedsend:
6534 struct timespec ts;
6536 p = lock_user (VERIFY_READ, arg2, arg3, 1);
6537 if (arg5 != 0) {
6538 target_to_host_timespec(&ts, arg5);
6539 ret = get_errno(mq_timedsend(arg1, p, arg3, arg4, &ts));
6540 host_to_target_timespec(arg5, &ts);
6542 else
6543 ret = get_errno(mq_send(arg1, p, arg3, arg4));
6544 unlock_user (p, arg2, arg3);
6546 break;
6548 case TARGET_NR_mq_timedreceive:
6550 struct timespec ts;
6551 unsigned int prio;
6553 p = lock_user (VERIFY_READ, arg2, arg3, 1);
6554 if (arg5 != 0) {
6555 target_to_host_timespec(&ts, arg5);
6556 ret = get_errno(mq_timedreceive(arg1, p, arg3, &prio, &ts));
6557 host_to_target_timespec(arg5, &ts);
6559 else
6560 ret = get_errno(mq_receive(arg1, p, arg3, &prio));
6561 unlock_user (p, arg2, arg3);
6562 if (arg4 != 0)
6563 put_user_u32(prio, arg4);
6565 break;
6567 /* Not implemented for now... */
6568 /* case TARGET_NR_mq_notify: */
6569 /* break; */
6571 case TARGET_NR_mq_getsetattr:
6573 struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
6574 ret = 0;
6575 if (arg3 != 0) {
6576 ret = mq_getattr(arg1, &posix_mq_attr_out);
6577 copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
6579 if (arg2 != 0) {
6580 copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
6581 ret |= mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_attr_out);
6585 break;
6586 #endif
6588 default:
6589 unimplemented:
6590 gemu_log("qemu: Unsupported syscall: %d\n", num);
6591 #if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
6592 unimplemented_nowarn:
6593 #endif
6594 ret = -TARGET_ENOSYS;
6595 break;
6597 fail:
6598 #ifdef DEBUG
6599 gemu_log(" = %ld\n", ret);
6600 #endif
6601 if(do_strace)
6602 print_syscall_ret(num, ret);
6603 return ret;
6604 efault:
6605 ret = -TARGET_EFAULT;
6606 goto fail;