1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#define _ATFILE_SOURCE
20#include <stdlib.h>
21#include <stdio.h>
22#include <stdarg.h>
23#include <string.h>
24#include <elf.h>
25#include <endian.h>
26#include <errno.h>
27#include <unistd.h>
28#include <fcntl.h>
29#include <time.h>
30#include <limits.h>
31#include <sys/types.h>
32#include <sys/ipc.h>
33#include <sys/msg.h>
34#include <sys/wait.h>
35#include <sys/time.h>
36#include <sys/stat.h>
37#include <sys/mount.h>
38#include <sys/prctl.h>
39#include <sys/resource.h>
40#include <sys/mman.h>
41#include <sys/swap.h>
42#include <signal.h>
43#include <sched.h>
44#ifdef __ia64__
45int __clone2(int (*fn)(void *), void *child_stack_base,
46 size_t stack_size, int flags, void *arg, ...);
47#endif
48#include <sys/socket.h>
49#include <sys/un.h>
50#include <sys/uio.h>
51#include <sys/poll.h>
52#include <sys/times.h>
53#include <sys/shm.h>
54#include <sys/sem.h>
55#include <sys/statfs.h>
56#include <utime.h>
57#include <sys/sysinfo.h>
58#include <sys/utsname.h>
59
60#include <netinet/ip.h>
61#include <netinet/tcp.h>
62#include <linux/wireless.h>
63#include "qemu-common.h"
64#ifdef TARGET_GPROF
65#include <sys/gmon.h>
66#endif
67#ifdef CONFIG_EVENTFD
68#include <sys/eventfd.h>
69#endif
70#ifdef CONFIG_EPOLL
71#include <sys/epoll.h>
72#endif
73#ifdef CONFIG_ATTR
74#include "qemu-xattr.h"
75#endif
76
77#define termios host_termios
78#define winsize host_winsize
79#define termio host_termio
80#define sgttyb host_sgttyb
81#define tchars host_tchars
82#define ltchars host_ltchars
83
84#include <linux/termios.h>
85#include <linux/unistd.h>
86#include <linux/utsname.h>
87#include <linux/cdrom.h>
88#include <linux/hdreg.h>
89#include <linux/soundcard.h>
90#include <linux/kd.h>
91#include <linux/mtio.h>
92#include <linux/fs.h>
93#if defined(CONFIG_FIEMAP)
94#include <linux/fiemap.h>
95#endif
96#include <linux/fb.h>
97#include <linux/vt.h>
98#include <linux/dm-ioctl.h>
99#include "linux_loop.h"
100#include "cpu-uname.h"
101
102#include "qemu.h"
103
104#if defined(CONFIG_USE_NPTL)
105#define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
106 CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
107#else
108
109#define CLONE_NPTL_FLAGS2 0
110#endif
111
112
113
114
115#define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct linux_dirent [2])
116#define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct linux_dirent [2])
117
118
119#undef _syscall0
120#undef _syscall1
121#undef _syscall2
122#undef _syscall3
123#undef _syscall4
124#undef _syscall5
125#undef _syscall6
126
127#define _syscall0(type,name) \
128static type name (void) \
129{ \
130 return syscall(__NR_##name); \
131}
132
133#define _syscall1(type,name,type1,arg1) \
134static type name (type1 arg1) \
135{ \
136 return syscall(__NR_##name, arg1); \
137}
138
139#define _syscall2(type,name,type1,arg1,type2,arg2) \
140static type name (type1 arg1,type2 arg2) \
141{ \
142 return syscall(__NR_##name, arg1, arg2); \
143}
144
145#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
146static type name (type1 arg1,type2 arg2,type3 arg3) \
147{ \
148 return syscall(__NR_##name, arg1, arg2, arg3); \
149}
150
151#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
152static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4) \
153{ \
154 return syscall(__NR_##name, arg1, arg2, arg3, arg4); \
155}
156
157#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
158 type5,arg5) \
159static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
160{ \
161 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5); \
162}
163
164
165#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
166 type5,arg5,type6,arg6) \
167static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \
168 type6 arg6) \
169{ \
170 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6); \
171}
172
173
174#define __NR_sys_uname __NR_uname
175#define __NR_sys_faccessat __NR_faccessat
176#define __NR_sys_fchmodat __NR_fchmodat
177#define __NR_sys_fchownat __NR_fchownat
178#define __NR_sys_fstatat64 __NR_fstatat64
179#define __NR_sys_futimesat __NR_futimesat
180#define __NR_sys_getcwd1 __NR_getcwd
181#define __NR_sys_getdents __NR_getdents
182#define __NR_sys_getdents64 __NR_getdents64
183#define __NR_sys_getpriority __NR_getpriority
184#define __NR_sys_linkat __NR_linkat
185#define __NR_sys_mkdirat __NR_mkdirat
186#define __NR_sys_mknodat __NR_mknodat
187#define __NR_sys_newfstatat __NR_newfstatat
188#define __NR_sys_openat __NR_openat
189#define __NR_sys_readlinkat __NR_readlinkat
190#define __NR_sys_renameat __NR_renameat
191#define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
192#define __NR_sys_symlinkat __NR_symlinkat
193#define __NR_sys_syslog __NR_syslog
194#define __NR_sys_tgkill __NR_tgkill
195#define __NR_sys_tkill __NR_tkill
196#define __NR_sys_unlinkat __NR_unlinkat
197#define __NR_sys_utimensat __NR_utimensat
198#define __NR_sys_futex __NR_futex
199#define __NR_sys_inotify_init __NR_inotify_init
200#define __NR_sys_inotify_add_watch __NR_inotify_add_watch
201#define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
202
203#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) || \
204 defined(__s390x__)
205#define __NR__llseek __NR_lseek
206#endif
207
208#ifdef __NR_gettid
209_syscall0(int, gettid)
210#else
211
212
213static int gettid(void) {
214 return -ENOSYS;
215}
216#endif
217_syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
218#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
219_syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
220#endif
221_syscall2(int, sys_getpriority, int, which, int, who);
222#if defined(TARGET_NR__llseek) && defined(__NR_llseek)
223_syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo,
224 loff_t *, res, uint, wh);
225#endif
226_syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
227_syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
228#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
229_syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
230#endif
231#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
232_syscall2(int,sys_tkill,int,tid,int,sig)
233#endif
234#ifdef __NR_exit_group
235_syscall1(int,exit_group,int,error_code)
236#endif
237#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
238_syscall1(int,set_tid_address,int *,tidptr)
239#endif
240#if defined(CONFIG_USE_NPTL)
241#if defined(TARGET_NR_futex) && defined(__NR_futex)
242_syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
243 const struct timespec *,timeout,int *,uaddr2,int,val3)
244#endif
245#endif
246#define __NR_sys_sched_getaffinity __NR_sched_getaffinity
247_syscall3(int, sys_sched_getaffinity, pid_t, pid, unsigned int, len,
248 unsigned long *, user_mask_ptr);
249#define __NR_sys_sched_setaffinity __NR_sched_setaffinity
250_syscall3(int, sys_sched_setaffinity, pid_t, pid, unsigned int, len,
251 unsigned long *, user_mask_ptr);
252_syscall4(int, reboot, int, magic1, int, magic2, unsigned int, cmd,
253 void *, arg);
254
255static bitmask_transtbl fcntl_flags_tbl[] = {
256 { TARGET_O_ACCMODE, TARGET_O_WRONLY, O_ACCMODE, O_WRONLY, },
257 { TARGET_O_ACCMODE, TARGET_O_RDWR, O_ACCMODE, O_RDWR, },
258 { TARGET_O_CREAT, TARGET_O_CREAT, O_CREAT, O_CREAT, },
259 { TARGET_O_EXCL, TARGET_O_EXCL, O_EXCL, O_EXCL, },
260 { TARGET_O_NOCTTY, TARGET_O_NOCTTY, O_NOCTTY, O_NOCTTY, },
261 { TARGET_O_TRUNC, TARGET_O_TRUNC, O_TRUNC, O_TRUNC, },
262 { TARGET_O_APPEND, TARGET_O_APPEND, O_APPEND, O_APPEND, },
263 { TARGET_O_NONBLOCK, TARGET_O_NONBLOCK, O_NONBLOCK, O_NONBLOCK, },
264 { TARGET_O_SYNC, TARGET_O_SYNC, O_SYNC, O_SYNC, },
265 { TARGET_FASYNC, TARGET_FASYNC, FASYNC, FASYNC, },
266 { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
267 { TARGET_O_NOFOLLOW, TARGET_O_NOFOLLOW, O_NOFOLLOW, O_NOFOLLOW, },
268 { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
269#if defined(O_DIRECT)
270 { TARGET_O_DIRECT, TARGET_O_DIRECT, O_DIRECT, O_DIRECT, },
271#endif
272 { 0, 0, 0, 0 }
273};
274
275#define COPY_UTSNAME_FIELD(dest, src) \
276 do { \
277 \
278 (void) strncpy((dest), (src), __NEW_UTS_LEN); \
279 (dest)[__NEW_UTS_LEN] = '\0'; \
280 } while (0)
281
282static int sys_uname(struct new_utsname *buf)
283{
284 struct utsname uts_buf;
285
286 if (uname(&uts_buf) < 0)
287 return (-1);
288
289
290
291
292
293
294
295 memset(buf, 0, sizeof(*buf));
296 COPY_UTSNAME_FIELD(buf->sysname, uts_buf.sysname);
297 COPY_UTSNAME_FIELD(buf->nodename, uts_buf.nodename);
298 COPY_UTSNAME_FIELD(buf->release, uts_buf.release);
299 COPY_UTSNAME_FIELD(buf->version, uts_buf.version);
300 COPY_UTSNAME_FIELD(buf->machine, uts_buf.machine);
301#ifdef _GNU_SOURCE
302 COPY_UTSNAME_FIELD(buf->domainname, uts_buf.domainname);
303#endif
304 return (0);
305
306#undef COPY_UTSNAME_FIELD
307}
308
309static int sys_getcwd1(char *buf, size_t size)
310{
311 if (getcwd(buf, size) == NULL) {
312
313 return (-1);
314 }
315 return strlen(buf)+1;
316}
317
318#ifdef CONFIG_ATFILE
319
320
321
322
323
324#ifdef TARGET_NR_faccessat
325static int sys_faccessat(int dirfd, const char *pathname, int mode)
326{
327 return (faccessat(dirfd, pathname, mode, 0));
328}
329#endif
330#ifdef TARGET_NR_fchmodat
331static int sys_fchmodat(int dirfd, const char *pathname, mode_t mode)
332{
333 return (fchmodat(dirfd, pathname, mode, 0));
334}
335#endif
336#if defined(TARGET_NR_fchownat)
337static int sys_fchownat(int dirfd, const char *pathname, uid_t owner,
338 gid_t group, int flags)
339{
340 return (fchownat(dirfd, pathname, owner, group, flags));
341}
342#endif
343#ifdef __NR_fstatat64
344static int sys_fstatat64(int dirfd, const char *pathname, struct stat *buf,
345 int flags)
346{
347 return (fstatat(dirfd, pathname, buf, flags));
348}
349#endif
350#ifdef __NR_newfstatat
351static int sys_newfstatat(int dirfd, const char *pathname, struct stat *buf,
352 int flags)
353{
354 return (fstatat(dirfd, pathname, buf, flags));
355}
356#endif
357#ifdef TARGET_NR_futimesat
358static int sys_futimesat(int dirfd, const char *pathname,
359 const struct timeval times[2])
360{
361 return (futimesat(dirfd, pathname, times));
362}
363#endif
364#ifdef TARGET_NR_linkat
365static int sys_linkat(int olddirfd, const char *oldpath,
366 int newdirfd, const char *newpath, int flags)
367{
368 return (linkat(olddirfd, oldpath, newdirfd, newpath, flags));
369}
370#endif
371#ifdef TARGET_NR_mkdirat
372static int sys_mkdirat(int dirfd, const char *pathname, mode_t mode)
373{
374 return (mkdirat(dirfd, pathname, mode));
375}
376#endif
377#ifdef TARGET_NR_mknodat
378static int sys_mknodat(int dirfd, const char *pathname, mode_t mode,
379 dev_t dev)
380{
381 return (mknodat(dirfd, pathname, mode, dev));
382}
383#endif
384#ifdef TARGET_NR_openat
385static int sys_openat(int dirfd, const char *pathname, int flags, mode_t mode)
386{
387
388
389
390
391 if ((flags & O_CREAT) != 0) {
392 return (openat(dirfd, pathname, flags, mode));
393 }
394 return (openat(dirfd, pathname, flags));
395}
396#endif
397#ifdef TARGET_NR_readlinkat
398static int sys_readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz)
399{
400 return (readlinkat(dirfd, pathname, buf, bufsiz));
401}
402#endif
403#ifdef TARGET_NR_renameat
404static int sys_renameat(int olddirfd, const char *oldpath,
405 int newdirfd, const char *newpath)
406{
407 return (renameat(olddirfd, oldpath, newdirfd, newpath));
408}
409#endif
410#ifdef TARGET_NR_symlinkat
411static int sys_symlinkat(const char *oldpath, int newdirfd, const char *newpath)
412{
413 return (symlinkat(oldpath, newdirfd, newpath));
414}
415#endif
416#ifdef TARGET_NR_unlinkat
417static int sys_unlinkat(int dirfd, const char *pathname, int flags)
418{
419 return (unlinkat(dirfd, pathname, flags));
420}
421#endif
422#else
423
424
425
426
427#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
428_syscall3(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode)
429#endif
430#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
431_syscall3(int,sys_fchmodat,int,dirfd,const char *,pathname, mode_t,mode)
432#endif
433#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
434_syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
435 uid_t,owner,gid_t,group,int,flags)
436#endif
437#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
438 defined(__NR_fstatat64)
439_syscall4(int,sys_fstatat64,int,dirfd,const char *,pathname,
440 struct stat *,buf,int,flags)
441#endif
442#if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
443_syscall3(int,sys_futimesat,int,dirfd,const char *,pathname,
444 const struct timeval *,times)
445#endif
446#if (defined(TARGET_NR_newfstatat) || defined(TARGET_NR_fstatat64) ) && \
447 defined(__NR_newfstatat)
448_syscall4(int,sys_newfstatat,int,dirfd,const char *,pathname,
449 struct stat *,buf,int,flags)
450#endif
451#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
452_syscall5(int,sys_linkat,int,olddirfd,const char *,oldpath,
453 int,newdirfd,const char *,newpath,int,flags)
454#endif
455#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
456_syscall3(int,sys_mkdirat,int,dirfd,const char *,pathname,mode_t,mode)
457#endif
458#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
459_syscall4(int,sys_mknodat,int,dirfd,const char *,pathname,
460 mode_t,mode,dev_t,dev)
461#endif
462#if defined(TARGET_NR_openat) && defined(__NR_openat)
463_syscall4(int,sys_openat,int,dirfd,const char *,pathname,int,flags,mode_t,mode)
464#endif
465#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
466_syscall4(int,sys_readlinkat,int,dirfd,const char *,pathname,
467 char *,buf,size_t,bufsize)
468#endif
469#if defined(TARGET_NR_renameat) && defined(__NR_renameat)
470_syscall4(int,sys_renameat,int,olddirfd,const char *,oldpath,
471 int,newdirfd,const char *,newpath)
472#endif
473#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
474_syscall3(int,sys_symlinkat,const char *,oldpath,
475 int,newdirfd,const char *,newpath)
476#endif
477#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
478_syscall3(int,sys_unlinkat,int,dirfd,const char *,pathname,int,flags)
479#endif
480
481#endif
482
483#ifdef CONFIG_UTIMENSAT
484static int sys_utimensat(int dirfd, const char *pathname,
485 const struct timespec times[2], int flags)
486{
487 if (pathname == NULL)
488 return futimens(dirfd, times);
489 else
490 return utimensat(dirfd, pathname, times, flags);
491}
492#else
493#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
494_syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
495 const struct timespec *,tsp,int,flags)
496#endif
497#endif
498
499#ifdef CONFIG_INOTIFY
500#include <sys/inotify.h>
501
502#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
503static int sys_inotify_init(void)
504{
505 return (inotify_init());
506}
507#endif
508#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
509static int sys_inotify_add_watch(int fd,const char *pathname, int32_t mask)
510{
511 return (inotify_add_watch(fd, pathname, mask));
512}
513#endif
514#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
515static int sys_inotify_rm_watch(int fd, int32_t wd)
516{
517 return (inotify_rm_watch(fd, wd));
518}
519#endif
520#ifdef CONFIG_INOTIFY1
521#if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
522static int sys_inotify_init1(int flags)
523{
524 return (inotify_init1(flags));
525}
526#endif
527#endif
528#else
529
530#undef TARGET_NR_inotify_init
531#undef TARGET_NR_inotify_init1
532#undef TARGET_NR_inotify_add_watch
533#undef TARGET_NR_inotify_rm_watch
534#endif
535
536#if defined(TARGET_NR_ppoll)
537#ifndef __NR_ppoll
538# define __NR_ppoll -1
539#endif
540#define __NR_sys_ppoll __NR_ppoll
541_syscall5(int, sys_ppoll, struct pollfd *, fds, nfds_t, nfds,
542 struct timespec *, timeout, const __sigset_t *, sigmask,
543 size_t, sigsetsize)
544#endif
545
546#if defined(TARGET_NR_pselect6)
547#ifndef __NR_pselect6
548# define __NR_pselect6 -1
549#endif
550#define __NR_sys_pselect6 __NR_pselect6
551_syscall6(int, sys_pselect6, int, nfds, fd_set *, readfds, fd_set *, writefds,
552 fd_set *, exceptfds, struct timespec *, timeout, void *, sig);
553#endif
554
555#if defined(TARGET_NR_prlimit64)
556#ifndef __NR_prlimit64
557# define __NR_prlimit64 -1
558#endif
559#define __NR_sys_prlimit64 __NR_prlimit64
560
561struct host_rlimit64 {
562 uint64_t rlim_cur;
563 uint64_t rlim_max;
564};
565_syscall4(int, sys_prlimit64, pid_t, pid, int, resource,
566 const struct host_rlimit64 *, new_limit,
567 struct host_rlimit64 *, old_limit)
568#endif
569
570extern int personality(int);
571extern int flock(int, int);
572extern int setfsuid(int);
573extern int setfsgid(int);
574extern int setgroups(int, gid_t *);
575
576
577#ifdef TARGET_ARM
578static inline int regpairs_aligned(void *cpu_env) {
579 return ((((CPUARMState *)cpu_env)->eabi) == 1) ;
580}
581#elif defined(TARGET_MIPS)
582static inline int regpairs_aligned(void *cpu_env) { return 1; }
583#else
584static inline int regpairs_aligned(void *cpu_env) { return 0; }
585#endif
586
587#define ERRNO_TABLE_SIZE 1200
588
589
590
591static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
592};
593
594
595
596
597
598static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
599 [EIDRM] = TARGET_EIDRM,
600 [ECHRNG] = TARGET_ECHRNG,
601 [EL2NSYNC] = TARGET_EL2NSYNC,
602 [EL3HLT] = TARGET_EL3HLT,
603 [EL3RST] = TARGET_EL3RST,
604 [ELNRNG] = TARGET_ELNRNG,
605 [EUNATCH] = TARGET_EUNATCH,
606 [ENOCSI] = TARGET_ENOCSI,
607 [EL2HLT] = TARGET_EL2HLT,
608 [EDEADLK] = TARGET_EDEADLK,
609 [ENOLCK] = TARGET_ENOLCK,
610 [EBADE] = TARGET_EBADE,
611 [EBADR] = TARGET_EBADR,
612 [EXFULL] = TARGET_EXFULL,
613 [ENOANO] = TARGET_ENOANO,
614 [EBADRQC] = TARGET_EBADRQC,
615 [EBADSLT] = TARGET_EBADSLT,
616 [EBFONT] = TARGET_EBFONT,
617 [ENOSTR] = TARGET_ENOSTR,
618 [ENODATA] = TARGET_ENODATA,
619 [ETIME] = TARGET_ETIME,
620 [ENOSR] = TARGET_ENOSR,
621 [ENONET] = TARGET_ENONET,
622 [ENOPKG] = TARGET_ENOPKG,
623 [EREMOTE] = TARGET_EREMOTE,
624 [ENOLINK] = TARGET_ENOLINK,
625 [EADV] = TARGET_EADV,
626 [ESRMNT] = TARGET_ESRMNT,
627 [ECOMM] = TARGET_ECOMM,
628 [EPROTO] = TARGET_EPROTO,
629 [EDOTDOT] = TARGET_EDOTDOT,
630 [EMULTIHOP] = TARGET_EMULTIHOP,
631 [EBADMSG] = TARGET_EBADMSG,
632 [ENAMETOOLONG] = TARGET_ENAMETOOLONG,
633 [EOVERFLOW] = TARGET_EOVERFLOW,
634 [ENOTUNIQ] = TARGET_ENOTUNIQ,
635 [EBADFD] = TARGET_EBADFD,
636 [EREMCHG] = TARGET_EREMCHG,
637 [ELIBACC] = TARGET_ELIBACC,
638 [ELIBBAD] = TARGET_ELIBBAD,
639 [ELIBSCN] = TARGET_ELIBSCN,
640 [ELIBMAX] = TARGET_ELIBMAX,
641 [ELIBEXEC] = TARGET_ELIBEXEC,
642 [EILSEQ] = TARGET_EILSEQ,
643 [ENOSYS] = TARGET_ENOSYS,
644 [ELOOP] = TARGET_ELOOP,
645 [ERESTART] = TARGET_ERESTART,
646 [ESTRPIPE] = TARGET_ESTRPIPE,
647 [ENOTEMPTY] = TARGET_ENOTEMPTY,
648 [EUSERS] = TARGET_EUSERS,
649 [ENOTSOCK] = TARGET_ENOTSOCK,
650 [EDESTADDRREQ] = TARGET_EDESTADDRREQ,
651 [EMSGSIZE] = TARGET_EMSGSIZE,
652 [EPROTOTYPE] = TARGET_EPROTOTYPE,
653 [ENOPROTOOPT] = TARGET_ENOPROTOOPT,
654 [EPROTONOSUPPORT] = TARGET_EPROTONOSUPPORT,
655 [ESOCKTNOSUPPORT] = TARGET_ESOCKTNOSUPPORT,
656 [EOPNOTSUPP] = TARGET_EOPNOTSUPP,
657 [EPFNOSUPPORT] = TARGET_EPFNOSUPPORT,
658 [EAFNOSUPPORT] = TARGET_EAFNOSUPPORT,
659 [EADDRINUSE] = TARGET_EADDRINUSE,
660 [EADDRNOTAVAIL] = TARGET_EADDRNOTAVAIL,
661 [ENETDOWN] = TARGET_ENETDOWN,
662 [ENETUNREACH] = TARGET_ENETUNREACH,
663 [ENETRESET] = TARGET_ENETRESET,
664 [ECONNABORTED] = TARGET_ECONNABORTED,
665 [ECONNRESET] = TARGET_ECONNRESET,
666 [ENOBUFS] = TARGET_ENOBUFS,
667 [EISCONN] = TARGET_EISCONN,
668 [ENOTCONN] = TARGET_ENOTCONN,
669 [EUCLEAN] = TARGET_EUCLEAN,
670 [ENOTNAM] = TARGET_ENOTNAM,
671 [ENAVAIL] = TARGET_ENAVAIL,
672 [EISNAM] = TARGET_EISNAM,
673 [EREMOTEIO] = TARGET_EREMOTEIO,
674 [ESHUTDOWN] = TARGET_ESHUTDOWN,
675 [ETOOMANYREFS] = TARGET_ETOOMANYREFS,
676 [ETIMEDOUT] = TARGET_ETIMEDOUT,
677 [ECONNREFUSED] = TARGET_ECONNREFUSED,
678 [EHOSTDOWN] = TARGET_EHOSTDOWN,
679 [EHOSTUNREACH] = TARGET_EHOSTUNREACH,
680 [EALREADY] = TARGET_EALREADY,
681 [EINPROGRESS] = TARGET_EINPROGRESS,
682 [ESTALE] = TARGET_ESTALE,
683 [ECANCELED] = TARGET_ECANCELED,
684 [ENOMEDIUM] = TARGET_ENOMEDIUM,
685 [EMEDIUMTYPE] = TARGET_EMEDIUMTYPE,
686#ifdef ENOKEY
687 [ENOKEY] = TARGET_ENOKEY,
688#endif
689#ifdef EKEYEXPIRED
690 [EKEYEXPIRED] = TARGET_EKEYEXPIRED,
691#endif
692#ifdef EKEYREVOKED
693 [EKEYREVOKED] = TARGET_EKEYREVOKED,
694#endif
695#ifdef EKEYREJECTED
696 [EKEYREJECTED] = TARGET_EKEYREJECTED,
697#endif
698#ifdef EOWNERDEAD
699 [EOWNERDEAD] = TARGET_EOWNERDEAD,
700#endif
701#ifdef ENOTRECOVERABLE
702 [ENOTRECOVERABLE] = TARGET_ENOTRECOVERABLE,
703#endif
704};
705
706static inline int host_to_target_errno(int err)
707{
708 if(host_to_target_errno_table[err])
709 return host_to_target_errno_table[err];
710 return err;
711}
712
713static inline int target_to_host_errno(int err)
714{
715 if (target_to_host_errno_table[err])
716 return target_to_host_errno_table[err];
717 return err;
718}
719
720static inline abi_long get_errno(abi_long ret)
721{
722 if (ret == -1)
723 return -host_to_target_errno(errno);
724 else
725 return ret;
726}
727
728static inline int is_error(abi_long ret)
729{
730 return (abi_ulong)ret >= (abi_ulong)(-4096);
731}
732
733char *target_strerror(int err)
734{
735 if ((err >= ERRNO_TABLE_SIZE) || (err < 0)) {
736 return NULL;
737 }
738 return strerror(target_to_host_errno(err));
739}
740
741static abi_ulong target_brk;
742static abi_ulong target_original_brk;
743static abi_ulong brk_page;
744
745void target_set_brk(abi_ulong new_brk)
746{
747 target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
748 brk_page = HOST_PAGE_ALIGN(target_brk);
749}
750
751
752#define DEBUGF_BRK(message, args...)
753
754
755abi_long do_brk(abi_ulong new_brk)
756{
757 abi_long mapped_addr;
758 int new_alloc_size;
759
760 DEBUGF_BRK("do_brk(" TARGET_ABI_FMT_lx ") -> ", new_brk);
761
762 if (!new_brk) {
763 DEBUGF_BRK(TARGET_ABI_FMT_lx " (!new_brk)\n", target_brk);
764 return target_brk;
765 }
766 if (new_brk < target_original_brk) {
767 DEBUGF_BRK(TARGET_ABI_FMT_lx " (new_brk < target_original_brk)\n",
768 target_brk);
769 return target_brk;
770 }
771
772
773
774 if (new_brk <= brk_page) {
775
776
777 if (new_brk > target_brk) {
778 memset(g2h(target_brk), 0, new_brk - target_brk);
779 }
780 target_brk = new_brk;
781 DEBUGF_BRK(TARGET_ABI_FMT_lx " (new_brk <= brk_page)\n", target_brk);
782 return target_brk;
783 }
784
785
786
787
788
789
790
791 new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page);
792 mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
793 PROT_READ|PROT_WRITE,
794 MAP_ANON|MAP_PRIVATE, 0, 0));
795
796 if (mapped_addr == brk_page) {
797
798
799
800
801
802
803
804 memset(g2h(target_brk), 0, brk_page - target_brk);
805
806 target_brk = new_brk;
807 brk_page = HOST_PAGE_ALIGN(target_brk);
808 DEBUGF_BRK(TARGET_ABI_FMT_lx " (mapped_addr == brk_page)\n",
809 target_brk);
810 return target_brk;
811 } else if (mapped_addr != -1) {
812
813
814
815 target_munmap(mapped_addr, new_alloc_size);
816 mapped_addr = -1;
817 DEBUGF_BRK(TARGET_ABI_FMT_lx " (mapped_addr != -1)\n", target_brk);
818 }
819 else {
820 DEBUGF_BRK(TARGET_ABI_FMT_lx " (otherwise)\n", target_brk);
821 }
822
823#if defined(TARGET_ALPHA)
824
825
826 return -TARGET_ENOMEM;
827#endif
828
829 return target_brk;
830}
831
832static inline abi_long copy_from_user_fdset(fd_set *fds,
833 abi_ulong target_fds_addr,
834 int n)
835{
836 int i, nw, j, k;
837 abi_ulong b, *target_fds;
838
839 nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
840 if (!(target_fds = lock_user(VERIFY_READ,
841 target_fds_addr,
842 sizeof(abi_ulong) * nw,
843 1)))
844 return -TARGET_EFAULT;
845
846 FD_ZERO(fds);
847 k = 0;
848 for (i = 0; i < nw; i++) {
849
850 __get_user(b, &target_fds[i]);
851 for (j = 0; j < TARGET_ABI_BITS; j++) {
852
853 if ((b >> j) & 1)
854 FD_SET(k, fds);
855 k++;
856 }
857 }
858
859 unlock_user(target_fds, target_fds_addr, 0);
860
861 return 0;
862}
863
864static inline abi_ulong copy_from_user_fdset_ptr(fd_set *fds, fd_set **fds_ptr,
865 abi_ulong target_fds_addr,
866 int n)
867{
868 if (target_fds_addr) {
869 if (copy_from_user_fdset(fds, target_fds_addr, n))
870 return -TARGET_EFAULT;
871 *fds_ptr = fds;
872 } else {
873 *fds_ptr = NULL;
874 }
875 return 0;
876}
877
878static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
879 const fd_set *fds,
880 int n)
881{
882 int i, nw, j, k;
883 abi_long v;
884 abi_ulong *target_fds;
885
886 nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
887 if (!(target_fds = lock_user(VERIFY_WRITE,
888 target_fds_addr,
889 sizeof(abi_ulong) * nw,
890 0)))
891 return -TARGET_EFAULT;
892
893 k = 0;
894 for (i = 0; i < nw; i++) {
895 v = 0;
896 for (j = 0; j < TARGET_ABI_BITS; j++) {
897 v |= ((FD_ISSET(k, fds) != 0) << j);
898 k++;
899 }
900 __put_user(v, &target_fds[i]);
901 }
902
903 unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
904
905 return 0;
906}
907
908#if defined(__alpha__)
909#define HOST_HZ 1024
910#else
911#define HOST_HZ 100
912#endif
913
914static inline abi_long host_to_target_clock_t(long ticks)
915{
916#if HOST_HZ == TARGET_HZ
917 return ticks;
918#else
919 return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
920#endif
921}
922
923static inline abi_long host_to_target_rusage(abi_ulong target_addr,
924 const struct rusage *rusage)
925{
926 struct target_rusage *target_rusage;
927
928 if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
929 return -TARGET_EFAULT;
930 target_rusage->ru_utime.tv_sec = tswapal(rusage->ru_utime.tv_sec);
931 target_rusage->ru_utime.tv_usec = tswapal(rusage->ru_utime.tv_usec);
932 target_rusage->ru_stime.tv_sec = tswapal(rusage->ru_stime.tv_sec);
933 target_rusage->ru_stime.tv_usec = tswapal(rusage->ru_stime.tv_usec);
934 target_rusage->ru_maxrss = tswapal(rusage->ru_maxrss);
935 target_rusage->ru_ixrss = tswapal(rusage->ru_ixrss);
936 target_rusage->ru_idrss = tswapal(rusage->ru_idrss);
937 target_rusage->ru_isrss = tswapal(rusage->ru_isrss);
938 target_rusage->ru_minflt = tswapal(rusage->ru_minflt);
939 target_rusage->ru_majflt = tswapal(rusage->ru_majflt);
940 target_rusage->ru_nswap = tswapal(rusage->ru_nswap);
941 target_rusage->ru_inblock = tswapal(rusage->ru_inblock);
942 target_rusage->ru_oublock = tswapal(rusage->ru_oublock);
943 target_rusage->ru_msgsnd = tswapal(rusage->ru_msgsnd);
944 target_rusage->ru_msgrcv = tswapal(rusage->ru_msgrcv);
945 target_rusage->ru_nsignals = tswapal(rusage->ru_nsignals);
946 target_rusage->ru_nvcsw = tswapal(rusage->ru_nvcsw);
947 target_rusage->ru_nivcsw = tswapal(rusage->ru_nivcsw);
948 unlock_user_struct(target_rusage, target_addr, 1);
949
950 return 0;
951}
952
953static inline rlim_t target_to_host_rlim(abi_ulong target_rlim)
954{
955 abi_ulong target_rlim_swap;
956 rlim_t result;
957
958 target_rlim_swap = tswapal(target_rlim);
959 if (target_rlim_swap == TARGET_RLIM_INFINITY)
960 return RLIM_INFINITY;
961
962 result = target_rlim_swap;
963 if (target_rlim_swap != (rlim_t)result)
964 return RLIM_INFINITY;
965
966 return result;
967}
968
969static inline abi_ulong host_to_target_rlim(rlim_t rlim)
970{
971 abi_ulong target_rlim_swap;
972 abi_ulong result;
973
974 if (rlim == RLIM_INFINITY || rlim != (abi_long)rlim)
975 target_rlim_swap = TARGET_RLIM_INFINITY;
976 else
977 target_rlim_swap = rlim;
978 result = tswapal(target_rlim_swap);
979
980 return result;
981}
982
983static inline int target_to_host_resource(int code)
984{
985 switch (code) {
986 case TARGET_RLIMIT_AS:
987 return RLIMIT_AS;
988 case TARGET_RLIMIT_CORE:
989 return RLIMIT_CORE;
990 case TARGET_RLIMIT_CPU:
991 return RLIMIT_CPU;
992 case TARGET_RLIMIT_DATA:
993 return RLIMIT_DATA;
994 case TARGET_RLIMIT_FSIZE:
995 return RLIMIT_FSIZE;
996 case TARGET_RLIMIT_LOCKS:
997 return RLIMIT_LOCKS;
998 case TARGET_RLIMIT_MEMLOCK:
999 return RLIMIT_MEMLOCK;
1000 case TARGET_RLIMIT_MSGQUEUE:
1001 return RLIMIT_MSGQUEUE;
1002 case TARGET_RLIMIT_NICE:
1003 return RLIMIT_NICE;
1004 case TARGET_RLIMIT_NOFILE:
1005 return RLIMIT_NOFILE;
1006 case TARGET_RLIMIT_NPROC:
1007 return RLIMIT_NPROC;
1008 case TARGET_RLIMIT_RSS:
1009 return RLIMIT_RSS;
1010 case TARGET_RLIMIT_RTPRIO:
1011 return RLIMIT_RTPRIO;
1012 case TARGET_RLIMIT_SIGPENDING:
1013 return RLIMIT_SIGPENDING;
1014 case TARGET_RLIMIT_STACK:
1015 return RLIMIT_STACK;
1016 default:
1017 return code;
1018 }
1019}
1020
1021static inline abi_long copy_from_user_timeval(struct timeval *tv,
1022 abi_ulong target_tv_addr)
1023{
1024 struct target_timeval *target_tv;
1025
1026 if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
1027 return -TARGET_EFAULT;
1028
1029 __get_user(tv->tv_sec, &target_tv->tv_sec);
1030 __get_user(tv->tv_usec, &target_tv->tv_usec);
1031
1032 unlock_user_struct(target_tv, target_tv_addr, 0);
1033
1034 return 0;
1035}
1036
1037static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
1038 const struct timeval *tv)
1039{
1040 struct target_timeval *target_tv;
1041
1042 if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
1043 return -TARGET_EFAULT;
1044
1045 __put_user(tv->tv_sec, &target_tv->tv_sec);
1046 __put_user(tv->tv_usec, &target_tv->tv_usec);
1047
1048 unlock_user_struct(target_tv, target_tv_addr, 1);
1049
1050 return 0;
1051}
1052
1053#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
1054#include <mqueue.h>
1055
1056static inline abi_long copy_from_user_mq_attr(struct mq_attr *attr,
1057 abi_ulong target_mq_attr_addr)
1058{
1059 struct target_mq_attr *target_mq_attr;
1060
1061 if (!lock_user_struct(VERIFY_READ, target_mq_attr,
1062 target_mq_attr_addr, 1))
1063 return -TARGET_EFAULT;
1064
1065 __get_user(attr->mq_flags, &target_mq_attr->mq_flags);
1066 __get_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
1067 __get_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
1068 __get_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
1069
1070 unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0);
1071
1072 return 0;
1073}
1074
1075static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr,
1076 const struct mq_attr *attr)
1077{
1078 struct target_mq_attr *target_mq_attr;
1079
1080 if (!lock_user_struct(VERIFY_WRITE, target_mq_attr,
1081 target_mq_attr_addr, 0))
1082 return -TARGET_EFAULT;
1083
1084 __put_user(attr->mq_flags, &target_mq_attr->mq_flags);
1085 __put_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
1086 __put_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
1087 __put_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
1088
1089 unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1);
1090
1091 return 0;
1092}
1093#endif
1094
1095#if defined(TARGET_NR_select) || defined(TARGET_NR__newselect)
1096
1097static abi_long do_select(int n,
1098 abi_ulong rfd_addr, abi_ulong wfd_addr,
1099 abi_ulong efd_addr, abi_ulong target_tv_addr)
1100{
1101 fd_set rfds, wfds, efds;
1102 fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
1103 struct timeval tv, *tv_ptr;
1104 abi_long ret;
1105
1106 ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
1107 if (ret) {
1108 return ret;
1109 }
1110 ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
1111 if (ret) {
1112 return ret;
1113 }
1114 ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
1115 if (ret) {
1116 return ret;
1117 }
1118
1119 if (target_tv_addr) {
1120 if (copy_from_user_timeval(&tv, target_tv_addr))
1121 return -TARGET_EFAULT;
1122 tv_ptr = &tv;
1123 } else {
1124 tv_ptr = NULL;
1125 }
1126
1127 ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
1128
1129 if (!is_error(ret)) {
1130 if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
1131 return -TARGET_EFAULT;
1132 if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
1133 return -TARGET_EFAULT;
1134 if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
1135 return -TARGET_EFAULT;
1136
1137 if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
1138 return -TARGET_EFAULT;
1139 }
1140
1141 return ret;
1142}
1143#endif
1144
1145static abi_long do_pipe2(int host_pipe[], int flags)
1146{
1147#ifdef CONFIG_PIPE2
1148 return pipe2(host_pipe, flags);
1149#else
1150 return -ENOSYS;
1151#endif
1152}
1153
1154static abi_long do_pipe(void *cpu_env, abi_ulong pipedes,
1155 int flags, int is_pipe2)
1156{
1157 int host_pipe[2];
1158 abi_long ret;
1159 ret = flags ? do_pipe2(host_pipe, flags) : pipe(host_pipe);
1160
1161 if (is_error(ret))
1162 return get_errno(ret);
1163
1164
1165
1166 if (!is_pipe2) {
1167#if defined(TARGET_ALPHA)
1168 ((CPUAlphaState *)cpu_env)->ir[IR_A4] = host_pipe[1];
1169 return host_pipe[0];
1170#elif defined(TARGET_MIPS)
1171 ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1];
1172 return host_pipe[0];
1173#elif defined(TARGET_SH4)
1174 ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
1175 return host_pipe[0];
1176#endif
1177 }
1178
1179 if (put_user_s32(host_pipe[0], pipedes)
1180 || put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0])))
1181 return -TARGET_EFAULT;
1182 return get_errno(ret);
1183}
1184
1185static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn,
1186 abi_ulong target_addr,
1187 socklen_t len)
1188{
1189 struct target_ip_mreqn *target_smreqn;
1190
1191 target_smreqn = lock_user(VERIFY_READ, target_addr, len, 1);
1192 if (!target_smreqn)
1193 return -TARGET_EFAULT;
1194 mreqn->imr_multiaddr.s_addr = target_smreqn->imr_multiaddr.s_addr;
1195 mreqn->imr_address.s_addr = target_smreqn->imr_address.s_addr;
1196 if (len == sizeof(struct target_ip_mreqn))
1197 mreqn->imr_ifindex = tswapal(target_smreqn->imr_ifindex);
1198 unlock_user(target_smreqn, target_addr, 0);
1199
1200 return 0;
1201}
1202
1203static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
1204 abi_ulong target_addr,
1205 socklen_t len)
1206{
1207 const socklen_t unix_maxlen = sizeof (struct sockaddr_un);
1208 sa_family_t sa_family;
1209 struct target_sockaddr *target_saddr;
1210
1211 target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
1212 if (!target_saddr)
1213 return -TARGET_EFAULT;
1214
1215 sa_family = tswap16(target_saddr->sa_family);
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225 if (sa_family == AF_UNIX) {
1226 if (len < unix_maxlen && len > 0) {
1227 char *cp = (char*)target_saddr;
1228
1229 if ( cp[len-1] && !cp[len] )
1230 len++;
1231 }
1232 if (len > unix_maxlen)
1233 len = unix_maxlen;
1234 }
1235
1236 memcpy(addr, target_saddr, len);
1237 addr->sa_family = sa_family;
1238 unlock_user(target_saddr, target_addr, 0);
1239
1240 return 0;
1241}
1242
1243static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
1244 struct sockaddr *addr,
1245 socklen_t len)
1246{
1247 struct target_sockaddr *target_saddr;
1248
1249 target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
1250 if (!target_saddr)
1251 return -TARGET_EFAULT;
1252 memcpy(target_saddr, addr, len);
1253 target_saddr->sa_family = tswap16(addr->sa_family);
1254 unlock_user(target_saddr, target_addr, len);
1255
1256 return 0;
1257}
1258
1259
1260static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
1261 struct target_msghdr *target_msgh)
1262{
1263 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1264 abi_long msg_controllen;
1265 abi_ulong target_cmsg_addr;
1266 struct target_cmsghdr *target_cmsg;
1267 socklen_t space = 0;
1268
1269 msg_controllen = tswapal(target_msgh->msg_controllen);
1270 if (msg_controllen < sizeof (struct target_cmsghdr))
1271 goto the_end;
1272 target_cmsg_addr = tswapal(target_msgh->msg_control);
1273 target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
1274 if (!target_cmsg)
1275 return -TARGET_EFAULT;
1276
1277 while (cmsg && target_cmsg) {
1278 void *data = CMSG_DATA(cmsg);
1279 void *target_data = TARGET_CMSG_DATA(target_cmsg);
1280
1281 int len = tswapal(target_cmsg->cmsg_len)
1282 - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
1283
1284 space += CMSG_SPACE(len);
1285 if (space > msgh->msg_controllen) {
1286 space -= CMSG_SPACE(len);
1287 gemu_log("Host cmsg overflow\n");
1288 break;
1289 }
1290
1291 cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
1292 cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
1293 cmsg->cmsg_len = CMSG_LEN(len);
1294
1295 if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1296 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1297 memcpy(data, target_data, len);
1298 } else {
1299 int *fd = (int *)data;
1300 int *target_fd = (int *)target_data;
1301 int i, numfds = len / sizeof(int);
1302
1303 for (i = 0; i < numfds; i++)
1304 fd[i] = tswap32(target_fd[i]);
1305 }
1306
1307 cmsg = CMSG_NXTHDR(msgh, cmsg);
1308 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1309 }
1310 unlock_user(target_cmsg, target_cmsg_addr, 0);
1311 the_end:
1312 msgh->msg_controllen = space;
1313 return 0;
1314}
1315
1316
1317static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
1318 struct msghdr *msgh)
1319{
1320 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1321 abi_long msg_controllen;
1322 abi_ulong target_cmsg_addr;
1323 struct target_cmsghdr *target_cmsg;
1324 socklen_t space = 0;
1325
1326 msg_controllen = tswapal(target_msgh->msg_controllen);
1327 if (msg_controllen < sizeof (struct target_cmsghdr))
1328 goto the_end;
1329 target_cmsg_addr = tswapal(target_msgh->msg_control);
1330 target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
1331 if (!target_cmsg)
1332 return -TARGET_EFAULT;
1333
1334 while (cmsg && target_cmsg) {
1335 void *data = CMSG_DATA(cmsg);
1336 void *target_data = TARGET_CMSG_DATA(target_cmsg);
1337
1338 int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
1339
1340 space += TARGET_CMSG_SPACE(len);
1341 if (space > msg_controllen) {
1342 space -= TARGET_CMSG_SPACE(len);
1343 gemu_log("Target cmsg overflow\n");
1344 break;
1345 }
1346
1347 target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
1348 target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
1349 target_cmsg->cmsg_len = tswapal(TARGET_CMSG_LEN(len));
1350
1351 if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1352 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1353 memcpy(target_data, data, len);
1354 } else {
1355 int *fd = (int *)data;
1356 int *target_fd = (int *)target_data;
1357 int i, numfds = len / sizeof(int);
1358
1359 for (i = 0; i < numfds; i++)
1360 target_fd[i] = tswap32(fd[i]);
1361 }
1362
1363 cmsg = CMSG_NXTHDR(msgh, cmsg);
1364 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1365 }
1366 unlock_user(target_cmsg, target_cmsg_addr, space);
1367 the_end:
1368 target_msgh->msg_controllen = tswapal(space);
1369 return 0;
1370}
1371
1372
1373static abi_long do_setsockopt(int sockfd, int level, int optname,
1374 abi_ulong optval_addr, socklen_t optlen)
1375{
1376 abi_long ret;
1377 int val;
1378 struct ip_mreqn *ip_mreq;
1379 struct ip_mreq_source *ip_mreq_source;
1380
1381 switch(level) {
1382 case SOL_TCP:
1383
1384 if (optlen < sizeof(uint32_t))
1385 return -TARGET_EINVAL;
1386
1387 if (get_user_u32(val, optval_addr))
1388 return -TARGET_EFAULT;
1389 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1390 break;
1391 case SOL_IP:
1392 switch(optname) {
1393 case IP_TOS:
1394 case IP_TTL:
1395 case IP_HDRINCL:
1396 case IP_ROUTER_ALERT:
1397 case IP_RECVOPTS:
1398 case IP_RETOPTS:
1399 case IP_PKTINFO:
1400 case IP_MTU_DISCOVER:
1401 case IP_RECVERR:
1402 case IP_RECVTOS:
1403#ifdef IP_FREEBIND
1404 case IP_FREEBIND:
1405#endif
1406 case IP_MULTICAST_TTL:
1407 case IP_MULTICAST_LOOP:
1408 val = 0;
1409 if (optlen >= sizeof(uint32_t)) {
1410 if (get_user_u32(val, optval_addr))
1411 return -TARGET_EFAULT;
1412 } else if (optlen >= 1) {
1413 if (get_user_u8(val, optval_addr))
1414 return -TARGET_EFAULT;
1415 }
1416 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1417 break;
1418 case IP_ADD_MEMBERSHIP:
1419 case IP_DROP_MEMBERSHIP:
1420 if (optlen < sizeof (struct target_ip_mreq) ||
1421 optlen > sizeof (struct target_ip_mreqn))
1422 return -TARGET_EINVAL;
1423
1424 ip_mreq = (struct ip_mreqn *) alloca(optlen);
1425 target_to_host_ip_mreq(ip_mreq, optval_addr, optlen);
1426 ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq, optlen));
1427 break;
1428
1429 case IP_BLOCK_SOURCE:
1430 case IP_UNBLOCK_SOURCE:
1431 case IP_ADD_SOURCE_MEMBERSHIP:
1432 case IP_DROP_SOURCE_MEMBERSHIP:
1433 if (optlen != sizeof (struct target_ip_mreq_source))
1434 return -TARGET_EINVAL;
1435
1436 ip_mreq_source = lock_user(VERIFY_READ, optval_addr, optlen, 1);
1437 ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq_source, optlen));
1438 unlock_user (ip_mreq_source, optval_addr, 0);
1439 break;
1440
1441 default:
1442 goto unimplemented;
1443 }
1444 break;
1445 case TARGET_SOL_SOCKET:
1446 switch (optname) {
1447
1448 case TARGET_SO_DEBUG:
1449 optname = SO_DEBUG;
1450 break;
1451 case TARGET_SO_REUSEADDR:
1452 optname = SO_REUSEADDR;
1453 break;
1454 case TARGET_SO_TYPE:
1455 optname = SO_TYPE;
1456 break;
1457 case TARGET_SO_ERROR:
1458 optname = SO_ERROR;
1459 break;
1460 case TARGET_SO_DONTROUTE:
1461 optname = SO_DONTROUTE;
1462 break;
1463 case TARGET_SO_BROADCAST:
1464 optname = SO_BROADCAST;
1465 break;
1466 case TARGET_SO_SNDBUF:
1467 optname = SO_SNDBUF;
1468 break;
1469 case TARGET_SO_RCVBUF:
1470 optname = SO_RCVBUF;
1471 break;
1472 case TARGET_SO_KEEPALIVE:
1473 optname = SO_KEEPALIVE;
1474 break;
1475 case TARGET_SO_OOBINLINE:
1476 optname = SO_OOBINLINE;
1477 break;
1478 case TARGET_SO_NO_CHECK:
1479 optname = SO_NO_CHECK;
1480 break;
1481 case TARGET_SO_PRIORITY:
1482 optname = SO_PRIORITY;
1483 break;
1484#ifdef SO_BSDCOMPAT
1485 case TARGET_SO_BSDCOMPAT:
1486 optname = SO_BSDCOMPAT;
1487 break;
1488#endif
1489 case TARGET_SO_PASSCRED:
1490 optname = SO_PASSCRED;
1491 break;
1492 case TARGET_SO_TIMESTAMP:
1493 optname = SO_TIMESTAMP;
1494 break;
1495 case TARGET_SO_RCVLOWAT:
1496 optname = SO_RCVLOWAT;
1497 break;
1498 case TARGET_SO_RCVTIMEO:
1499 optname = SO_RCVTIMEO;
1500 break;
1501 case TARGET_SO_SNDTIMEO:
1502 optname = SO_SNDTIMEO;
1503 break;
1504 break;
1505 default:
1506 goto unimplemented;
1507 }
1508 if (optlen < sizeof(uint32_t))
1509 return -TARGET_EINVAL;
1510
1511 if (get_user_u32(val, optval_addr))
1512 return -TARGET_EFAULT;
1513 ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
1514 break;
1515 default:
1516 unimplemented:
1517 gemu_log("Unsupported setsockopt level=%d optname=%d\n", level, optname);
1518 ret = -TARGET_ENOPROTOOPT;
1519 }
1520 return ret;
1521}
1522
1523
1524static abi_long do_getsockopt(int sockfd, int level, int optname,
1525 abi_ulong optval_addr, abi_ulong optlen)
1526{
1527 abi_long ret;
1528 int len, val;
1529 socklen_t lv;
1530
1531 switch(level) {
1532 case TARGET_SOL_SOCKET:
1533 level = SOL_SOCKET;
1534 switch (optname) {
1535
1536 case TARGET_SO_LINGER:
1537 case TARGET_SO_RCVTIMEO:
1538 case TARGET_SO_SNDTIMEO:
1539 case TARGET_SO_PEERNAME:
1540 goto unimplemented;
1541 case TARGET_SO_PEERCRED: {
1542 struct ucred cr;
1543 socklen_t crlen;
1544 struct target_ucred *tcr;
1545
1546 if (get_user_u32(len, optlen)) {
1547 return -TARGET_EFAULT;
1548 }
1549 if (len < 0) {
1550 return -TARGET_EINVAL;
1551 }
1552
1553 crlen = sizeof(cr);
1554 ret = get_errno(getsockopt(sockfd, level, SO_PEERCRED,
1555 &cr, &crlen));
1556 if (ret < 0) {
1557 return ret;
1558 }
1559 if (len > crlen) {
1560 len = crlen;
1561 }
1562 if (!lock_user_struct(VERIFY_WRITE, tcr, optval_addr, 0)) {
1563 return -TARGET_EFAULT;
1564 }
1565 __put_user(cr.pid, &tcr->pid);
1566 __put_user(cr.uid, &tcr->uid);
1567 __put_user(cr.gid, &tcr->gid);
1568 unlock_user_struct(tcr, optval_addr, 1);
1569 if (put_user_u32(len, optlen)) {
1570 return -TARGET_EFAULT;
1571 }
1572 break;
1573 }
1574
1575 case TARGET_SO_DEBUG:
1576 optname = SO_DEBUG;
1577 goto int_case;
1578 case TARGET_SO_REUSEADDR:
1579 optname = SO_REUSEADDR;
1580 goto int_case;
1581 case TARGET_SO_TYPE:
1582 optname = SO_TYPE;
1583 goto int_case;
1584 case TARGET_SO_ERROR:
1585 optname = SO_ERROR;
1586 goto int_case;
1587 case TARGET_SO_DONTROUTE:
1588 optname = SO_DONTROUTE;
1589 goto int_case;
1590 case TARGET_SO_BROADCAST:
1591 optname = SO_BROADCAST;
1592 goto int_case;
1593 case TARGET_SO_SNDBUF:
1594 optname = SO_SNDBUF;
1595 goto int_case;
1596 case TARGET_SO_RCVBUF:
1597 optname = SO_RCVBUF;
1598 goto int_case;
1599 case TARGET_SO_KEEPALIVE:
1600 optname = SO_KEEPALIVE;
1601 goto int_case;
1602 case TARGET_SO_OOBINLINE:
1603 optname = SO_OOBINLINE;
1604 goto int_case;
1605 case TARGET_SO_NO_CHECK:
1606 optname = SO_NO_CHECK;
1607 goto int_case;
1608 case TARGET_SO_PRIORITY:
1609 optname = SO_PRIORITY;
1610 goto int_case;
1611#ifdef SO_BSDCOMPAT
1612 case TARGET_SO_BSDCOMPAT:
1613 optname = SO_BSDCOMPAT;
1614 goto int_case;
1615#endif
1616 case TARGET_SO_PASSCRED:
1617 optname = SO_PASSCRED;
1618 goto int_case;
1619 case TARGET_SO_TIMESTAMP:
1620 optname = SO_TIMESTAMP;
1621 goto int_case;
1622 case TARGET_SO_RCVLOWAT:
1623 optname = SO_RCVLOWAT;
1624 goto int_case;
1625 default:
1626 goto int_case;
1627 }
1628 break;
1629 case SOL_TCP:
1630
1631 int_case:
1632 if (get_user_u32(len, optlen))
1633 return -TARGET_EFAULT;
1634 if (len < 0)
1635 return -TARGET_EINVAL;
1636 lv = sizeof(lv);
1637 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1638 if (ret < 0)
1639 return ret;
1640 if (len > lv)
1641 len = lv;
1642 if (len == 4) {
1643 if (put_user_u32(val, optval_addr))
1644 return -TARGET_EFAULT;
1645 } else {
1646 if (put_user_u8(val, optval_addr))
1647 return -TARGET_EFAULT;
1648 }
1649 if (put_user_u32(len, optlen))
1650 return -TARGET_EFAULT;
1651 break;
1652 case SOL_IP:
1653 switch(optname) {
1654 case IP_TOS:
1655 case IP_TTL:
1656 case IP_HDRINCL:
1657 case IP_ROUTER_ALERT:
1658 case IP_RECVOPTS:
1659 case IP_RETOPTS:
1660 case IP_PKTINFO:
1661 case IP_MTU_DISCOVER:
1662 case IP_RECVERR:
1663 case IP_RECVTOS:
1664#ifdef IP_FREEBIND
1665 case IP_FREEBIND:
1666#endif
1667 case IP_MULTICAST_TTL:
1668 case IP_MULTICAST_LOOP:
1669 if (get_user_u32(len, optlen))
1670 return -TARGET_EFAULT;
1671 if (len < 0)
1672 return -TARGET_EINVAL;
1673 lv = sizeof(lv);
1674 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1675 if (ret < 0)
1676 return ret;
1677 if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
1678 len = 1;
1679 if (put_user_u32(len, optlen)
1680 || put_user_u8(val, optval_addr))
1681 return -TARGET_EFAULT;
1682 } else {
1683 if (len > sizeof(int))
1684 len = sizeof(int);
1685 if (put_user_u32(len, optlen)
1686 || put_user_u32(val, optval_addr))
1687 return -TARGET_EFAULT;
1688 }
1689 break;
1690 default:
1691 ret = -TARGET_ENOPROTOOPT;
1692 break;
1693 }
1694 break;
1695 default:
1696 unimplemented:
1697 gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1698 level, optname);
1699 ret = -TARGET_EOPNOTSUPP;
1700 break;
1701 }
1702 return ret;
1703}
1704
1705
1706
1707
1708
1709static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1710 int count, int copy)
1711{
1712 struct target_iovec *target_vec;
1713 abi_ulong base;
1714 int i;
1715
1716 target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1717 if (!target_vec)
1718 return -TARGET_EFAULT;
1719 for(i = 0;i < count; i++) {
1720 base = tswapal(target_vec[i].iov_base);
1721 vec[i].iov_len = tswapal(target_vec[i].iov_len);
1722 if (vec[i].iov_len != 0) {
1723 vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
1724
1725
1726 } else {
1727
1728 vec[i].iov_base = NULL;
1729 }
1730 }
1731 unlock_user (target_vec, target_addr, 0);
1732 return 0;
1733}
1734
1735static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1736 int count, int copy)
1737{
1738 struct target_iovec *target_vec;
1739 abi_ulong base;
1740 int i;
1741
1742 target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1743 if (!target_vec)
1744 return -TARGET_EFAULT;
1745 for(i = 0;i < count; i++) {
1746 if (target_vec[i].iov_base) {
1747 base = tswapal(target_vec[i].iov_base);
1748 unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1749 }
1750 }
1751 unlock_user (target_vec, target_addr, 0);
1752
1753 return 0;
1754}
1755
1756
1757static abi_long do_socket(int domain, int type, int protocol)
1758{
1759#if defined(TARGET_MIPS)
1760 switch(type) {
1761 case TARGET_SOCK_DGRAM:
1762 type = SOCK_DGRAM;
1763 break;
1764 case TARGET_SOCK_STREAM:
1765 type = SOCK_STREAM;
1766 break;
1767 case TARGET_SOCK_RAW:
1768 type = SOCK_RAW;
1769 break;
1770 case TARGET_SOCK_RDM:
1771 type = SOCK_RDM;
1772 break;
1773 case TARGET_SOCK_SEQPACKET:
1774 type = SOCK_SEQPACKET;
1775 break;
1776 case TARGET_SOCK_PACKET:
1777 type = SOCK_PACKET;
1778 break;
1779 }
1780#endif
1781 if (domain == PF_NETLINK)
1782 return -EAFNOSUPPORT;
1783 return get_errno(socket(domain, type, protocol));
1784}
1785
1786
1787static abi_long do_bind(int sockfd, abi_ulong target_addr,
1788 socklen_t addrlen)
1789{
1790 void *addr;
1791 abi_long ret;
1792
1793 if ((int)addrlen < 0) {
1794 return -TARGET_EINVAL;
1795 }
1796
1797 addr = alloca(addrlen+1);
1798
1799 ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1800 if (ret)
1801 return ret;
1802
1803 return get_errno(bind(sockfd, addr, addrlen));
1804}
1805
1806
1807static abi_long do_connect(int sockfd, abi_ulong target_addr,
1808 socklen_t addrlen)
1809{
1810 void *addr;
1811 abi_long ret;
1812
1813 if ((int)addrlen < 0) {
1814 return -TARGET_EINVAL;
1815 }
1816
1817 addr = alloca(addrlen);
1818
1819 ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1820 if (ret)
1821 return ret;
1822
1823 return get_errno(connect(sockfd, addr, addrlen));
1824}
1825
1826
1827static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1828 int flags, int send)
1829{
1830 abi_long ret, len;
1831 struct target_msghdr *msgp;
1832 struct msghdr msg;
1833 int count;
1834 struct iovec *vec;
1835 abi_ulong target_vec;
1836
1837
1838 if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1839 msgp,
1840 target_msg,
1841 send ? 1 : 0))
1842 return -TARGET_EFAULT;
1843 if (msgp->msg_name) {
1844 msg.msg_namelen = tswap32(msgp->msg_namelen);
1845 msg.msg_name = alloca(msg.msg_namelen);
1846 ret = target_to_host_sockaddr(msg.msg_name, tswapal(msgp->msg_name),
1847 msg.msg_namelen);
1848 if (ret) {
1849 unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1850 return ret;
1851 }
1852 } else {
1853 msg.msg_name = NULL;
1854 msg.msg_namelen = 0;
1855 }
1856 msg.msg_controllen = 2 * tswapal(msgp->msg_controllen);
1857 msg.msg_control = alloca(msg.msg_controllen);
1858 msg.msg_flags = tswap32(msgp->msg_flags);
1859
1860 count = tswapal(msgp->msg_iovlen);
1861 vec = alloca(count * sizeof(struct iovec));
1862 target_vec = tswapal(msgp->msg_iov);
1863 lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1864 msg.msg_iovlen = count;
1865 msg.msg_iov = vec;
1866
1867 if (send) {
1868 ret = target_to_host_cmsg(&msg, msgp);
1869 if (ret == 0)
1870 ret = get_errno(sendmsg(fd, &msg, flags));
1871 } else {
1872 ret = get_errno(recvmsg(fd, &msg, flags));
1873 if (!is_error(ret)) {
1874 len = ret;
1875 ret = host_to_target_cmsg(msgp, &msg);
1876 if (!is_error(ret))
1877 ret = len;
1878 }
1879 }
1880 unlock_iovec(vec, target_vec, count, !send);
1881 unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1882 return ret;
1883}
1884
1885
1886static abi_long do_accept(int fd, abi_ulong target_addr,
1887 abi_ulong target_addrlen_addr)
1888{
1889 socklen_t addrlen;
1890 void *addr;
1891 abi_long ret;
1892
1893 if (target_addr == 0)
1894 return get_errno(accept(fd, NULL, NULL));
1895
1896
1897 if (get_user_u32(addrlen, target_addrlen_addr))
1898 return -TARGET_EINVAL;
1899
1900 if ((int)addrlen < 0) {
1901 return -TARGET_EINVAL;
1902 }
1903
1904 if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1905 return -TARGET_EINVAL;
1906
1907 addr = alloca(addrlen);
1908
1909 ret = get_errno(accept(fd, addr, &addrlen));
1910 if (!is_error(ret)) {
1911 host_to_target_sockaddr(target_addr, addr, addrlen);
1912 if (put_user_u32(addrlen, target_addrlen_addr))
1913 ret = -TARGET_EFAULT;
1914 }
1915 return ret;
1916}
1917
1918
1919static abi_long do_getpeername(int fd, abi_ulong target_addr,
1920 abi_ulong target_addrlen_addr)
1921{
1922 socklen_t addrlen;
1923 void *addr;
1924 abi_long ret;
1925
1926 if (get_user_u32(addrlen, target_addrlen_addr))
1927 return -TARGET_EFAULT;
1928
1929 if ((int)addrlen < 0) {
1930 return -TARGET_EINVAL;
1931 }
1932
1933 if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1934 return -TARGET_EFAULT;
1935
1936 addr = alloca(addrlen);
1937
1938 ret = get_errno(getpeername(fd, addr, &addrlen));
1939 if (!is_error(ret)) {
1940 host_to_target_sockaddr(target_addr, addr, addrlen);
1941 if (put_user_u32(addrlen, target_addrlen_addr))
1942 ret = -TARGET_EFAULT;
1943 }
1944 return ret;
1945}
1946
1947
1948static abi_long do_getsockname(int fd, abi_ulong target_addr,
1949 abi_ulong target_addrlen_addr)
1950{
1951 socklen_t addrlen;
1952 void *addr;
1953 abi_long ret;
1954
1955 if (get_user_u32(addrlen, target_addrlen_addr))
1956 return -TARGET_EFAULT;
1957
1958 if ((int)addrlen < 0) {
1959 return -TARGET_EINVAL;
1960 }
1961
1962 if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1963 return -TARGET_EFAULT;
1964
1965 addr = alloca(addrlen);
1966
1967 ret = get_errno(getsockname(fd, addr, &addrlen));
1968 if (!is_error(ret)) {
1969 host_to_target_sockaddr(target_addr, addr, addrlen);
1970 if (put_user_u32(addrlen, target_addrlen_addr))
1971 ret = -TARGET_EFAULT;
1972 }
1973 return ret;
1974}
1975
1976
1977static abi_long do_socketpair(int domain, int type, int protocol,
1978 abi_ulong target_tab_addr)
1979{
1980 int tab[2];
1981 abi_long ret;
1982
1983 ret = get_errno(socketpair(domain, type, protocol, tab));
1984 if (!is_error(ret)) {
1985 if (put_user_s32(tab[0], target_tab_addr)
1986 || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1987 ret = -TARGET_EFAULT;
1988 }
1989 return ret;
1990}
1991
1992
1993static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
1994 abi_ulong target_addr, socklen_t addrlen)
1995{
1996 void *addr;
1997 void *host_msg;
1998 abi_long ret;
1999
2000 if ((int)addrlen < 0) {
2001 return -TARGET_EINVAL;
2002 }
2003
2004 host_msg = lock_user(VERIFY_READ, msg, len, 1);
2005 if (!host_msg)
2006 return -TARGET_EFAULT;
2007 if (target_addr) {
2008 addr = alloca(addrlen);
2009 ret = target_to_host_sockaddr(addr, target_addr, addrlen);
2010 if (ret) {
2011 unlock_user(host_msg, msg, 0);
2012 return ret;
2013 }
2014 ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
2015 } else {
2016 ret = get_errno(send(fd, host_msg, len, flags));
2017 }
2018 unlock_user(host_msg, msg, 0);
2019 return ret;
2020}
2021
2022
2023static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
2024 abi_ulong target_addr,
2025 abi_ulong target_addrlen)
2026{
2027 socklen_t addrlen;
2028 void *addr;
2029 void *host_msg;
2030 abi_long ret;
2031
2032 host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
2033 if (!host_msg)
2034 return -TARGET_EFAULT;
2035 if (target_addr) {
2036 if (get_user_u32(addrlen, target_addrlen)) {
2037 ret = -TARGET_EFAULT;
2038 goto fail;
2039 }
2040 if ((int)addrlen < 0) {
2041 ret = -TARGET_EINVAL;
2042 goto fail;
2043 }
2044 addr = alloca(addrlen);
2045 ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
2046 } else {
2047 addr = NULL;
2048 ret = get_errno(qemu_recv(fd, host_msg, len, flags));
2049 }
2050 if (!is_error(ret)) {
2051 if (target_addr) {
2052 host_to_target_sockaddr(target_addr, addr, addrlen);
2053 if (put_user_u32(addrlen, target_addrlen)) {
2054 ret = -TARGET_EFAULT;
2055 goto fail;
2056 }
2057 }
2058 unlock_user(host_msg, msg, len);
2059 } else {
2060fail:
2061 unlock_user(host_msg, msg, 0);
2062 }
2063 return ret;
2064}
2065
2066#ifdef TARGET_NR_socketcall
2067
2068static abi_long do_socketcall(int num, abi_ulong vptr)
2069{
2070 abi_long ret;
2071 const int n = sizeof(abi_ulong);
2072
2073 switch(num) {
2074 case SOCKOP_socket:
2075 {
2076 abi_ulong domain, type, protocol;
2077
2078 if (get_user_ual(domain, vptr)
2079 || get_user_ual(type, vptr + n)
2080 || get_user_ual(protocol, vptr + 2 * n))
2081 return -TARGET_EFAULT;
2082
2083 ret = do_socket(domain, type, protocol);
2084 }
2085 break;
2086 case SOCKOP_bind:
2087 {
2088 abi_ulong sockfd;
2089 abi_ulong target_addr;
2090 socklen_t addrlen;
2091
2092 if (get_user_ual(sockfd, vptr)
2093 || get_user_ual(target_addr, vptr + n)
2094 || get_user_ual(addrlen, vptr + 2 * n))
2095 return -TARGET_EFAULT;
2096
2097 ret = do_bind(sockfd, target_addr, addrlen);
2098 }
2099 break;
2100 case SOCKOP_connect:
2101 {
2102 abi_ulong sockfd;
2103 abi_ulong target_addr;
2104 socklen_t addrlen;
2105
2106 if (get_user_ual(sockfd, vptr)
2107 || get_user_ual(target_addr, vptr + n)
2108 || get_user_ual(addrlen, vptr + 2 * n))
2109 return -TARGET_EFAULT;
2110
2111 ret = do_connect(sockfd, target_addr, addrlen);
2112 }
2113 break;
2114 case SOCKOP_listen:
2115 {
2116 abi_ulong sockfd, backlog;
2117
2118 if (get_user_ual(sockfd, vptr)
2119 || get_user_ual(backlog, vptr + n))
2120 return -TARGET_EFAULT;
2121
2122 ret = get_errno(listen(sockfd, backlog));
2123 }
2124 break;
2125 case SOCKOP_accept:
2126 {
2127 abi_ulong sockfd;
2128 abi_ulong target_addr, target_addrlen;
2129
2130 if (get_user_ual(sockfd, vptr)
2131 || get_user_ual(target_addr, vptr + n)
2132 || get_user_ual(target_addrlen, vptr + 2 * n))
2133 return -TARGET_EFAULT;
2134
2135 ret = do_accept(sockfd, target_addr, target_addrlen);
2136 }
2137 break;
2138 case SOCKOP_getsockname:
2139 {
2140 abi_ulong sockfd;
2141 abi_ulong target_addr, target_addrlen;
2142
2143 if (get_user_ual(sockfd, vptr)
2144 || get_user_ual(target_addr, vptr + n)
2145 || get_user_ual(target_addrlen, vptr + 2 * n))
2146 return -TARGET_EFAULT;
2147
2148 ret = do_getsockname(sockfd, target_addr, target_addrlen);
2149 }
2150 break;
2151 case SOCKOP_getpeername:
2152 {
2153 abi_ulong sockfd;
2154 abi_ulong target_addr, target_addrlen;
2155
2156 if (get_user_ual(sockfd, vptr)
2157 || get_user_ual(target_addr, vptr + n)
2158 || get_user_ual(target_addrlen, vptr + 2 * n))
2159 return -TARGET_EFAULT;
2160
2161 ret = do_getpeername(sockfd, target_addr, target_addrlen);
2162 }
2163 break;
2164 case SOCKOP_socketpair:
2165 {
2166 abi_ulong domain, type, protocol;
2167 abi_ulong tab;
2168
2169 if (get_user_ual(domain, vptr)
2170 || get_user_ual(type, vptr + n)
2171 || get_user_ual(protocol, vptr + 2 * n)
2172 || get_user_ual(tab, vptr + 3 * n))
2173 return -TARGET_EFAULT;
2174
2175 ret = do_socketpair(domain, type, protocol, tab);
2176 }
2177 break;
2178 case SOCKOP_send:
2179 {
2180 abi_ulong sockfd;
2181 abi_ulong msg;
2182 size_t len;
2183 abi_ulong flags;
2184
2185 if (get_user_ual(sockfd, vptr)
2186 || get_user_ual(msg, vptr + n)
2187 || get_user_ual(len, vptr + 2 * n)
2188 || get_user_ual(flags, vptr + 3 * n))
2189 return -TARGET_EFAULT;
2190
2191 ret = do_sendto(sockfd, msg, len, flags, 0, 0);
2192 }
2193 break;
2194 case SOCKOP_recv:
2195 {
2196 abi_ulong sockfd;
2197 abi_ulong msg;
2198 size_t len;
2199 abi_ulong flags;
2200
2201 if (get_user_ual(sockfd, vptr)
2202 || get_user_ual(msg, vptr + n)
2203 || get_user_ual(len, vptr + 2 * n)
2204 || get_user_ual(flags, vptr + 3 * n))
2205 return -TARGET_EFAULT;
2206
2207 ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
2208 }
2209 break;
2210 case SOCKOP_sendto:
2211 {
2212 abi_ulong sockfd;
2213 abi_ulong msg;
2214 size_t len;
2215 abi_ulong flags;
2216 abi_ulong addr;
2217 socklen_t addrlen;
2218
2219 if (get_user_ual(sockfd, vptr)
2220 || get_user_ual(msg, vptr + n)
2221 || get_user_ual(len, vptr + 2 * n)
2222 || get_user_ual(flags, vptr + 3 * n)
2223 || get_user_ual(addr, vptr + 4 * n)
2224 || get_user_ual(addrlen, vptr + 5 * n))
2225 return -TARGET_EFAULT;
2226
2227 ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
2228 }
2229 break;
2230 case SOCKOP_recvfrom:
2231 {
2232 abi_ulong sockfd;
2233 abi_ulong msg;
2234 size_t len;
2235 abi_ulong flags;
2236 abi_ulong addr;
2237 socklen_t addrlen;
2238
2239 if (get_user_ual(sockfd, vptr)
2240 || get_user_ual(msg, vptr + n)
2241 || get_user_ual(len, vptr + 2 * n)
2242 || get_user_ual(flags, vptr + 3 * n)
2243 || get_user_ual(addr, vptr + 4 * n)
2244 || get_user_ual(addrlen, vptr + 5 * n))
2245 return -TARGET_EFAULT;
2246
2247 ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
2248 }
2249 break;
2250 case SOCKOP_shutdown:
2251 {
2252 abi_ulong sockfd, how;
2253
2254 if (get_user_ual(sockfd, vptr)
2255 || get_user_ual(how, vptr + n))
2256 return -TARGET_EFAULT;
2257
2258 ret = get_errno(shutdown(sockfd, how));
2259 }
2260 break;
2261 case SOCKOP_sendmsg:
2262 case SOCKOP_recvmsg:
2263 {
2264 abi_ulong fd;
2265 abi_ulong target_msg;
2266 abi_ulong flags;
2267
2268 if (get_user_ual(fd, vptr)
2269 || get_user_ual(target_msg, vptr + n)
2270 || get_user_ual(flags, vptr + 2 * n))
2271 return -TARGET_EFAULT;
2272
2273 ret = do_sendrecvmsg(fd, target_msg, flags,
2274 (num == SOCKOP_sendmsg));
2275 }
2276 break;
2277 case SOCKOP_setsockopt:
2278 {
2279 abi_ulong sockfd;
2280 abi_ulong level;
2281 abi_ulong optname;
2282 abi_ulong optval;
2283 socklen_t optlen;
2284
2285 if (get_user_ual(sockfd, vptr)
2286 || get_user_ual(level, vptr + n)
2287 || get_user_ual(optname, vptr + 2 * n)
2288 || get_user_ual(optval, vptr + 3 * n)
2289 || get_user_ual(optlen, vptr + 4 * n))
2290 return -TARGET_EFAULT;
2291
2292 ret = do_setsockopt(sockfd, level, optname, optval, optlen);
2293 }
2294 break;
2295 case SOCKOP_getsockopt:
2296 {
2297 abi_ulong sockfd;
2298 abi_ulong level;
2299 abi_ulong optname;
2300 abi_ulong optval;
2301 socklen_t optlen;
2302
2303 if (get_user_ual(sockfd, vptr)
2304 || get_user_ual(level, vptr + n)
2305 || get_user_ual(optname, vptr + 2 * n)
2306 || get_user_ual(optval, vptr + 3 * n)
2307 || get_user_ual(optlen, vptr + 4 * n))
2308 return -TARGET_EFAULT;
2309
2310 ret = do_getsockopt(sockfd, level, optname, optval, optlen);
2311 }
2312 break;
2313 default:
2314 gemu_log("Unsupported socketcall: %d\n", num);
2315 ret = -TARGET_ENOSYS;
2316 break;
2317 }
2318 return ret;
2319}
2320#endif
2321
2322#define N_SHM_REGIONS 32
2323
2324static struct shm_region {
2325 abi_ulong start;
2326 abi_ulong size;
2327} shm_regions[N_SHM_REGIONS];
2328
2329struct target_ipc_perm
2330{
2331 abi_long __key;
2332 abi_ulong uid;
2333 abi_ulong gid;
2334 abi_ulong cuid;
2335 abi_ulong cgid;
2336 unsigned short int mode;
2337 unsigned short int __pad1;
2338 unsigned short int __seq;
2339 unsigned short int __pad2;
2340 abi_ulong __unused1;
2341 abi_ulong __unused2;
2342};
2343
2344struct target_semid_ds
2345{
2346 struct target_ipc_perm sem_perm;
2347 abi_ulong sem_otime;
2348 abi_ulong __unused1;
2349 abi_ulong sem_ctime;
2350 abi_ulong __unused2;
2351 abi_ulong sem_nsems;
2352 abi_ulong __unused3;
2353 abi_ulong __unused4;
2354};
2355
2356static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
2357 abi_ulong target_addr)
2358{
2359 struct target_ipc_perm *target_ip;
2360 struct target_semid_ds *target_sd;
2361
2362 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2363 return -TARGET_EFAULT;
2364 target_ip = &(target_sd->sem_perm);
2365 host_ip->__key = tswapal(target_ip->__key);
2366 host_ip->uid = tswapal(target_ip->uid);
2367 host_ip->gid = tswapal(target_ip->gid);
2368 host_ip->cuid = tswapal(target_ip->cuid);
2369 host_ip->cgid = tswapal(target_ip->cgid);
2370 host_ip->mode = tswap16(target_ip->mode);
2371 unlock_user_struct(target_sd, target_addr, 0);
2372 return 0;
2373}
2374
2375static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
2376 struct ipc_perm *host_ip)
2377{
2378 struct target_ipc_perm *target_ip;
2379 struct target_semid_ds *target_sd;
2380
2381 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2382 return -TARGET_EFAULT;
2383 target_ip = &(target_sd->sem_perm);
2384 target_ip->__key = tswapal(host_ip->__key);
2385 target_ip->uid = tswapal(host_ip->uid);
2386 target_ip->gid = tswapal(host_ip->gid);
2387 target_ip->cuid = tswapal(host_ip->cuid);
2388 target_ip->cgid = tswapal(host_ip->cgid);
2389 target_ip->mode = tswap16(host_ip->mode);
2390 unlock_user_struct(target_sd, target_addr, 1);
2391 return 0;
2392}
2393
2394static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
2395 abi_ulong target_addr)
2396{
2397 struct target_semid_ds *target_sd;
2398
2399 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2400 return -TARGET_EFAULT;
2401 if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr))
2402 return -TARGET_EFAULT;
2403 host_sd->sem_nsems = tswapal(target_sd->sem_nsems);
2404 host_sd->sem_otime = tswapal(target_sd->sem_otime);
2405 host_sd->sem_ctime = tswapal(target_sd->sem_ctime);
2406 unlock_user_struct(target_sd, target_addr, 0);
2407 return 0;
2408}
2409
2410static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
2411 struct semid_ds *host_sd)
2412{
2413 struct target_semid_ds *target_sd;
2414
2415 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2416 return -TARGET_EFAULT;
2417 if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
2418 return -TARGET_EFAULT;
2419 target_sd->sem_nsems = tswapal(host_sd->sem_nsems);
2420 target_sd->sem_otime = tswapal(host_sd->sem_otime);
2421 target_sd->sem_ctime = tswapal(host_sd->sem_ctime);
2422 unlock_user_struct(target_sd, target_addr, 1);
2423 return 0;
2424}
2425
2426struct target_seminfo {
2427 int semmap;
2428 int semmni;
2429 int semmns;
2430 int semmnu;
2431 int semmsl;
2432 int semopm;
2433 int semume;
2434 int semusz;
2435 int semvmx;
2436 int semaem;
2437};
2438
2439static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
2440 struct seminfo *host_seminfo)
2441{
2442 struct target_seminfo *target_seminfo;
2443 if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
2444 return -TARGET_EFAULT;
2445 __put_user(host_seminfo->semmap, &target_seminfo->semmap);
2446 __put_user(host_seminfo->semmni, &target_seminfo->semmni);
2447 __put_user(host_seminfo->semmns, &target_seminfo->semmns);
2448 __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
2449 __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
2450 __put_user(host_seminfo->semopm, &target_seminfo->semopm);
2451 __put_user(host_seminfo->semume, &target_seminfo->semume);
2452 __put_user(host_seminfo->semusz, &target_seminfo->semusz);
2453 __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
2454 __put_user(host_seminfo->semaem, &target_seminfo->semaem);
2455 unlock_user_struct(target_seminfo, target_addr, 1);
2456 return 0;
2457}
2458
2459union semun {
2460 int val;
2461 struct semid_ds *buf;
2462 unsigned short *array;
2463 struct seminfo *__buf;
2464};
2465
2466union target_semun {
2467 int val;
2468 abi_ulong buf;
2469 abi_ulong array;
2470 abi_ulong __buf;
2471};
2472
2473static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
2474 abi_ulong target_addr)
2475{
2476 int nsems;
2477 unsigned short *array;
2478 union semun semun;
2479 struct semid_ds semid_ds;
2480 int i, ret;
2481
2482 semun.buf = &semid_ds;
2483
2484 ret = semctl(semid, 0, IPC_STAT, semun);
2485 if (ret == -1)
2486 return get_errno(ret);
2487
2488 nsems = semid_ds.sem_nsems;
2489
2490 *host_array = malloc(nsems*sizeof(unsigned short));
2491 array = lock_user(VERIFY_READ, target_addr,
2492 nsems*sizeof(unsigned short), 1);
2493 if (!array)
2494 return -TARGET_EFAULT;
2495
2496 for(i=0; i<nsems; i++) {
2497 __get_user((*host_array)[i], &array[i]);
2498 }
2499 unlock_user(array, target_addr, 0);
2500
2501 return 0;
2502}
2503
2504static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
2505 unsigned short **host_array)
2506{
2507 int nsems;
2508 unsigned short *array;
2509 union semun semun;
2510 struct semid_ds semid_ds;
2511 int i, ret;
2512
2513 semun.buf = &semid_ds;
2514
2515 ret = semctl(semid, 0, IPC_STAT, semun);
2516 if (ret == -1)
2517 return get_errno(ret);
2518
2519 nsems = semid_ds.sem_nsems;
2520
2521 array = lock_user(VERIFY_WRITE, target_addr,
2522 nsems*sizeof(unsigned short), 0);
2523 if (!array)
2524 return -TARGET_EFAULT;
2525
2526 for(i=0; i<nsems; i++) {
2527 __put_user((*host_array)[i], &array[i]);
2528 }
2529 free(*host_array);
2530 unlock_user(array, target_addr, 1);
2531
2532 return 0;
2533}
2534
2535static inline abi_long do_semctl(int semid, int semnum, int cmd,
2536 union target_semun target_su)
2537{
2538 union semun arg;
2539 struct semid_ds dsarg;
2540 unsigned short *array = NULL;
2541 struct seminfo seminfo;
2542 abi_long ret = -TARGET_EINVAL;
2543 abi_long err;
2544 cmd &= 0xff;
2545
2546 switch( cmd ) {
2547 case GETVAL:
2548 case SETVAL:
2549 arg.val = tswap32(target_su.val);
2550 ret = get_errno(semctl(semid, semnum, cmd, arg));
2551 target_su.val = tswap32(arg.val);
2552 break;
2553 case GETALL:
2554 case SETALL:
2555 err = target_to_host_semarray(semid, &array, target_su.array);
2556 if (err)
2557 return err;
2558 arg.array = array;
2559 ret = get_errno(semctl(semid, semnum, cmd, arg));
2560 err = host_to_target_semarray(semid, target_su.array, &array);
2561 if (err)
2562 return err;
2563 break;
2564 case IPC_STAT:
2565 case IPC_SET:
2566 case SEM_STAT:
2567 err = target_to_host_semid_ds(&dsarg, target_su.buf);
2568 if (err)
2569 return err;
2570 arg.buf = &dsarg;
2571 ret = get_errno(semctl(semid, semnum, cmd, arg));
2572 err = host_to_target_semid_ds(target_su.buf, &dsarg);
2573 if (err)
2574 return err;
2575 break;
2576 case IPC_INFO:
2577 case SEM_INFO:
2578 arg.__buf = &seminfo;
2579 ret = get_errno(semctl(semid, semnum, cmd, arg));
2580 err = host_to_target_seminfo(target_su.__buf, &seminfo);
2581 if (err)
2582 return err;
2583 break;
2584 case IPC_RMID:
2585 case GETPID:
2586 case GETNCNT:
2587 case GETZCNT:
2588 ret = get_errno(semctl(semid, semnum, cmd, NULL));
2589 break;
2590 }
2591
2592 return ret;
2593}
2594
2595struct target_sembuf {
2596 unsigned short sem_num;
2597 short sem_op;
2598 short sem_flg;
2599};
2600
2601static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
2602 abi_ulong target_addr,
2603 unsigned nsops)
2604{
2605 struct target_sembuf *target_sembuf;
2606 int i;
2607
2608 target_sembuf = lock_user(VERIFY_READ, target_addr,
2609 nsops*sizeof(struct target_sembuf), 1);
2610 if (!target_sembuf)
2611 return -TARGET_EFAULT;
2612
2613 for(i=0; i<nsops; i++) {
2614 __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
2615 __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
2616 __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
2617 }
2618
2619 unlock_user(target_sembuf, target_addr, 0);
2620
2621 return 0;
2622}
2623
2624static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
2625{
2626 struct sembuf sops[nsops];
2627
2628 if (target_to_host_sembuf(sops, ptr, nsops))
2629 return -TARGET_EFAULT;
2630
2631 return semop(semid, sops, nsops);
2632}
2633
2634struct target_msqid_ds
2635{
2636 struct target_ipc_perm msg_perm;
2637 abi_ulong msg_stime;
2638#if TARGET_ABI_BITS == 32
2639 abi_ulong __unused1;
2640#endif
2641 abi_ulong msg_rtime;
2642#if TARGET_ABI_BITS == 32
2643 abi_ulong __unused2;
2644#endif
2645 abi_ulong msg_ctime;
2646#if TARGET_ABI_BITS == 32
2647 abi_ulong __unused3;
2648#endif
2649 abi_ulong __msg_cbytes;
2650 abi_ulong msg_qnum;
2651 abi_ulong msg_qbytes;
2652 abi_ulong msg_lspid;
2653 abi_ulong msg_lrpid;
2654 abi_ulong __unused4;
2655 abi_ulong __unused5;
2656};
2657
2658static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
2659 abi_ulong target_addr)
2660{
2661 struct target_msqid_ds *target_md;
2662
2663 if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
2664 return -TARGET_EFAULT;
2665 if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
2666 return -TARGET_EFAULT;
2667 host_md->msg_stime = tswapal(target_md->msg_stime);
2668 host_md->msg_rtime = tswapal(target_md->msg_rtime);
2669 host_md->msg_ctime = tswapal(target_md->msg_ctime);
2670 host_md->__msg_cbytes = tswapal(target_md->__msg_cbytes);
2671 host_md->msg_qnum = tswapal(target_md->msg_qnum);
2672 host_md->msg_qbytes = tswapal(target_md->msg_qbytes);
2673 host_md->msg_lspid = tswapal(target_md->msg_lspid);
2674 host_md->msg_lrpid = tswapal(target_md->msg_lrpid);
2675 unlock_user_struct(target_md, target_addr, 0);
2676 return 0;
2677}
2678
2679static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
2680 struct msqid_ds *host_md)
2681{
2682 struct target_msqid_ds *target_md;
2683
2684 if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
2685 return -TARGET_EFAULT;
2686 if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
2687 return -TARGET_EFAULT;
2688 target_md->msg_stime = tswapal(host_md->msg_stime);
2689 target_md->msg_rtime = tswapal(host_md->msg_rtime);
2690 target_md->msg_ctime = tswapal(host_md->msg_ctime);
2691 target_md->__msg_cbytes = tswapal(host_md->__msg_cbytes);
2692 target_md->msg_qnum = tswapal(host_md->msg_qnum);
2693 target_md->msg_qbytes = tswapal(host_md->msg_qbytes);
2694 target_md->msg_lspid = tswapal(host_md->msg_lspid);
2695 target_md->msg_lrpid = tswapal(host_md->msg_lrpid);
2696 unlock_user_struct(target_md, target_addr, 1);
2697 return 0;
2698}
2699
2700struct target_msginfo {
2701 int msgpool;
2702 int msgmap;
2703 int msgmax;
2704 int msgmnb;
2705 int msgmni;
2706 int msgssz;
2707 int msgtql;
2708 unsigned short int msgseg;
2709};
2710
2711static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
2712 struct msginfo *host_msginfo)
2713{
2714 struct target_msginfo *target_msginfo;
2715 if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
2716 return -TARGET_EFAULT;
2717 __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
2718 __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
2719 __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
2720 __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
2721 __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
2722 __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
2723 __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
2724 __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
2725 unlock_user_struct(target_msginfo, target_addr, 1);
2726 return 0;
2727}
2728
2729static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
2730{
2731 struct msqid_ds dsarg;
2732 struct msginfo msginfo;
2733 abi_long ret = -TARGET_EINVAL;
2734
2735 cmd &= 0xff;
2736
2737 switch (cmd) {
2738 case IPC_STAT:
2739 case IPC_SET:
2740 case MSG_STAT:
2741 if (target_to_host_msqid_ds(&dsarg,ptr))
2742 return -TARGET_EFAULT;
2743 ret = get_errno(msgctl(msgid, cmd, &dsarg));
2744 if (host_to_target_msqid_ds(ptr,&dsarg))
2745 return -TARGET_EFAULT;
2746 break;
2747 case IPC_RMID:
2748 ret = get_errno(msgctl(msgid, cmd, NULL));
2749 break;
2750 case IPC_INFO:
2751 case MSG_INFO:
2752 ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
2753 if (host_to_target_msginfo(ptr, &msginfo))
2754 return -TARGET_EFAULT;
2755 break;
2756 }
2757
2758 return ret;
2759}
2760
2761struct target_msgbuf {
2762 abi_long mtype;
2763 char mtext[1];
2764};
2765
2766static inline abi_long do_msgsnd(int msqid, abi_long msgp,
2767 unsigned int msgsz, int msgflg)
2768{
2769 struct target_msgbuf *target_mb;
2770 struct msgbuf *host_mb;
2771 abi_long ret = 0;
2772
2773 if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
2774 return -TARGET_EFAULT;
2775 host_mb = malloc(msgsz+sizeof(long));
2776 host_mb->mtype = (abi_long) tswapal(target_mb->mtype);
2777 memcpy(host_mb->mtext, target_mb->mtext, msgsz);
2778 ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
2779 free(host_mb);
2780 unlock_user_struct(target_mb, msgp, 0);
2781
2782 return ret;
2783}
2784
2785static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2786 unsigned int msgsz, abi_long msgtyp,
2787 int msgflg)
2788{
2789 struct target_msgbuf *target_mb;
2790 char *target_mtext;
2791 struct msgbuf *host_mb;
2792 abi_long ret = 0;
2793
2794 if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2795 return -TARGET_EFAULT;
2796
2797 host_mb = malloc(msgsz+sizeof(long));
2798 ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapal(msgtyp), msgflg));
2799
2800 if (ret > 0) {
2801 abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2802 target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2803 if (!target_mtext) {
2804 ret = -TARGET_EFAULT;
2805 goto end;
2806 }
2807 memcpy(target_mb->mtext, host_mb->mtext, ret);
2808 unlock_user(target_mtext, target_mtext_addr, ret);
2809 }
2810
2811 target_mb->mtype = tswapal(host_mb->mtype);
2812 free(host_mb);
2813
2814end:
2815 if (target_mb)
2816 unlock_user_struct(target_mb, msgp, 1);
2817 return ret;
2818}
2819
2820struct target_shmid_ds
2821{
2822 struct target_ipc_perm shm_perm;
2823 abi_ulong shm_segsz;
2824 abi_ulong shm_atime;
2825#if TARGET_ABI_BITS == 32
2826 abi_ulong __unused1;
2827#endif
2828 abi_ulong shm_dtime;
2829#if TARGET_ABI_BITS == 32
2830 abi_ulong __unused2;
2831#endif
2832 abi_ulong shm_ctime;
2833#if TARGET_ABI_BITS == 32
2834 abi_ulong __unused3;
2835#endif
2836 int shm_cpid;
2837 int shm_lpid;
2838 abi_ulong shm_nattch;
2839 unsigned long int __unused4;
2840 unsigned long int __unused5;
2841};
2842
2843static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
2844 abi_ulong target_addr)
2845{
2846 struct target_shmid_ds *target_sd;
2847
2848 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2849 return -TARGET_EFAULT;
2850 if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr))
2851 return -TARGET_EFAULT;
2852 __get_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2853 __get_user(host_sd->shm_atime, &target_sd->shm_atime);
2854 __get_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2855 __get_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2856 __get_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2857 __get_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2858 __get_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2859 unlock_user_struct(target_sd, target_addr, 0);
2860 return 0;
2861}
2862
2863static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
2864 struct shmid_ds *host_sd)
2865{
2866 struct target_shmid_ds *target_sd;
2867
2868 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2869 return -TARGET_EFAULT;
2870 if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm)))
2871 return -TARGET_EFAULT;
2872 __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2873 __put_user(host_sd->shm_atime, &target_sd->shm_atime);
2874 __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2875 __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2876 __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2877 __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2878 __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2879 unlock_user_struct(target_sd, target_addr, 1);
2880 return 0;
2881}
2882
2883struct target_shminfo {
2884 abi_ulong shmmax;
2885 abi_ulong shmmin;
2886 abi_ulong shmmni;
2887 abi_ulong shmseg;
2888 abi_ulong shmall;
2889};
2890
2891static inline abi_long host_to_target_shminfo(abi_ulong target_addr,
2892 struct shminfo *host_shminfo)
2893{
2894 struct target_shminfo *target_shminfo;
2895 if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0))
2896 return -TARGET_EFAULT;
2897 __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
2898 __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
2899 __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
2900 __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
2901 __put_user(host_shminfo->shmall, &target_shminfo->shmall);
2902 unlock_user_struct(target_shminfo, target_addr, 1);
2903 return 0;
2904}
2905
2906struct target_shm_info {
2907 int used_ids;
2908 abi_ulong shm_tot;
2909 abi_ulong shm_rss;
2910 abi_ulong shm_swp;
2911 abi_ulong swap_attempts;
2912 abi_ulong swap_successes;
2913};
2914
2915static inline abi_long host_to_target_shm_info(abi_ulong target_addr,
2916 struct shm_info *host_shm_info)
2917{
2918 struct target_shm_info *target_shm_info;
2919 if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0))
2920 return -TARGET_EFAULT;
2921 __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
2922 __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
2923 __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
2924 __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
2925 __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts);
2926 __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes);
2927 unlock_user_struct(target_shm_info, target_addr, 1);
2928 return 0;
2929}
2930
2931static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
2932{
2933 struct shmid_ds dsarg;
2934 struct shminfo shminfo;
2935 struct shm_info shm_info;
2936 abi_long ret = -TARGET_EINVAL;
2937
2938 cmd &= 0xff;
2939
2940 switch(cmd) {
2941 case IPC_STAT:
2942 case IPC_SET:
2943 case SHM_STAT:
2944 if (target_to_host_shmid_ds(&dsarg, buf))
2945 return -TARGET_EFAULT;
2946 ret = get_errno(shmctl(shmid, cmd, &dsarg));
2947 if (host_to_target_shmid_ds(buf, &dsarg))
2948 return -TARGET_EFAULT;
2949 break;
2950 case IPC_INFO:
2951 ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
2952 if (host_to_target_shminfo(buf, &shminfo))
2953 return -TARGET_EFAULT;
2954 break;
2955 case SHM_INFO:
2956 ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
2957 if (host_to_target_shm_info(buf, &shm_info))
2958 return -TARGET_EFAULT;
2959 break;
2960 case IPC_RMID:
2961 case SHM_LOCK:
2962 case SHM_UNLOCK:
2963 ret = get_errno(shmctl(shmid, cmd, NULL));
2964 break;
2965 }
2966
2967 return ret;
2968}
2969
2970static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
2971{
2972 abi_long raddr;
2973 void *host_raddr;
2974 struct shmid_ds shm_info;
2975 int i,ret;
2976
2977
2978 ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
2979 if (is_error(ret)) {
2980
2981 return ret;
2982 }
2983
2984 mmap_lock();
2985
2986 if (shmaddr)
2987 host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
2988 else {
2989 abi_ulong mmap_start;
2990
2991 mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
2992
2993 if (mmap_start == -1) {
2994 errno = ENOMEM;
2995 host_raddr = (void *)-1;
2996 } else
2997 host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);
2998 }
2999
3000 if (host_raddr == (void *)-1) {
3001 mmap_unlock();
3002 return get_errno((long)host_raddr);
3003 }
3004 raddr=h2g((unsigned long)host_raddr);
3005
3006 page_set_flags(raddr, raddr + shm_info.shm_segsz,
3007 PAGE_VALID | PAGE_READ |
3008 ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
3009
3010 for (i = 0; i < N_SHM_REGIONS; i++) {
3011 if (shm_regions[i].start == 0) {
3012 shm_regions[i].start = raddr;
3013 shm_regions[i].size = shm_info.shm_segsz;
3014 break;
3015 }
3016 }
3017
3018 mmap_unlock();
3019 return raddr;
3020
3021}
3022
3023static inline abi_long do_shmdt(abi_ulong shmaddr)
3024{
3025 int i;
3026
3027 for (i = 0; i < N_SHM_REGIONS; ++i) {
3028 if (shm_regions[i].start == shmaddr) {
3029 shm_regions[i].start = 0;
3030 page_set_flags(shmaddr, shmaddr + shm_regions[i].size, 0);
3031 break;
3032 }
3033 }
3034
3035 return get_errno(shmdt(g2h(shmaddr)));
3036}
3037
3038#ifdef TARGET_NR_ipc
3039
3040
3041static abi_long do_ipc(unsigned int call, int first,
3042 int second, int third,
3043 abi_long ptr, abi_long fifth)
3044{
3045 int version;
3046 abi_long ret = 0;
3047
3048 version = call >> 16;
3049 call &= 0xffff;
3050
3051 switch (call) {
3052 case IPCOP_semop:
3053 ret = do_semop(first, ptr, second);
3054 break;
3055
3056 case IPCOP_semget:
3057 ret = get_errno(semget(first, second, third));
3058 break;
3059
3060 case IPCOP_semctl:
3061 ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr);
3062 break;
3063
3064 case IPCOP_msgget:
3065 ret = get_errno(msgget(first, second));
3066 break;
3067
3068 case IPCOP_msgsnd:
3069 ret = do_msgsnd(first, ptr, second, third);
3070 break;
3071
3072 case IPCOP_msgctl:
3073 ret = do_msgctl(first, second, ptr);
3074 break;
3075
3076 case IPCOP_msgrcv:
3077 switch (version) {
3078 case 0:
3079 {
3080 struct target_ipc_kludge {
3081 abi_long msgp;
3082 abi_long msgtyp;
3083 } *tmp;
3084
3085 if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
3086 ret = -TARGET_EFAULT;
3087 break;
3088 }
3089
3090 ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
3091
3092 unlock_user_struct(tmp, ptr, 0);
3093 break;
3094 }
3095 default:
3096 ret = do_msgrcv(first, ptr, second, fifth, third);
3097 }
3098 break;
3099
3100 case IPCOP_shmat:
3101 switch (version) {
3102 default:
3103 {
3104 abi_ulong raddr;
3105 raddr = do_shmat(first, ptr, second);
3106 if (is_error(raddr))
3107 return get_errno(raddr);
3108 if (put_user_ual(raddr, third))
3109 return -TARGET_EFAULT;
3110 break;
3111 }
3112 case 1:
3113 ret = -TARGET_EINVAL;
3114 break;
3115 }
3116 break;
3117 case IPCOP_shmdt:
3118 ret = do_shmdt(ptr);
3119 break;
3120
3121 case IPCOP_shmget:
3122
3123 ret = get_errno(shmget(first, second, third));
3124 break;
3125
3126
3127 case IPCOP_shmctl:
3128 ret = do_shmctl(first, second, third);
3129 break;
3130 default:
3131 gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
3132 ret = -TARGET_ENOSYS;
3133 break;
3134 }
3135 return ret;
3136}
3137#endif
3138
3139
3140
3141#define STRUCT(name, ...) STRUCT_ ## name,
3142#define STRUCT_SPECIAL(name) STRUCT_ ## name,
3143enum {
3144#include "syscall_types.h"
3145};
3146#undef STRUCT
3147#undef STRUCT_SPECIAL
3148
3149#define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = { __VA_ARGS__, TYPE_NULL };
3150#define STRUCT_SPECIAL(name)
3151#include "syscall_types.h"
3152#undef STRUCT
3153#undef STRUCT_SPECIAL
3154
3155typedef struct IOCTLEntry IOCTLEntry;
3156
3157typedef abi_long do_ioctl_fn(const IOCTLEntry *ie, uint8_t *buf_temp,
3158 int fd, abi_long cmd, abi_long arg);
3159
3160struct IOCTLEntry {
3161 unsigned int target_cmd;
3162 unsigned int host_cmd;
3163 const char *name;
3164 int access;
3165 do_ioctl_fn *do_ioctl;
3166 const argtype arg_type[5];
3167};
3168
3169#define IOC_R 0x0001
3170#define IOC_W 0x0002
3171#define IOC_RW (IOC_R | IOC_W)
3172
3173#define MAX_STRUCT_SIZE 4096
3174
3175#ifdef CONFIG_FIEMAP
3176
3177
3178
3179
3180#define FIEMAP_MAX_EXTENTS ((UINT_MAX - sizeof(struct fiemap)) \
3181 / sizeof(struct fiemap_extent))
3182
3183static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp,
3184 int fd, abi_long cmd, abi_long arg)
3185{
3186
3187
3188
3189
3190
3191 int target_size_in, target_size_out;
3192 struct fiemap *fm;
3193 const argtype *arg_type = ie->arg_type;
3194 const argtype extent_arg_type[] = { MK_STRUCT(STRUCT_fiemap_extent) };
3195 void *argptr, *p;
3196 abi_long ret;
3197 int i, extent_size = thunk_type_size(extent_arg_type, 0);
3198 uint32_t outbufsz;
3199 int free_fm = 0;
3200
3201 assert(arg_type[0] == TYPE_PTR);
3202 assert(ie->access == IOC_RW);
3203 arg_type++;
3204 target_size_in = thunk_type_size(arg_type, 0);
3205 argptr = lock_user(VERIFY_READ, arg, target_size_in, 1);
3206 if (!argptr) {
3207 return -TARGET_EFAULT;
3208 }
3209 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3210 unlock_user(argptr, arg, 0);
3211 fm = (struct fiemap *)buf_temp;
3212 if (fm->fm_extent_count > FIEMAP_MAX_EXTENTS) {
3213 return -TARGET_EINVAL;
3214 }
3215
3216 outbufsz = sizeof (*fm) +
3217 (sizeof(struct fiemap_extent) * fm->fm_extent_count);
3218
3219 if (outbufsz > MAX_STRUCT_SIZE) {
3220
3221
3222
3223 fm = malloc(outbufsz);
3224 if (!fm) {
3225 return -TARGET_ENOMEM;
3226 }
3227 memcpy(fm, buf_temp, sizeof(struct fiemap));
3228 free_fm = 1;
3229 }
3230 ret = get_errno(ioctl(fd, ie->host_cmd, fm));
3231 if (!is_error(ret)) {
3232 target_size_out = target_size_in;
3233
3234
3235
3236 if (fm->fm_extent_count != 0) {
3237 target_size_out += fm->fm_mapped_extents * extent_size;
3238 }
3239 argptr = lock_user(VERIFY_WRITE, arg, target_size_out, 0);
3240 if (!argptr) {
3241 ret = -TARGET_EFAULT;
3242 } else {
3243
3244 thunk_convert(argptr, fm, arg_type, THUNK_TARGET);
3245 if (fm->fm_extent_count != 0) {
3246 p = argptr + target_size_in;
3247
3248 for (i = 0; i < fm->fm_mapped_extents; i++) {
3249 thunk_convert(p, &fm->fm_extents[i], extent_arg_type,
3250 THUNK_TARGET);
3251 p += extent_size;
3252 }
3253 }
3254 unlock_user(argptr, arg, target_size_out);
3255 }
3256 }
3257 if (free_fm) {
3258 free(fm);
3259 }
3260 return ret;
3261}
3262#endif
3263
3264static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp,
3265 int fd, abi_long cmd, abi_long arg)
3266{
3267 const argtype *arg_type = ie->arg_type;
3268 int target_size;
3269 void *argptr;
3270 int ret;
3271 struct ifconf *host_ifconf;
3272 uint32_t outbufsz;
3273 const argtype ifreq_arg_type[] = { MK_STRUCT(STRUCT_sockaddr_ifreq) };
3274 int target_ifreq_size;
3275 int nb_ifreq;
3276 int free_buf = 0;
3277 int i;
3278 int target_ifc_len;
3279 abi_long target_ifc_buf;
3280 int host_ifc_len;
3281 char *host_ifc_buf;
3282
3283 assert(arg_type[0] == TYPE_PTR);
3284 assert(ie->access == IOC_RW);
3285
3286 arg_type++;
3287 target_size = thunk_type_size(arg_type, 0);
3288
3289 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3290 if (!argptr)
3291 return -TARGET_EFAULT;
3292 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3293 unlock_user(argptr, arg, 0);
3294
3295 host_ifconf = (struct ifconf *)(unsigned long)buf_temp;
3296 target_ifc_len = host_ifconf->ifc_len;
3297 target_ifc_buf = (abi_long)(unsigned long)host_ifconf->ifc_buf;
3298
3299 target_ifreq_size = thunk_type_size(ifreq_arg_type, 0);
3300 nb_ifreq = target_ifc_len / target_ifreq_size;
3301 host_ifc_len = nb_ifreq * sizeof(struct ifreq);
3302
3303 outbufsz = sizeof(*host_ifconf) + host_ifc_len;
3304 if (outbufsz > MAX_STRUCT_SIZE) {
3305
3306
3307
3308 host_ifconf = malloc(outbufsz);
3309 if (!host_ifconf) {
3310 return -TARGET_ENOMEM;
3311 }
3312 memcpy(host_ifconf, buf_temp, sizeof(*host_ifconf));
3313 free_buf = 1;
3314 }
3315 host_ifc_buf = (char*)host_ifconf + sizeof(*host_ifconf);
3316
3317 host_ifconf->ifc_len = host_ifc_len;
3318 host_ifconf->ifc_buf = host_ifc_buf;
3319
3320 ret = get_errno(ioctl(fd, ie->host_cmd, host_ifconf));
3321 if (!is_error(ret)) {
3322
3323
3324 nb_ifreq = host_ifconf->ifc_len / sizeof(struct ifreq);
3325 target_ifc_len = nb_ifreq * target_ifreq_size;
3326 host_ifconf->ifc_len = target_ifc_len;
3327
3328
3329
3330 host_ifconf->ifc_buf = (char *)(unsigned long)target_ifc_buf;
3331
3332
3333
3334 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3335 if (!argptr)
3336 return -TARGET_EFAULT;
3337 thunk_convert(argptr, host_ifconf, arg_type, THUNK_TARGET);
3338 unlock_user(argptr, arg, target_size);
3339
3340
3341
3342 argptr = lock_user(VERIFY_WRITE, target_ifc_buf, target_ifc_len, 0);
3343 for (i = 0; i < nb_ifreq ; i++) {
3344 thunk_convert(argptr + i * target_ifreq_size,
3345 host_ifc_buf + i * sizeof(struct ifreq),
3346 ifreq_arg_type, THUNK_TARGET);
3347 }
3348 unlock_user(argptr, target_ifc_buf, target_ifc_len);
3349 }
3350
3351 if (free_buf) {
3352 free(host_ifconf);
3353 }
3354
3355 return ret;
3356}
3357
3358static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
3359 abi_long cmd, abi_long arg)
3360{
3361 void *argptr;
3362 struct dm_ioctl *host_dm;
3363 abi_long guest_data;
3364 uint32_t guest_data_size;
3365 int target_size;
3366 const argtype *arg_type = ie->arg_type;
3367 abi_long ret;
3368 void *big_buf = NULL;
3369 char *host_data;
3370
3371 arg_type++;
3372 target_size = thunk_type_size(arg_type, 0);
3373 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3374 if (!argptr) {
3375 ret = -TARGET_EFAULT;
3376 goto out;
3377 }
3378 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3379 unlock_user(argptr, arg, 0);
3380
3381
3382 big_buf = g_malloc0(((struct dm_ioctl*)buf_temp)->data_size * 2);
3383 memcpy(big_buf, buf_temp, target_size);
3384 buf_temp = big_buf;
3385 host_dm = big_buf;
3386
3387 guest_data = arg + host_dm->data_start;
3388 if ((guest_data - arg) < 0) {
3389 ret = -EINVAL;
3390 goto out;
3391 }
3392 guest_data_size = host_dm->data_size - host_dm->data_start;
3393 host_data = (char*)host_dm + host_dm->data_start;
3394
3395 argptr = lock_user(VERIFY_READ, guest_data, guest_data_size, 1);
3396 switch (ie->host_cmd) {
3397 case DM_REMOVE_ALL:
3398 case DM_LIST_DEVICES:
3399 case DM_DEV_CREATE:
3400 case DM_DEV_REMOVE:
3401 case DM_DEV_SUSPEND:
3402 case DM_DEV_STATUS:
3403 case DM_DEV_WAIT:
3404 case DM_TABLE_STATUS:
3405 case DM_TABLE_CLEAR:
3406 case DM_TABLE_DEPS:
3407 case DM_LIST_VERSIONS:
3408
3409 break;
3410 case DM_DEV_RENAME:
3411 case DM_DEV_SET_GEOMETRY:
3412
3413 memcpy(host_data, argptr, guest_data_size);
3414 break;
3415 case DM_TARGET_MSG:
3416 memcpy(host_data, argptr, guest_data_size);
3417 *(uint64_t*)host_data = tswap64(*(uint64_t*)argptr);
3418 break;
3419 case DM_TABLE_LOAD:
3420 {
3421 void *gspec = argptr;
3422 void *cur_data = host_data;
3423 const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };
3424 int spec_size = thunk_type_size(arg_type, 0);
3425 int i;
3426
3427 for (i = 0; i < host_dm->target_count; i++) {
3428 struct dm_target_spec *spec = cur_data;
3429 uint32_t next;
3430 int slen;
3431
3432 thunk_convert(spec, gspec, arg_type, THUNK_HOST);
3433 slen = strlen((char*)gspec + spec_size) + 1;
3434 next = spec->next;
3435 spec->next = sizeof(*spec) + slen;
3436 strcpy((char*)&spec[1], gspec + spec_size);
3437 gspec += next;
3438 cur_data += spec->next;
3439 }
3440 break;
3441 }
3442 default:
3443 ret = -TARGET_EINVAL;
3444 goto out;
3445 }
3446 unlock_user(argptr, guest_data, 0);
3447
3448 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3449 if (!is_error(ret)) {
3450 guest_data = arg + host_dm->data_start;
3451 guest_data_size = host_dm->data_size - host_dm->data_start;
3452 argptr = lock_user(VERIFY_WRITE, guest_data, guest_data_size, 0);
3453 switch (ie->host_cmd) {
3454 case DM_REMOVE_ALL:
3455 case DM_DEV_CREATE:
3456 case DM_DEV_REMOVE:
3457 case DM_DEV_RENAME:
3458 case DM_DEV_SUSPEND:
3459 case DM_DEV_STATUS:
3460 case DM_TABLE_LOAD:
3461 case DM_TABLE_CLEAR:
3462 case DM_TARGET_MSG:
3463 case DM_DEV_SET_GEOMETRY:
3464
3465 break;
3466 case DM_LIST_DEVICES:
3467 {
3468 struct dm_name_list *nl = (void*)host_dm + host_dm->data_start;
3469 uint32_t remaining_data = guest_data_size;
3470 void *cur_data = argptr;
3471 const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_name_list) };
3472 int nl_size = 12;
3473
3474 while (1) {
3475 uint32_t next = nl->next;
3476 if (next) {
3477 nl->next = nl_size + (strlen(nl->name) + 1);
3478 }
3479 if (remaining_data < nl->next) {
3480 host_dm->flags |= DM_BUFFER_FULL_FLAG;
3481 break;
3482 }
3483 thunk_convert(cur_data, nl, arg_type, THUNK_TARGET);
3484 strcpy(cur_data + nl_size, nl->name);
3485 cur_data += nl->next;
3486 remaining_data -= nl->next;
3487 if (!next) {
3488 break;
3489 }
3490 nl = (void*)nl + next;
3491 }
3492 break;
3493 }
3494 case DM_DEV_WAIT:
3495 case DM_TABLE_STATUS:
3496 {
3497 struct dm_target_spec *spec = (void*)host_dm + host_dm->data_start;
3498 void *cur_data = argptr;
3499 const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };
3500 int spec_size = thunk_type_size(arg_type, 0);
3501 int i;
3502
3503 for (i = 0; i < host_dm->target_count; i++) {
3504 uint32_t next = spec->next;
3505 int slen = strlen((char*)&spec[1]) + 1;
3506 spec->next = (cur_data - argptr) + spec_size + slen;
3507 if (guest_data_size < spec->next) {
3508 host_dm->flags |= DM_BUFFER_FULL_FLAG;
3509 break;
3510 }
3511 thunk_convert(cur_data, spec, arg_type, THUNK_TARGET);
3512 strcpy(cur_data + spec_size, (char*)&spec[1]);
3513 cur_data = argptr + spec->next;
3514 spec = (void*)host_dm + host_dm->data_start + next;
3515 }
3516 break;
3517 }
3518 case DM_TABLE_DEPS:
3519 {
3520 void *hdata = (void*)host_dm + host_dm->data_start;
3521 int count = *(uint32_t*)hdata;
3522 uint64_t *hdev = hdata + 8;
3523 uint64_t *gdev = argptr + 8;
3524 int i;
3525
3526 *(uint32_t*)argptr = tswap32(count);
3527 for (i = 0; i < count; i++) {
3528 *gdev = tswap64(*hdev);
3529 gdev++;
3530 hdev++;
3531 }
3532 break;
3533 }
3534 case DM_LIST_VERSIONS:
3535 {
3536 struct dm_target_versions *vers = (void*)host_dm + host_dm->data_start;
3537 uint32_t remaining_data = guest_data_size;
3538 void *cur_data = argptr;
3539 const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_versions) };
3540 int vers_size = thunk_type_size(arg_type, 0);
3541
3542 while (1) {
3543 uint32_t next = vers->next;
3544 if (next) {
3545 vers->next = vers_size + (strlen(vers->name) + 1);
3546 }
3547 if (remaining_data < vers->next) {
3548 host_dm->flags |= DM_BUFFER_FULL_FLAG;
3549 break;
3550 }
3551 thunk_convert(cur_data, vers, arg_type, THUNK_TARGET);
3552 strcpy(cur_data + vers_size, vers->name);
3553 cur_data += vers->next;
3554 remaining_data -= vers->next;
3555 if (!next) {
3556 break;
3557 }
3558 vers = (void*)vers + next;
3559 }
3560 break;
3561 }
3562 default:
3563 ret = -TARGET_EINVAL;
3564 goto out;
3565 }
3566 unlock_user(argptr, guest_data, guest_data_size);
3567
3568 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3569 if (!argptr) {
3570 ret = -TARGET_EFAULT;
3571 goto out;
3572 }
3573 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
3574 unlock_user(argptr, arg, target_size);
3575 }
3576out:
3577 if (big_buf) {
3578 free(big_buf);
3579 }
3580 return ret;
3581}
3582
3583static IOCTLEntry ioctl_entries[] = {
3584#define IOCTL(cmd, access, ...) \
3585 { TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } },
3586#define IOCTL_SPECIAL(cmd, access, dofn, ...) \
3587 { TARGET_ ## cmd, cmd, #cmd, access, dofn, { __VA_ARGS__ } },
3588#include "ioctls.h"
3589 { 0, 0, },
3590};
3591
3592
3593
3594static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
3595{
3596 const IOCTLEntry *ie;
3597 const argtype *arg_type;
3598 abi_long ret;
3599 uint8_t buf_temp[MAX_STRUCT_SIZE];
3600 int target_size;
3601 void *argptr;
3602
3603 ie = ioctl_entries;
3604 for(;;) {
3605 if (ie->target_cmd == 0) {
3606 gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
3607 return -TARGET_ENOSYS;
3608 }
3609 if (ie->target_cmd == cmd)
3610 break;
3611 ie++;
3612 }
3613 arg_type = ie->arg_type;
3614#if defined(DEBUG)
3615 gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
3616#endif
3617 if (ie->do_ioctl) {
3618 return ie->do_ioctl(ie, buf_temp, fd, cmd, arg);
3619 }
3620
3621 switch(arg_type[0]) {
3622 case TYPE_NULL:
3623
3624 ret = get_errno(ioctl(fd, ie->host_cmd));
3625 break;
3626 case TYPE_PTRVOID:
3627 case TYPE_INT:
3628
3629 ret = get_errno(ioctl(fd, ie->host_cmd, arg));
3630 break;
3631 case TYPE_PTR:
3632 arg_type++;
3633 target_size = thunk_type_size(arg_type, 0);
3634 switch(ie->access) {
3635 case IOC_R:
3636 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3637 if (!is_error(ret)) {
3638 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3639 if (!argptr)
3640 return -TARGET_EFAULT;
3641 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
3642 unlock_user(argptr, arg, target_size);
3643 }
3644 break;
3645 case IOC_W:
3646 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3647 if (!argptr)
3648 return -TARGET_EFAULT;
3649 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3650 unlock_user(argptr, arg, 0);
3651 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3652 break;
3653 default:
3654 case IOC_RW:
3655 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3656 if (!argptr)
3657 return -TARGET_EFAULT;
3658 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3659 unlock_user(argptr, arg, 0);
3660 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3661 if (!is_error(ret)) {
3662 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3663 if (!argptr)
3664 return -TARGET_EFAULT;
3665 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
3666 unlock_user(argptr, arg, target_size);
3667 }
3668 break;
3669 }
3670 break;
3671 default:
3672 gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
3673 (long)cmd, arg_type[0]);
3674 ret = -TARGET_ENOSYS;
3675 break;
3676 }
3677 return ret;
3678}
3679
3680static const bitmask_transtbl iflag_tbl[] = {
3681 { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
3682 { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
3683 { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
3684 { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
3685 { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
3686 { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
3687 { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
3688 { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
3689 { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
3690 { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
3691 { TARGET_IXON, TARGET_IXON, IXON, IXON },
3692 { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
3693 { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
3694 { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
3695 { 0, 0, 0, 0 }
3696};
3697
3698static const bitmask_transtbl oflag_tbl[] = {
3699 { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
3700 { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
3701 { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
3702 { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
3703 { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
3704 { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
3705 { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
3706 { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
3707 { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
3708 { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
3709 { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
3710 { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
3711 { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
3712 { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
3713 { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
3714 { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
3715 { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
3716 { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
3717 { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
3718 { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
3719 { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
3720 { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
3721 { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
3722 { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
3723 { 0, 0, 0, 0 }
3724};
3725
3726static const bitmask_transtbl cflag_tbl[] = {
3727 { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
3728 { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
3729 { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
3730 { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
3731 { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
3732 { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
3733 { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
3734 { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
3735 { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
3736 { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
3737 { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
3738 { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
3739 { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
3740 { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
3741 { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
3742 { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
3743 { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
3744 { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
3745 { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
3746 { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
3747 { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
3748 { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
3749 { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
3750 { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
3751 { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
3752 { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
3753 { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
3754 { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
3755 { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
3756 { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
3757 { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
3758 { 0, 0, 0, 0 }
3759};
3760
3761static const bitmask_transtbl lflag_tbl[] = {
3762 { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
3763 { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
3764 { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
3765 { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
3766 { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
3767 { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
3768 { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
3769 { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
3770 { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
3771 { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
3772 { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
3773 { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
3774 { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
3775 { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
3776 { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
3777 { 0, 0, 0, 0 }
3778};
3779
3780static void target_to_host_termios (void *dst, const void *src)
3781{
3782 struct host_termios *host = dst;
3783 const struct target_termios *target = src;
3784
3785 host->c_iflag =
3786 target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
3787 host->c_oflag =
3788 target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
3789 host->c_cflag =
3790 target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
3791 host->c_lflag =
3792 target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
3793 host->c_line = target->c_line;
3794
3795 memset(host->c_cc, 0, sizeof(host->c_cc));
3796 host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
3797 host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
3798 host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
3799 host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
3800 host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
3801 host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
3802 host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
3803 host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
3804 host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
3805 host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
3806 host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
3807 host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
3808 host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
3809 host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
3810 host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
3811 host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
3812 host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
3813}
3814
3815static void host_to_target_termios (void *dst, const void *src)
3816{
3817 struct target_termios *target = dst;
3818 const struct host_termios *host = src;
3819
3820 target->c_iflag =
3821 tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
3822 target->c_oflag =
3823 tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
3824 target->c_cflag =
3825 tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
3826 target->c_lflag =
3827 tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
3828 target->c_line = host->c_line;
3829
3830 memset(target->c_cc, 0, sizeof(target->c_cc));
3831 target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
3832 target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
3833 target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
3834 target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
3835 target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
3836 target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
3837 target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
3838 target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
3839 target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
3840 target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
3841 target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
3842 target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
3843 target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
3844 target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
3845 target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
3846 target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
3847 target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
3848}
3849
3850static const StructEntry struct_termios_def = {
3851 .convert = { host_to_target_termios, target_to_host_termios },
3852 .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
3853 .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
3854};
3855
3856static bitmask_transtbl mmap_flags_tbl[] = {
3857 { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
3858 { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
3859 { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
3860 { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
3861 { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
3862 { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
3863 { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
3864 { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
3865 { 0, 0, 0, 0 }
3866};
3867
3868#if defined(TARGET_I386)
3869
3870
3871static uint8_t *ldt_table;
3872
3873static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
3874{
3875 int size;
3876 void *p;
3877
3878 if (!ldt_table)
3879 return 0;
3880 size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
3881 if (size > bytecount)
3882 size = bytecount;
3883 p = lock_user(VERIFY_WRITE, ptr, size, 0);
3884 if (!p)
3885 return -TARGET_EFAULT;
3886
3887 memcpy(p, ldt_table, size);
3888 unlock_user(p, ptr, size);
3889 return size;
3890}
3891
3892
3893static abi_long write_ldt(CPUX86State *env,
3894 abi_ulong ptr, unsigned long bytecount, int oldmode)
3895{
3896 struct target_modify_ldt_ldt_s ldt_info;
3897 struct target_modify_ldt_ldt_s *target_ldt_info;
3898 int seg_32bit, contents, read_exec_only, limit_in_pages;
3899 int seg_not_present, useable, lm;
3900 uint32_t *lp, entry_1, entry_2;
3901
3902 if (bytecount != sizeof(ldt_info))
3903 return -TARGET_EINVAL;
3904 if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
3905 return -TARGET_EFAULT;
3906 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3907 ldt_info.base_addr = tswapal(target_ldt_info->base_addr);
3908 ldt_info.limit = tswap32(target_ldt_info->limit);
3909 ldt_info.flags = tswap32(target_ldt_info->flags);
3910 unlock_user_struct(target_ldt_info, ptr, 0);
3911
3912 if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
3913 return -TARGET_EINVAL;
3914 seg_32bit = ldt_info.flags & 1;
3915 contents = (ldt_info.flags >> 1) & 3;
3916 read_exec_only = (ldt_info.flags >> 3) & 1;
3917 limit_in_pages = (ldt_info.flags >> 4) & 1;
3918 seg_not_present = (ldt_info.flags >> 5) & 1;
3919 useable = (ldt_info.flags >> 6) & 1;
3920#ifdef TARGET_ABI32
3921 lm = 0;
3922#else
3923 lm = (ldt_info.flags >> 7) & 1;
3924#endif
3925 if (contents == 3) {
3926 if (oldmode)
3927 return -TARGET_EINVAL;
3928 if (seg_not_present == 0)
3929 return -TARGET_EINVAL;
3930 }
3931
3932 if (!ldt_table) {
3933 env->ldt.base = target_mmap(0,
3934 TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
3935 PROT_READ|PROT_WRITE,
3936 MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
3937 if (env->ldt.base == -1)
3938 return -TARGET_ENOMEM;
3939 memset(g2h(env->ldt.base), 0,
3940 TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
3941 env->ldt.limit = 0xffff;
3942 ldt_table = g2h(env->ldt.base);
3943 }
3944
3945
3946
3947 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3948 if (oldmode ||
3949 (contents == 0 &&
3950 read_exec_only == 1 &&
3951 seg_32bit == 0 &&
3952 limit_in_pages == 0 &&
3953 seg_not_present == 1 &&
3954 useable == 0 )) {
3955 entry_1 = 0;
3956 entry_2 = 0;
3957 goto install;
3958 }
3959 }
3960
3961 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
3962 (ldt_info.limit & 0x0ffff);
3963 entry_2 = (ldt_info.base_addr & 0xff000000) |
3964 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3965 (ldt_info.limit & 0xf0000) |
3966 ((read_exec_only ^ 1) << 9) |
3967 (contents << 10) |
3968 ((seg_not_present ^ 1) << 15) |
3969 (seg_32bit << 22) |
3970 (limit_in_pages << 23) |
3971 (lm << 21) |
3972 0x7000;
3973 if (!oldmode)
3974 entry_2 |= (useable << 20);
3975
3976
3977install:
3978 lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
3979 lp[0] = tswap32(entry_1);
3980 lp[1] = tswap32(entry_2);
3981 return 0;
3982}
3983
3984
3985static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
3986 unsigned long bytecount)
3987{
3988 abi_long ret;
3989
3990 switch (func) {
3991 case 0:
3992 ret = read_ldt(ptr, bytecount);
3993 break;
3994 case 1:
3995 ret = write_ldt(env, ptr, bytecount, 1);
3996 break;
3997 case 0x11:
3998 ret = write_ldt(env, ptr, bytecount, 0);
3999 break;
4000 default:
4001 ret = -TARGET_ENOSYS;
4002 break;
4003 }
4004 return ret;
4005}
4006
4007#if defined(TARGET_I386) && defined(TARGET_ABI32)
4008static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
4009{
4010 uint64_t *gdt_table = g2h(env->gdt.base);
4011 struct target_modify_ldt_ldt_s ldt_info;
4012 struct target_modify_ldt_ldt_s *target_ldt_info;
4013 int seg_32bit, contents, read_exec_only, limit_in_pages;
4014 int seg_not_present, useable, lm;
4015 uint32_t *lp, entry_1, entry_2;
4016 int i;
4017
4018 lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
4019 if (!target_ldt_info)
4020 return -TARGET_EFAULT;
4021 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
4022 ldt_info.base_addr = tswapal(target_ldt_info->base_addr);
4023 ldt_info.limit = tswap32(target_ldt_info->limit);
4024 ldt_info.flags = tswap32(target_ldt_info->flags);
4025 if (ldt_info.entry_number == -1) {
4026 for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
4027 if (gdt_table[i] == 0) {
4028 ldt_info.entry_number = i;
4029 target_ldt_info->entry_number = tswap32(i);
4030 break;
4031 }
4032 }
4033 }
4034 unlock_user_struct(target_ldt_info, ptr, 1);
4035
4036 if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN ||
4037 ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
4038 return -TARGET_EINVAL;
4039 seg_32bit = ldt_info.flags & 1;
4040 contents = (ldt_info.flags >> 1) & 3;
4041 read_exec_only = (ldt_info.flags >> 3) & 1;
4042 limit_in_pages = (ldt_info.flags >> 4) & 1;
4043 seg_not_present = (ldt_info.flags >> 5) & 1;
4044 useable = (ldt_info.flags >> 6) & 1;
4045#ifdef TARGET_ABI32
4046 lm = 0;
4047#else
4048 lm = (ldt_info.flags >> 7) & 1;
4049#endif
4050
4051 if (contents == 3) {
4052 if (seg_not_present == 0)
4053 return -TARGET_EINVAL;
4054 }
4055
4056
4057
4058 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
4059 if ((contents == 0 &&
4060 read_exec_only == 1 &&
4061 seg_32bit == 0 &&
4062 limit_in_pages == 0 &&
4063 seg_not_present == 1 &&
4064 useable == 0 )) {
4065 entry_1 = 0;
4066 entry_2 = 0;
4067 goto install;
4068 }
4069 }
4070
4071 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
4072 (ldt_info.limit & 0x0ffff);
4073 entry_2 = (ldt_info.base_addr & 0xff000000) |
4074 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
4075 (ldt_info.limit & 0xf0000) |
4076 ((read_exec_only ^ 1) << 9) |
4077 (contents << 10) |
4078 ((seg_not_present ^ 1) << 15) |
4079 (seg_32bit << 22) |
4080 (limit_in_pages << 23) |
4081 (useable << 20) |
4082 (lm << 21) |
4083 0x7000;
4084
4085
4086install:
4087 lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
4088 lp[0] = tswap32(entry_1);
4089 lp[1] = tswap32(entry_2);
4090 return 0;
4091}
4092
4093static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
4094{
4095 struct target_modify_ldt_ldt_s *target_ldt_info;
4096 uint64_t *gdt_table = g2h(env->gdt.base);
4097 uint32_t base_addr, limit, flags;
4098 int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
4099 int seg_not_present, useable, lm;
4100 uint32_t *lp, entry_1, entry_2;
4101
4102 lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
4103 if (!target_ldt_info)
4104 return -TARGET_EFAULT;
4105 idx = tswap32(target_ldt_info->entry_number);
4106 if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
4107 idx > TARGET_GDT_ENTRY_TLS_MAX) {
4108 unlock_user_struct(target_ldt_info, ptr, 1);
4109 return -TARGET_EINVAL;
4110 }
4111 lp = (uint32_t *)(gdt_table + idx);
4112 entry_1 = tswap32(lp[0]);
4113 entry_2 = tswap32(lp[1]);
4114
4115 read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
4116 contents = (entry_2 >> 10) & 3;
4117 seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
4118 seg_32bit = (entry_2 >> 22) & 1;
4119 limit_in_pages = (entry_2 >> 23) & 1;
4120 useable = (entry_2 >> 20) & 1;
4121#ifdef TARGET_ABI32
4122 lm = 0;
4123#else
4124 lm = (entry_2 >> 21) & 1;
4125#endif
4126 flags = (seg_32bit << 0) | (contents << 1) |
4127 (read_exec_only << 3) | (limit_in_pages << 4) |
4128 (seg_not_present << 5) | (useable << 6) | (lm << 7);
4129 limit = (entry_1 & 0xffff) | (entry_2 & 0xf0000);
4130 base_addr = (entry_1 >> 16) |
4131 (entry_2 & 0xff000000) |
4132 ((entry_2 & 0xff) << 16);
4133 target_ldt_info->base_addr = tswapal(base_addr);
4134 target_ldt_info->limit = tswap32(limit);
4135 target_ldt_info->flags = tswap32(flags);
4136 unlock_user_struct(target_ldt_info, ptr, 1);
4137 return 0;
4138}
4139#endif
4140
4141#ifndef TARGET_ABI32
4142static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
4143{
4144 abi_long ret = 0;
4145 abi_ulong val;
4146 int idx;
4147
4148 switch(code) {
4149 case TARGET_ARCH_SET_GS:
4150 case TARGET_ARCH_SET_FS:
4151 if (code == TARGET_ARCH_SET_GS)
4152 idx = R_GS;
4153 else
4154 idx = R_FS;
4155 cpu_x86_load_seg(env, idx, 0);
4156 env->segs[idx].base = addr;
4157 break;
4158 case TARGET_ARCH_GET_GS:
4159 case TARGET_ARCH_GET_FS:
4160 if (code == TARGET_ARCH_GET_GS)
4161 idx = R_GS;
4162 else
4163 idx = R_FS;
4164 val = env->segs[idx].base;
4165 if (put_user(val, addr, abi_ulong))
4166 ret = -TARGET_EFAULT;
4167 break;
4168 default:
4169 ret = -TARGET_EINVAL;
4170 break;
4171 }
4172 return ret;
4173}
4174#endif
4175
4176#endif
4177
4178#define NEW_STACK_SIZE 0x40000
4179
4180#if defined(CONFIG_USE_NPTL)
4181
4182static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
4183typedef struct {
4184 CPUArchState *env;
4185 pthread_mutex_t mutex;
4186 pthread_cond_t cond;
4187 pthread_t thread;
4188 uint32_t tid;
4189 abi_ulong child_tidptr;
4190 abi_ulong parent_tidptr;
4191 sigset_t sigmask;
4192} new_thread_info;
4193
4194static void *clone_func(void *arg)
4195{
4196 new_thread_info *info = arg;
4197 CPUArchState *env;
4198 TaskState *ts;
4199
4200 env = info->env;
4201 thread_env = env;
4202 ts = (TaskState *)thread_env->opaque;
4203 info->tid = gettid();
4204 env->host_tid = info->tid;
4205 task_settid(ts);
4206 if (info->child_tidptr)
4207 put_user_u32(info->tid, info->child_tidptr);
4208 if (info->parent_tidptr)
4209 put_user_u32(info->tid, info->parent_tidptr);
4210
4211 sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
4212
4213 pthread_mutex_lock(&info->mutex);
4214 pthread_cond_broadcast(&info->cond);
4215 pthread_mutex_unlock(&info->mutex);
4216
4217 pthread_mutex_lock(&clone_lock);
4218 pthread_mutex_unlock(&clone_lock);
4219 cpu_loop(env);
4220
4221 return NULL;
4222}
4223#else
4224
4225static int clone_func(void *arg)
4226{
4227 CPUArchState *env = arg;
4228 cpu_loop(env);
4229
4230 return 0;
4231}
4232#endif
4233
4234
4235
4236static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
4237 abi_ulong parent_tidptr, target_ulong newtls,
4238 abi_ulong child_tidptr)
4239{
4240 int ret;
4241 TaskState *ts;
4242 CPUArchState *new_env;
4243#if defined(CONFIG_USE_NPTL)
4244 unsigned int nptl_flags;
4245 sigset_t sigmask;
4246#else
4247 uint8_t *new_stack;
4248#endif
4249
4250
4251 if (flags & CLONE_VFORK)
4252 flags &= ~(CLONE_VFORK | CLONE_VM);
4253
4254 if (flags & CLONE_VM) {
4255 TaskState *parent_ts = (TaskState *)env->opaque;
4256#if defined(CONFIG_USE_NPTL)
4257 new_thread_info info;
4258 pthread_attr_t attr;
4259#endif
4260 ts = g_malloc0(sizeof(TaskState));
4261 init_task_state(ts);
4262
4263 new_env = cpu_copy(env);
4264#if defined(TARGET_I386) || defined(TARGET_SPARC) || defined(TARGET_PPC)
4265 cpu_state_reset(new_env);
4266#endif
4267
4268 cpu_clone_regs(new_env, newsp);
4269 new_env->opaque = ts;
4270 ts->bprm = parent_ts->bprm;
4271 ts->info = parent_ts->info;
4272#if defined(CONFIG_USE_NPTL)
4273 nptl_flags = flags;
4274 flags &= ~CLONE_NPTL_FLAGS2;
4275
4276 if (nptl_flags & CLONE_CHILD_CLEARTID) {
4277 ts->child_tidptr = child_tidptr;
4278 }
4279
4280 if (nptl_flags & CLONE_SETTLS)
4281 cpu_set_tls (new_env, newtls);
4282
4283
4284 pthread_mutex_lock(&clone_lock);
4285
4286 memset(&info, 0, sizeof(info));
4287 pthread_mutex_init(&info.mutex, NULL);
4288 pthread_mutex_lock(&info.mutex);
4289 pthread_cond_init(&info.cond, NULL);
4290 info.env = new_env;
4291 if (nptl_flags & CLONE_CHILD_SETTID)
4292 info.child_tidptr = child_tidptr;
4293 if (nptl_flags & CLONE_PARENT_SETTID)
4294 info.parent_tidptr = parent_tidptr;
4295
4296 ret = pthread_attr_init(&attr);
4297 ret = pthread_attr_setstacksize(&attr, NEW_STACK_SIZE);
4298 ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
4299
4300
4301 sigfillset(&sigmask);
4302 sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
4303
4304 ret = pthread_create(&info.thread, &attr, clone_func, &info);
4305
4306
4307 sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
4308 pthread_attr_destroy(&attr);
4309 if (ret == 0) {
4310
4311 pthread_cond_wait(&info.cond, &info.mutex);
4312 ret = info.tid;
4313 if (flags & CLONE_PARENT_SETTID)
4314 put_user_u32(ret, parent_tidptr);
4315 } else {
4316 ret = -1;
4317 }
4318 pthread_mutex_unlock(&info.mutex);
4319 pthread_cond_destroy(&info.cond);
4320 pthread_mutex_destroy(&info.mutex);
4321 pthread_mutex_unlock(&clone_lock);
4322#else
4323 if (flags & CLONE_NPTL_FLAGS2)
4324 return -EINVAL;
4325
4326 new_stack = g_malloc0 (NEW_STACK_SIZE);
4327#ifdef __ia64__
4328 ret = __clone2(clone_func, new_stack, NEW_STACK_SIZE, flags, new_env);
4329#else
4330 ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
4331#endif
4332#endif
4333 } else {
4334
4335 if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
4336 return -EINVAL;
4337 fork_start();
4338 ret = fork();
4339 if (ret == 0) {
4340
4341 cpu_clone_regs(env, newsp);
4342 fork_end(1);
4343#if defined(CONFIG_USE_NPTL)
4344
4345
4346
4347
4348
4349
4350 if (flags & CLONE_CHILD_SETTID)
4351 put_user_u32(gettid(), child_tidptr);
4352 if (flags & CLONE_PARENT_SETTID)
4353 put_user_u32(gettid(), parent_tidptr);
4354 ts = (TaskState *)env->opaque;
4355 if (flags & CLONE_SETTLS)
4356 cpu_set_tls (env, newtls);
4357 if (flags & CLONE_CHILD_CLEARTID)
4358 ts->child_tidptr = child_tidptr;
4359#endif
4360 } else {
4361 fork_end(0);
4362 }
4363 }
4364 return ret;
4365}
4366
4367
4368static int target_to_host_fcntl_cmd(int cmd)
4369{
4370 switch(cmd) {
4371 case TARGET_F_DUPFD:
4372 case TARGET_F_GETFD:
4373 case TARGET_F_SETFD:
4374 case TARGET_F_GETFL:
4375 case TARGET_F_SETFL:
4376 return cmd;
4377 case TARGET_F_GETLK:
4378 return F_GETLK;
4379 case TARGET_F_SETLK:
4380 return F_SETLK;
4381 case TARGET_F_SETLKW:
4382 return F_SETLKW;
4383 case TARGET_F_GETOWN:
4384 return F_GETOWN;
4385 case TARGET_F_SETOWN:
4386 return F_SETOWN;
4387 case TARGET_F_GETSIG:
4388 return F_GETSIG;
4389 case TARGET_F_SETSIG:
4390 return F_SETSIG;
4391#if TARGET_ABI_BITS == 32
4392 case TARGET_F_GETLK64:
4393 return F_GETLK64;
4394 case TARGET_F_SETLK64:
4395 return F_SETLK64;
4396 case TARGET_F_SETLKW64:
4397 return F_SETLKW64;
4398#endif
4399 case TARGET_F_SETLEASE:
4400 return F_SETLEASE;
4401 case TARGET_F_GETLEASE:
4402 return F_GETLEASE;
4403#ifdef F_DUPFD_CLOEXEC
4404 case TARGET_F_DUPFD_CLOEXEC:
4405 return F_DUPFD_CLOEXEC;
4406#endif
4407 case TARGET_F_NOTIFY:
4408 return F_NOTIFY;
4409 default:
4410 return -TARGET_EINVAL;
4411 }
4412 return -TARGET_EINVAL;
4413}
4414
4415static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
4416{
4417 struct flock fl;
4418 struct target_flock *target_fl;
4419 struct flock64 fl64;
4420 struct target_flock64 *target_fl64;
4421 abi_long ret;
4422 int host_cmd = target_to_host_fcntl_cmd(cmd);
4423
4424 if (host_cmd == -TARGET_EINVAL)
4425 return host_cmd;
4426
4427 switch(cmd) {
4428 case TARGET_F_GETLK:
4429 if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
4430 return -TARGET_EFAULT;
4431 fl.l_type = tswap16(target_fl->l_type);
4432 fl.l_whence = tswap16(target_fl->l_whence);
4433 fl.l_start = tswapal(target_fl->l_start);
4434 fl.l_len = tswapal(target_fl->l_len);
4435 fl.l_pid = tswap32(target_fl->l_pid);
4436 unlock_user_struct(target_fl, arg, 0);
4437 ret = get_errno(fcntl(fd, host_cmd, &fl));
4438 if (ret == 0) {
4439 if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
4440 return -TARGET_EFAULT;
4441 target_fl->l_type = tswap16(fl.l_type);
4442 target_fl->l_whence = tswap16(fl.l_whence);
4443 target_fl->l_start = tswapal(fl.l_start);
4444 target_fl->l_len = tswapal(fl.l_len);
4445 target_fl->l_pid = tswap32(fl.l_pid);
4446 unlock_user_struct(target_fl, arg, 1);
4447 }
4448 break;
4449
4450 case TARGET_F_SETLK:
4451 case TARGET_F_SETLKW:
4452 if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
4453 return -TARGET_EFAULT;
4454 fl.l_type = tswap16(target_fl->l_type);
4455 fl.l_whence = tswap16(target_fl->l_whence);
4456 fl.l_start = tswapal(target_fl->l_start);
4457 fl.l_len = tswapal(target_fl->l_len);
4458 fl.l_pid = tswap32(target_fl->l_pid);
4459 unlock_user_struct(target_fl, arg, 0);
4460 ret = get_errno(fcntl(fd, host_cmd, &fl));
4461 break;
4462
4463 case TARGET_F_GETLK64:
4464 if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
4465 return -TARGET_EFAULT;
4466 fl64.l_type = tswap16(target_fl64->l_type) >> 1;
4467 fl64.l_whence = tswap16(target_fl64->l_whence);
4468 fl64.l_start = tswap64(target_fl64->l_start);
4469 fl64.l_len = tswap64(target_fl64->l_len);
4470 fl64.l_pid = tswap32(target_fl64->l_pid);
4471 unlock_user_struct(target_fl64, arg, 0);
4472 ret = get_errno(fcntl(fd, host_cmd, &fl64));
4473 if (ret == 0) {
4474 if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
4475 return -TARGET_EFAULT;
4476 target_fl64->l_type = tswap16(fl64.l_type) >> 1;
4477 target_fl64->l_whence = tswap16(fl64.l_whence);
4478 target_fl64->l_start = tswap64(fl64.l_start);
4479 target_fl64->l_len = tswap64(fl64.l_len);
4480 target_fl64->l_pid = tswap32(fl64.l_pid);
4481 unlock_user_struct(target_fl64, arg, 1);
4482 }
4483 break;
4484 case TARGET_F_SETLK64:
4485 case TARGET_F_SETLKW64:
4486 if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
4487 return -TARGET_EFAULT;
4488 fl64.l_type = tswap16(target_fl64->l_type) >> 1;
4489 fl64.l_whence = tswap16(target_fl64->l_whence);
4490 fl64.l_start = tswap64(target_fl64->l_start);
4491 fl64.l_len = tswap64(target_fl64->l_len);
4492 fl64.l_pid = tswap32(target_fl64->l_pid);
4493 unlock_user_struct(target_fl64, arg, 0);
4494 ret = get_errno(fcntl(fd, host_cmd, &fl64));
4495 break;
4496
4497 case TARGET_F_GETFL:
4498 ret = get_errno(fcntl(fd, host_cmd, arg));
4499 if (ret >= 0) {
4500 ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
4501 }
4502 break;
4503
4504 case TARGET_F_SETFL:
4505 ret = get_errno(fcntl(fd, host_cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
4506 break;
4507
4508 case TARGET_F_SETOWN:
4509 case TARGET_F_GETOWN:
4510 case TARGET_F_SETSIG:
4511 case TARGET_F_GETSIG:
4512 case TARGET_F_SETLEASE:
4513 case TARGET_F_GETLEASE:
4514 ret = get_errno(fcntl(fd, host_cmd, arg));
4515 break;
4516
4517 default:
4518 ret = get_errno(fcntl(fd, cmd, arg));
4519 break;
4520 }
4521 return ret;
4522}
4523
4524#ifdef USE_UID16
4525
4526static inline int high2lowuid(int uid)
4527{
4528 if (uid > 65535)
4529 return 65534;
4530 else
4531 return uid;
4532}
4533
4534static inline int high2lowgid(int gid)
4535{
4536 if (gid > 65535)
4537 return 65534;
4538 else
4539 return gid;
4540}
4541
4542static inline int low2highuid(int uid)
4543{
4544 if ((int16_t)uid == -1)
4545 return -1;
4546 else
4547 return uid;
4548}
4549
4550static inline int low2highgid(int gid)
4551{
4552 if ((int16_t)gid == -1)
4553 return -1;
4554 else
4555 return gid;
4556}
4557static inline int tswapid(int id)
4558{
4559 return tswap16(id);
4560}
4561#else
4562static inline int high2lowuid(int uid)
4563{
4564 return uid;
4565}
4566static inline int high2lowgid(int gid)
4567{
4568 return gid;
4569}
4570static inline int low2highuid(int uid)
4571{
4572 return uid;
4573}
4574static inline int low2highgid(int gid)
4575{
4576 return gid;
4577}
4578static inline int tswapid(int id)
4579{
4580 return tswap32(id);
4581}
4582#endif
4583
4584void syscall_init(void)
4585{
4586 IOCTLEntry *ie;
4587 const argtype *arg_type;
4588 int size;
4589 int i;
4590
4591#define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
4592#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
4593#include "syscall_types.h"
4594#undef STRUCT
4595#undef STRUCT_SPECIAL
4596
4597
4598
4599 ie = ioctl_entries;
4600 while (ie->target_cmd != 0) {
4601 if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
4602 TARGET_IOC_SIZEMASK) {
4603 arg_type = ie->arg_type;
4604 if (arg_type[0] != TYPE_PTR) {
4605 fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
4606 ie->target_cmd);
4607 exit(1);
4608 }
4609 arg_type++;
4610 size = thunk_type_size(arg_type, 0);
4611 ie->target_cmd = (ie->target_cmd &
4612 ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
4613 (size << TARGET_IOC_SIZESHIFT);
4614 }
4615
4616
4617
4618 for (i=0; i < ERRNO_TABLE_SIZE; i++)
4619 target_to_host_errno_table[host_to_target_errno_table[i]] = i;
4620
4621
4622#if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
4623 (defined(__x86_64__) && defined(TARGET_X86_64))
4624 if (unlikely(ie->target_cmd != ie->host_cmd)) {
4625 fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
4626 ie->name, ie->target_cmd, ie->host_cmd);
4627 }
4628#endif
4629 ie++;
4630 }
4631}
4632
4633#if TARGET_ABI_BITS == 32
4634static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
4635{
4636#ifdef TARGET_WORDS_BIGENDIAN
4637 return ((uint64_t)word0 << 32) | word1;
4638#else
4639 return ((uint64_t)word1 << 32) | word0;
4640#endif
4641}
4642#else
4643static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
4644{
4645 return word0;
4646}
4647#endif
4648
4649#ifdef TARGET_NR_truncate64
4650static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
4651 abi_long arg2,
4652 abi_long arg3,
4653 abi_long arg4)
4654{
4655 if (regpairs_aligned(cpu_env)) {
4656 arg2 = arg3;
4657 arg3 = arg4;
4658 }
4659 return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
4660}
4661#endif
4662
4663#ifdef TARGET_NR_ftruncate64
4664static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
4665 abi_long arg2,
4666 abi_long arg3,
4667 abi_long arg4)
4668{
4669 if (regpairs_aligned(cpu_env)) {
4670 arg2 = arg3;
4671 arg3 = arg4;
4672 }
4673 return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
4674}
4675#endif
4676
4677static inline abi_long target_to_host_timespec(struct timespec *host_ts,
4678 abi_ulong target_addr)
4679{
4680 struct target_timespec *target_ts;
4681
4682 if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
4683 return -TARGET_EFAULT;
4684 host_ts->tv_sec = tswapal(target_ts->tv_sec);
4685 host_ts->tv_nsec = tswapal(target_ts->tv_nsec);
4686 unlock_user_struct(target_ts, target_addr, 0);
4687 return 0;
4688}
4689
4690static inline abi_long host_to_target_timespec(abi_ulong target_addr,
4691 struct timespec *host_ts)
4692{
4693 struct target_timespec *target_ts;
4694
4695 if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
4696 return -TARGET_EFAULT;
4697 target_ts->tv_sec = tswapal(host_ts->tv_sec);
4698 target_ts->tv_nsec = tswapal(host_ts->tv_nsec);
4699 unlock_user_struct(target_ts, target_addr, 1);
4700 return 0;
4701}
4702
4703#if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
4704static inline abi_long host_to_target_stat64(void *cpu_env,
4705 abi_ulong target_addr,
4706 struct stat *host_st)
4707{
4708#ifdef TARGET_ARM
4709 if (((CPUARMState *)cpu_env)->eabi) {
4710 struct target_eabi_stat64 *target_st;
4711
4712 if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
4713 return -TARGET_EFAULT;
4714 memset(target_st, 0, sizeof(struct target_eabi_stat64));
4715 __put_user(host_st->st_dev, &target_st->st_dev);
4716 __put_user(host_st->st_ino, &target_st->st_ino);
4717#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4718 __put_user(host_st->st_ino, &target_st->__st_ino);
4719#endif
4720 __put_user(host_st->st_mode, &target_st->st_mode);
4721 __put_user(host_st->st_nlink, &target_st->st_nlink);
4722 __put_user(host_st->st_uid, &target_st->st_uid);
4723 __put_user(host_st->st_gid, &target_st->st_gid);
4724 __put_user(host_st->st_rdev, &target_st->st_rdev);
4725 __put_user(host_st->st_size, &target_st->st_size);
4726 __put_user(host_st->st_blksize, &target_st->st_blksize);
4727 __put_user(host_st->st_blocks, &target_st->st_blocks);
4728 __put_user(host_st->st_atime, &target_st->target_st_atime);
4729 __put_user(host_st->st_mtime, &target_st->target_st_mtime);
4730 __put_user(host_st->st_ctime, &target_st->target_st_ctime);
4731 unlock_user_struct(target_st, target_addr, 1);
4732 } else
4733#endif
4734 {
4735#if TARGET_ABI_BITS == 64 && !defined(TARGET_ALPHA)
4736 struct target_stat *target_st;
4737#else
4738 struct target_stat64 *target_st;
4739#endif
4740
4741 if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
4742 return -TARGET_EFAULT;
4743 memset(target_st, 0, sizeof(*target_st));
4744 __put_user(host_st->st_dev, &target_st->st_dev);
4745 __put_user(host_st->st_ino, &target_st->st_ino);
4746#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4747 __put_user(host_st->st_ino, &target_st->__st_ino);
4748#endif
4749 __put_user(host_st->st_mode, &target_st->st_mode);
4750 __put_user(host_st->st_nlink, &target_st->st_nlink);
4751 __put_user(host_st->st_uid, &target_st->st_uid);
4752 __put_user(host_st->st_gid, &target_st->st_gid);
4753 __put_user(host_st->st_rdev, &target_st->st_rdev);
4754
4755 __put_user(host_st->st_size, &target_st->st_size);
4756 __put_user(host_st->st_blksize, &target_st->st_blksize);
4757 __put_user(host_st->st_blocks, &target_st->st_blocks);
4758 __put_user(host_st->st_atime, &target_st->target_st_atime);
4759 __put_user(host_st->st_mtime, &target_st->target_st_mtime);
4760 __put_user(host_st->st_ctime, &target_st->target_st_ctime);
4761 unlock_user_struct(target_st, target_addr, 1);
4762 }
4763
4764 return 0;
4765}
4766#endif
4767
4768#if defined(CONFIG_USE_NPTL)
4769
4770
4771
4772
4773
4774static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
4775 target_ulong uaddr2, int val3)
4776{
4777 struct timespec ts, *pts;
4778 int base_op;
4779
4780
4781
4782#ifdef FUTEX_CMD_MASK
4783 base_op = op & FUTEX_CMD_MASK;
4784#else
4785 base_op = op;
4786#endif
4787 switch (base_op) {
4788 case FUTEX_WAIT:
4789 if (timeout) {
4790 pts = &ts;
4791 target_to_host_timespec(pts, timeout);
4792 } else {
4793 pts = NULL;
4794 }
4795 return get_errno(sys_futex(g2h(uaddr), op, tswap32(val),
4796 pts, NULL, 0));
4797 case FUTEX_WAKE:
4798 return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4799 case FUTEX_FD:
4800 return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4801 case FUTEX_REQUEUE:
4802 case FUTEX_CMP_REQUEUE:
4803 case FUTEX_WAKE_OP:
4804
4805
4806
4807
4808
4809 pts = (struct timespec *)(uintptr_t) timeout;
4810 return get_errno(sys_futex(g2h(uaddr), op, val, pts,
4811 g2h(uaddr2),
4812 (base_op == FUTEX_CMP_REQUEUE
4813 ? tswap32(val3)
4814 : val3)));
4815 default:
4816 return -TARGET_ENOSYS;
4817 }
4818}
4819#endif
4820
4821
4822
4823static int host_to_target_waitstatus(int status)
4824{
4825 if (WIFSIGNALED(status)) {
4826 return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f);
4827 }
4828 if (WIFSTOPPED(status)) {
4829 return (host_to_target_signal(WSTOPSIG(status)) << 8)
4830 | (status & 0xff);
4831 }
4832 return status;
4833}
4834
4835int get_osversion(void)
4836{
4837 static int osversion;
4838 struct new_utsname buf;
4839 const char *s;
4840 int i, n, tmp;
4841 if (osversion)
4842 return osversion;
4843 if (qemu_uname_release && *qemu_uname_release) {
4844 s = qemu_uname_release;
4845 } else {
4846 if (sys_uname(&buf))
4847 return 0;
4848 s = buf.release;
4849 }
4850 tmp = 0;
4851 for (i = 0; i < 3; i++) {
4852 n = 0;
4853 while (*s >= '0' && *s <= '9') {
4854 n *= 10;
4855 n += *s - '0';
4856 s++;
4857 }
4858 tmp = (tmp << 8) + n;
4859 if (*s == '.')
4860 s++;
4861 }
4862 osversion = tmp;
4863 return osversion;
4864}
4865
4866
4867static int open_self_maps(void *cpu_env, int fd)
4868{
4869#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
4870 TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
4871#endif
4872 FILE *fp;
4873 char *line = NULL;
4874 size_t len = 0;
4875 ssize_t read;
4876
4877 fp = fopen("/proc/self/maps", "r");
4878 if (fp == NULL) {
4879 return -EACCES;
4880 }
4881
4882 while ((read = getline(&line, &len, fp)) != -1) {
4883 int fields, dev_maj, dev_min, inode;
4884 uint64_t min, max, offset;
4885 char flag_r, flag_w, flag_x, flag_p;
4886 char path[512] = "";
4887 fields = sscanf(line, "%"PRIx64"-%"PRIx64" %c%c%c%c %"PRIx64" %x:%x %d"
4888 " %512s", &min, &max, &flag_r, &flag_w, &flag_x,
4889 &flag_p, &offset, &dev_maj, &dev_min, &inode, path);
4890
4891 if ((fields < 10) || (fields > 11)) {
4892 continue;
4893 }
4894 if (!strncmp(path, "[stack]", 7)) {
4895 continue;
4896 }
4897 if (h2g_valid(min) && h2g_valid(max)) {
4898 dprintf(fd, TARGET_ABI_FMT_lx "-" TARGET_ABI_FMT_lx
4899 " %c%c%c%c %08" PRIx64 " %02x:%02x %d%s%s\n",
4900 h2g(min), h2g(max), flag_r, flag_w,
4901 flag_x, flag_p, offset, dev_maj, dev_min, inode,
4902 path[0] ? " " : "", path);
4903 }
4904 }
4905
4906 free(line);
4907 fclose(fp);
4908
4909#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
4910 dprintf(fd, "%08llx-%08llx rw-p %08llx 00:00 0 [stack]\n",
4911 (unsigned long long)ts->info->stack_limit,
4912 (unsigned long long)(ts->stack_base + (TARGET_PAGE_SIZE - 1))
4913 & TARGET_PAGE_MASK,
4914 (unsigned long long)0);
4915#endif
4916
4917 return 0;
4918}
4919
4920static int open_self_stat(void *cpu_env, int fd)
4921{
4922 TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
4923 abi_ulong start_stack = ts->info->start_stack;
4924 int i;
4925
4926 for (i = 0; i < 44; i++) {
4927 char buf[128];
4928 int len;
4929 uint64_t val = 0;
4930
4931 if (i == 0) {
4932
4933 val = getpid();
4934 snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
4935 } else if (i == 1) {
4936
4937 snprintf(buf, sizeof(buf), "(%s) ", ts->bprm->argv[0]);
4938 } else if (i == 27) {
4939
4940 val = start_stack;
4941 snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
4942 } else {
4943
4944 snprintf(buf, sizeof(buf), "0%c", i == 43 ? '\n' : ' ');
4945 }
4946
4947 len = strlen(buf);
4948 if (write(fd, buf, len) != len) {
4949 return -1;
4950 }
4951 }
4952
4953 return 0;
4954}
4955
4956static int open_self_auxv(void *cpu_env, int fd)
4957{
4958 TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
4959 abi_ulong auxv = ts->info->saved_auxv;
4960 abi_ulong len = ts->info->auxv_len;
4961 char *ptr;
4962
4963
4964
4965
4966
4967 ptr = lock_user(VERIFY_READ, auxv, len, 0);
4968 if (ptr != NULL) {
4969 while (len > 0) {
4970 ssize_t r;
4971 r = write(fd, ptr, len);
4972 if (r <= 0) {
4973 break;
4974 }
4975 len -= r;
4976 ptr += r;
4977 }
4978 lseek(fd, 0, SEEK_SET);
4979 unlock_user(ptr, auxv, len);
4980 }
4981
4982 return 0;
4983}
4984
4985static int do_open(void *cpu_env, const char *pathname, int flags, mode_t mode)
4986{
4987 struct fake_open {
4988 const char *filename;
4989 int (*fill)(void *cpu_env, int fd);
4990 };
4991 const struct fake_open *fake_open;
4992 static const struct fake_open fakes[] = {
4993 { "/proc/self/maps", open_self_maps },
4994 { "/proc/self/stat", open_self_stat },
4995 { "/proc/self/auxv", open_self_auxv },
4996 { NULL, NULL }
4997 };
4998
4999 for (fake_open = fakes; fake_open->filename; fake_open++) {
5000 if (!strncmp(pathname, fake_open->filename,
5001 strlen(fake_open->filename))) {
5002 break;
5003 }
5004 }
5005
5006 if (fake_open->filename) {
5007 const char *tmpdir;
5008 char filename[PATH_MAX];
5009 int fd, r;
5010
5011
5012 tmpdir = getenv("TMPDIR");
5013 if (!tmpdir)
5014 tmpdir = "/tmp";
5015 snprintf(filename, sizeof(filename), "%s/qemu-open.XXXXXX", tmpdir);
5016 fd = mkstemp(filename);
5017 if (fd < 0) {
5018 return fd;
5019 }
5020 unlink(filename);
5021
5022 if ((r = fake_open->fill(cpu_env, fd))) {
5023 close(fd);
5024 return r;
5025 }
5026 lseek(fd, 0, SEEK_SET);
5027
5028 return fd;
5029 }
5030
5031 return get_errno(open(path(pathname), flags, mode));
5032}
5033
5034
5035
5036
5037abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
5038 abi_long arg2, abi_long arg3, abi_long arg4,
5039 abi_long arg5, abi_long arg6, abi_long arg7,
5040 abi_long arg8)
5041{
5042 abi_long ret;
5043 struct stat st;
5044 struct statfs stfs;
5045 void *p;
5046
5047#ifdef DEBUG
5048 gemu_log("syscall %d", num);
5049#endif
5050 if(do_strace)
5051 print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
5052
5053 switch(num) {
5054 case TARGET_NR_exit:
5055#ifdef CONFIG_USE_NPTL
5056
5057
5058
5059
5060
5061
5062 if (first_cpu->next_cpu) {
5063 TaskState *ts;
5064 CPUArchState **lastp;
5065 CPUArchState *p;
5066
5067 cpu_list_lock();
5068 lastp = &first_cpu;
5069 p = first_cpu;
5070 while (p && p != (CPUArchState *)cpu_env) {
5071 lastp = &p->next_cpu;
5072 p = p->next_cpu;
5073 }
5074
5075
5076 if (!p)
5077 abort();
5078
5079 *lastp = p->next_cpu;
5080 cpu_list_unlock();
5081 ts = ((CPUArchState *)cpu_env)->opaque;
5082 if (ts->child_tidptr) {
5083 put_user_u32(0, ts->child_tidptr);
5084 sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
5085 NULL, NULL, 0);
5086 }
5087 thread_env = NULL;
5088 object_delete(OBJECT(ENV_GET_CPU(cpu_env)));
5089 g_free(ts);
5090 pthread_exit(NULL);
5091 }
5092#endif
5093#ifdef TARGET_GPROF
5094 _mcleanup();
5095#endif
5096 gdb_exit(cpu_env, arg1);
5097 _exit(arg1);
5098 ret = 0;
5099 break;
5100 case TARGET_NR_read:
5101 if (arg3 == 0)
5102 ret = 0;
5103 else {
5104 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5105 goto efault;
5106 ret = get_errno(read(arg1, p, arg3));
5107 unlock_user(p, arg2, ret);
5108 }
5109 break;
5110 case TARGET_NR_write:
5111 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5112 goto efault;
5113 ret = get_errno(write(arg1, p, arg3));
5114 unlock_user(p, arg2, 0);
5115 break;
5116 case TARGET_NR_open:
5117 if (!(p = lock_user_string(arg1)))
5118 goto efault;
5119 ret = get_errno(do_open(cpu_env, p,
5120 target_to_host_bitmask(arg2, fcntl_flags_tbl),
5121 arg3));
5122 unlock_user(p, arg1, 0);
5123 break;
5124#if defined(TARGET_NR_openat) && defined(__NR_openat)
5125 case TARGET_NR_openat:
5126 if (!(p = lock_user_string(arg2)))
5127 goto efault;
5128 ret = get_errno(sys_openat(arg1,
5129 path(p),
5130 target_to_host_bitmask(arg3, fcntl_flags_tbl),
5131 arg4));
5132 unlock_user(p, arg2, 0);
5133 break;
5134#endif
5135 case TARGET_NR_close:
5136 ret = get_errno(close(arg1));
5137 break;
5138 case TARGET_NR_brk:
5139 ret = do_brk(arg1);
5140 break;
5141 case TARGET_NR_fork:
5142 ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
5143 break;
5144#ifdef TARGET_NR_waitpid
5145 case TARGET_NR_waitpid:
5146 {
5147 int status;
5148 ret = get_errno(waitpid(arg1, &status, arg3));
5149 if (!is_error(ret) && arg2 && ret
5150 && put_user_s32(host_to_target_waitstatus(status), arg2))
5151 goto efault;
5152 }
5153 break;
5154#endif
5155#ifdef TARGET_NR_waitid
5156 case TARGET_NR_waitid:
5157 {
5158 siginfo_t info;
5159 info.si_pid = 0;
5160 ret = get_errno(waitid(arg1, arg2, &info, arg4));
5161 if (!is_error(ret) && arg3 && info.si_pid != 0) {
5162 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
5163 goto efault;
5164 host_to_target_siginfo(p, &info);
5165 unlock_user(p, arg3, sizeof(target_siginfo_t));
5166 }
5167 }
5168 break;
5169#endif
5170#ifdef TARGET_NR_creat
5171 case TARGET_NR_creat:
5172 if (!(p = lock_user_string(arg1)))
5173 goto efault;
5174 ret = get_errno(creat(p, arg2));
5175 unlock_user(p, arg1, 0);
5176 break;
5177#endif
5178 case TARGET_NR_link:
5179 {
5180 void * p2;
5181 p = lock_user_string(arg1);
5182 p2 = lock_user_string(arg2);
5183 if (!p || !p2)
5184 ret = -TARGET_EFAULT;
5185 else
5186 ret = get_errno(link(p, p2));
5187 unlock_user(p2, arg2, 0);
5188 unlock_user(p, arg1, 0);
5189 }
5190 break;
5191#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
5192 case TARGET_NR_linkat:
5193 {
5194 void * p2 = NULL;
5195 if (!arg2 || !arg4)
5196 goto efault;
5197 p = lock_user_string(arg2);
5198 p2 = lock_user_string(arg4);
5199 if (!p || !p2)
5200 ret = -TARGET_EFAULT;
5201 else
5202 ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
5203 unlock_user(p, arg2, 0);
5204 unlock_user(p2, arg4, 0);
5205 }
5206 break;
5207#endif
5208 case TARGET_NR_unlink:
5209 if (!(p = lock_user_string(arg1)))
5210 goto efault;
5211 ret = get_errno(unlink(p));
5212 unlock_user(p, arg1, 0);
5213 break;
5214#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
5215 case TARGET_NR_unlinkat:
5216 if (!(p = lock_user_string(arg2)))
5217 goto efault;
5218 ret = get_errno(sys_unlinkat(arg1, p, arg3));
5219 unlock_user(p, arg2, 0);
5220 break;
5221#endif
5222 case TARGET_NR_execve:
5223 {
5224 char **argp, **envp;
5225 int argc, envc;
5226 abi_ulong gp;
5227 abi_ulong guest_argp;
5228 abi_ulong guest_envp;
5229 abi_ulong addr;
5230 char **q;
5231 int total_size = 0;
5232
5233 argc = 0;
5234 guest_argp = arg2;
5235 for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
5236 if (get_user_ual(addr, gp))
5237 goto efault;
5238 if (!addr)
5239 break;
5240 argc++;
5241 }
5242 envc = 0;
5243 guest_envp = arg3;
5244 for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
5245 if (get_user_ual(addr, gp))
5246 goto efault;
5247 if (!addr)
5248 break;
5249 envc++;
5250 }
5251
5252 argp = alloca((argc + 1) * sizeof(void *));
5253 envp = alloca((envc + 1) * sizeof(void *));
5254
5255 for (gp = guest_argp, q = argp; gp;
5256 gp += sizeof(abi_ulong), q++) {
5257 if (get_user_ual(addr, gp))
5258 goto execve_efault;
5259 if (!addr)
5260 break;
5261 if (!(*q = lock_user_string(addr)))
5262 goto execve_efault;
5263 total_size += strlen(*q) + 1;
5264 }
5265 *q = NULL;
5266
5267 for (gp = guest_envp, q = envp; gp;
5268 gp += sizeof(abi_ulong), q++) {
5269 if (get_user_ual(addr, gp))
5270 goto execve_efault;
5271 if (!addr)
5272 break;
5273 if (!(*q = lock_user_string(addr)))
5274 goto execve_efault;
5275 total_size += strlen(*q) + 1;
5276 }
5277 *q = NULL;
5278
5279
5280
5281 if (total_size > MAX_ARG_PAGES * TARGET_PAGE_SIZE) {
5282 ret = -TARGET_E2BIG;
5283 goto execve_end;
5284 }
5285 if (!(p = lock_user_string(arg1)))
5286 goto execve_efault;
5287 ret = get_errno(execve(p, argp, envp));
5288 unlock_user(p, arg1, 0);
5289
5290 goto execve_end;
5291
5292 execve_efault:
5293 ret = -TARGET_EFAULT;
5294
5295 execve_end:
5296 for (gp = guest_argp, q = argp; *q;
5297 gp += sizeof(abi_ulong), q++) {
5298 if (get_user_ual(addr, gp)
5299 || !addr)
5300 break;
5301 unlock_user(*q, addr, 0);
5302 }
5303 for (gp = guest_envp, q = envp; *q;
5304 gp += sizeof(abi_ulong), q++) {
5305 if (get_user_ual(addr, gp)
5306 || !addr)
5307 break;
5308 unlock_user(*q, addr, 0);
5309 }
5310 }
5311 break;
5312 case TARGET_NR_chdir:
5313 if (!(p = lock_user_string(arg1)))
5314 goto efault;
5315 ret = get_errno(chdir(p));
5316 unlock_user(p, arg1, 0);
5317 break;
5318#ifdef TARGET_NR_time
5319 case TARGET_NR_time:
5320 {
5321 time_t host_time;
5322 ret = get_errno(time(&host_time));
5323 if (!is_error(ret)
5324 && arg1
5325 && put_user_sal(host_time, arg1))
5326 goto efault;
5327 }
5328 break;
5329#endif
5330 case TARGET_NR_mknod:
5331 if (!(p = lock_user_string(arg1)))
5332 goto efault;
5333 ret = get_errno(mknod(p, arg2, arg3));
5334 unlock_user(p, arg1, 0);
5335 break;
5336#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
5337 case TARGET_NR_mknodat:
5338 if (!(p = lock_user_string(arg2)))
5339 goto efault;
5340 ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
5341 unlock_user(p, arg2, 0);
5342 break;
5343#endif
5344 case TARGET_NR_chmod:
5345 if (!(p = lock_user_string(arg1)))
5346 goto efault;
5347 ret = get_errno(chmod(p, arg2));
5348 unlock_user(p, arg1, 0);
5349 break;
5350#ifdef TARGET_NR_break
5351 case TARGET_NR_break:
5352 goto unimplemented;
5353#endif
5354#ifdef TARGET_NR_oldstat
5355 case TARGET_NR_oldstat:
5356 goto unimplemented;
5357#endif
5358 case TARGET_NR_lseek:
5359 ret = get_errno(lseek(arg1, arg2, arg3));
5360 break;
5361#if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA)
5362
5363 case TARGET_NR_getxpid:
5364 ((CPUAlphaState *)cpu_env)->ir[IR_A4] = getppid();
5365 ret = get_errno(getpid());
5366 break;
5367#endif
5368#ifdef TARGET_NR_getpid
5369 case TARGET_NR_getpid:
5370 ret = get_errno(getpid());
5371 break;
5372#endif
5373 case TARGET_NR_mount:
5374 {
5375
5376 void *p2, *p3;
5377 p = lock_user_string(arg1);
5378 p2 = lock_user_string(arg2);
5379 p3 = lock_user_string(arg3);
5380 if (!p || !p2 || !p3)
5381 ret = -TARGET_EFAULT;
5382 else {
5383
5384
5385
5386
5387 if ( ! arg5 )
5388 ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, NULL));
5389 else
5390 ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
5391 }
5392 unlock_user(p, arg1, 0);
5393 unlock_user(p2, arg2, 0);
5394 unlock_user(p3, arg3, 0);
5395 break;
5396 }
5397#ifdef TARGET_NR_umount
5398 case TARGET_NR_umount:
5399 if (!(p = lock_user_string(arg1)))
5400 goto efault;
5401 ret = get_errno(umount(p));
5402 unlock_user(p, arg1, 0);
5403 break;
5404#endif
5405#ifdef TARGET_NR_stime
5406 case TARGET_NR_stime:
5407 {
5408 time_t host_time;
5409 if (get_user_sal(host_time, arg1))
5410 goto efault;
5411 ret = get_errno(stime(&host_time));
5412 }
5413 break;
5414#endif
5415 case TARGET_NR_ptrace:
5416 goto unimplemented;
5417#ifdef TARGET_NR_alarm
5418 case TARGET_NR_alarm:
5419 ret = alarm(arg1);
5420 break;
5421#endif
5422#ifdef TARGET_NR_oldfstat
5423 case TARGET_NR_oldfstat:
5424 goto unimplemented;
5425#endif
5426#ifdef TARGET_NR_pause
5427 case TARGET_NR_pause:
5428 ret = get_errno(pause());
5429 break;
5430#endif
5431#ifdef TARGET_NR_utime
5432 case TARGET_NR_utime:
5433 {
5434 struct utimbuf tbuf, *host_tbuf;
5435 struct target_utimbuf *target_tbuf;
5436 if (arg2) {
5437 if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
5438 goto efault;
5439 tbuf.actime = tswapal(target_tbuf->actime);
5440 tbuf.modtime = tswapal(target_tbuf->modtime);
5441 unlock_user_struct(target_tbuf, arg2, 0);
5442 host_tbuf = &tbuf;
5443 } else {
5444 host_tbuf = NULL;
5445 }
5446 if (!(p = lock_user_string(arg1)))
5447 goto efault;
5448 ret = get_errno(utime(p, host_tbuf));
5449 unlock_user(p, arg1, 0);
5450 }
5451 break;
5452#endif
5453 case TARGET_NR_utimes:
5454 {
5455 struct timeval *tvp, tv[2];
5456 if (arg2) {
5457 if (copy_from_user_timeval(&tv[0], arg2)
5458 || copy_from_user_timeval(&tv[1],
5459 arg2 + sizeof(struct target_timeval)))
5460 goto efault;
5461 tvp = tv;
5462 } else {
5463 tvp = NULL;
5464 }
5465 if (!(p = lock_user_string(arg1)))
5466 goto efault;
5467 ret = get_errno(utimes(p, tvp));
5468 unlock_user(p, arg1, 0);
5469 }
5470 break;
5471#if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
5472 case TARGET_NR_futimesat:
5473 {
5474 struct timeval *tvp, tv[2];
5475 if (arg3) {
5476 if (copy_from_user_timeval(&tv[0], arg3)
5477 || copy_from_user_timeval(&tv[1],
5478 arg3 + sizeof(struct target_timeval)))
5479 goto efault;
5480 tvp = tv;
5481 } else {
5482 tvp = NULL;
5483 }
5484 if (!(p = lock_user_string(arg2)))
5485 goto efault;
5486 ret = get_errno(sys_futimesat(arg1, path(p), tvp));
5487 unlock_user(p, arg2, 0);
5488 }
5489 break;
5490#endif
5491#ifdef TARGET_NR_stty
5492 case TARGET_NR_stty:
5493 goto unimplemented;
5494#endif
5495#ifdef TARGET_NR_gtty
5496 case TARGET_NR_gtty:
5497 goto unimplemented;
5498#endif
5499 case TARGET_NR_access:
5500 if (!(p = lock_user_string(arg1)))
5501 goto efault;
5502 ret = get_errno(access(path(p), arg2));
5503 unlock_user(p, arg1, 0);
5504 break;
5505#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
5506 case TARGET_NR_faccessat:
5507 if (!(p = lock_user_string(arg2)))
5508 goto efault;
5509 ret = get_errno(sys_faccessat(arg1, p, arg3));
5510 unlock_user(p, arg2, 0);
5511 break;
5512#endif
5513#ifdef TARGET_NR_nice
5514 case TARGET_NR_nice:
5515 ret = get_errno(nice(arg1));
5516 break;
5517#endif
5518#ifdef TARGET_NR_ftime
5519 case TARGET_NR_ftime:
5520 goto unimplemented;
5521#endif
5522 case TARGET_NR_sync:
5523 sync();
5524 ret = 0;
5525 break;
5526 case TARGET_NR_kill:
5527 ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
5528 break;
5529 case TARGET_NR_rename:
5530 {
5531 void *p2;
5532 p = lock_user_string(arg1);
5533 p2 = lock_user_string(arg2);
5534 if (!p || !p2)
5535 ret = -TARGET_EFAULT;
5536 else
5537 ret = get_errno(rename(p, p2));
5538 unlock_user(p2, arg2, 0);
5539 unlock_user(p, arg1, 0);
5540 }
5541 break;
5542#if defined(TARGET_NR_renameat) && defined(__NR_renameat)
5543 case TARGET_NR_renameat:
5544 {
5545 void *p2;
5546 p = lock_user_string(arg2);
5547 p2 = lock_user_string(arg4);
5548 if (!p || !p2)
5549 ret = -TARGET_EFAULT;
5550 else
5551 ret = get_errno(sys_renameat(arg1, p, arg3, p2));
5552 unlock_user(p2, arg4, 0);
5553 unlock_user(p, arg2, 0);
5554 }
5555 break;
5556#endif
5557 case TARGET_NR_mkdir:
5558 if (!(p = lock_user_string(arg1)))
5559 goto efault;
5560 ret = get_errno(mkdir(p, arg2));
5561 unlock_user(p, arg1, 0);
5562 break;
5563#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
5564 case TARGET_NR_mkdirat:
5565 if (!(p = lock_user_string(arg2)))
5566 goto efault;
5567 ret = get_errno(sys_mkdirat(arg1, p, arg3));
5568 unlock_user(p, arg2, 0);
5569 break;
5570#endif
5571 case TARGET_NR_rmdir:
5572 if (!(p = lock_user_string(arg1)))
5573 goto efault;
5574 ret = get_errno(rmdir(p));
5575 unlock_user(p, arg1, 0);
5576 break;
5577 case TARGET_NR_dup:
5578 ret = get_errno(dup(arg1));
5579 break;
5580 case TARGET_NR_pipe:
5581 ret = do_pipe(cpu_env, arg1, 0, 0);
5582 break;
5583#ifdef TARGET_NR_pipe2
5584 case TARGET_NR_pipe2:
5585 ret = do_pipe(cpu_env, arg1, arg2, 1);
5586 break;
5587#endif
5588 case TARGET_NR_times:
5589 {
5590 struct target_tms *tmsp;
5591 struct tms tms;
5592 ret = get_errno(times(&tms));
5593 if (arg1) {
5594 tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
5595 if (!tmsp)
5596 goto efault;
5597 tmsp->tms_utime = tswapal(host_to_target_clock_t(tms.tms_utime));
5598 tmsp->tms_stime = tswapal(host_to_target_clock_t(tms.tms_stime));
5599 tmsp->tms_cutime = tswapal(host_to_target_clock_t(tms.tms_cutime));
5600 tmsp->tms_cstime = tswapal(host_to_target_clock_t(tms.tms_cstime));
5601 }
5602 if (!is_error(ret))
5603 ret = host_to_target_clock_t(ret);
5604 }
5605 break;
5606#ifdef TARGET_NR_prof
5607 case TARGET_NR_prof:
5608 goto unimplemented;
5609#endif
5610#ifdef TARGET_NR_signal
5611 case TARGET_NR_signal:
5612 goto unimplemented;
5613#endif
5614 case TARGET_NR_acct:
5615 if (arg1 == 0) {
5616 ret = get_errno(acct(NULL));
5617 } else {
5618 if (!(p = lock_user_string(arg1)))
5619 goto efault;
5620 ret = get_errno(acct(path(p)));
5621 unlock_user(p, arg1, 0);
5622 }
5623 break;
5624#ifdef TARGET_NR_umount2
5625 case TARGET_NR_umount2:
5626 if (!(p = lock_user_string(arg1)))
5627 goto efault;
5628 ret = get_errno(umount2(p, arg2));
5629 unlock_user(p, arg1, 0);
5630 break;
5631#endif
5632#ifdef TARGET_NR_lock
5633 case TARGET_NR_lock:
5634 goto unimplemented;
5635#endif
5636 case TARGET_NR_ioctl:
5637 ret = do_ioctl(arg1, arg2, arg3);
5638 break;
5639 case TARGET_NR_fcntl:
5640 ret = do_fcntl(arg1, arg2, arg3);
5641 break;
5642#ifdef TARGET_NR_mpx
5643 case TARGET_NR_mpx:
5644 goto unimplemented;
5645#endif
5646 case TARGET_NR_setpgid:
5647 ret = get_errno(setpgid(arg1, arg2));
5648 break;
5649#ifdef TARGET_NR_ulimit
5650 case TARGET_NR_ulimit:
5651 goto unimplemented;
5652#endif
5653#ifdef TARGET_NR_oldolduname
5654 case TARGET_NR_oldolduname:
5655 goto unimplemented;
5656#endif
5657 case TARGET_NR_umask:
5658 ret = get_errno(umask(arg1));
5659 break;
5660 case TARGET_NR_chroot:
5661 if (!(p = lock_user_string(arg1)))
5662 goto efault;
5663 ret = get_errno(chroot(p));
5664 unlock_user(p, arg1, 0);
5665 break;
5666 case TARGET_NR_ustat:
5667 goto unimplemented;
5668 case TARGET_NR_dup2:
5669 ret = get_errno(dup2(arg1, arg2));
5670 break;
5671#if defined(CONFIG_DUP3) && defined(TARGET_NR_dup3)
5672 case TARGET_NR_dup3:
5673 ret = get_errno(dup3(arg1, arg2, arg3));
5674 break;
5675#endif
5676#ifdef TARGET_NR_getppid
5677 case TARGET_NR_getppid:
5678 ret = get_errno(getppid());
5679 break;
5680#endif
5681 case TARGET_NR_getpgrp:
5682 ret = get_errno(getpgrp());
5683 break;
5684 case TARGET_NR_setsid:
5685 ret = get_errno(setsid());
5686 break;
5687#ifdef TARGET_NR_sigaction
5688 case TARGET_NR_sigaction:
5689 {
5690#if defined(TARGET_ALPHA)
5691 struct target_sigaction act, oact, *pact = 0;
5692 struct target_old_sigaction *old_act;
5693 if (arg2) {
5694 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
5695 goto efault;
5696 act._sa_handler = old_act->_sa_handler;
5697 target_siginitset(&act.sa_mask, old_act->sa_mask);
5698 act.sa_flags = old_act->sa_flags;
5699 act.sa_restorer = 0;
5700 unlock_user_struct(old_act, arg2, 0);
5701 pact = &act;
5702 }
5703 ret = get_errno(do_sigaction(arg1, pact, &oact));
5704 if (!is_error(ret) && arg3) {
5705 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
5706 goto efault;
5707 old_act->_sa_handler = oact._sa_handler;
5708 old_act->sa_mask = oact.sa_mask.sig[0];
5709 old_act->sa_flags = oact.sa_flags;
5710 unlock_user_struct(old_act, arg3, 1);
5711 }
5712#elif defined(TARGET_MIPS)
5713 struct target_sigaction act, oact, *pact, *old_act;
5714
5715 if (arg2) {
5716 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
5717 goto efault;
5718 act._sa_handler = old_act->_sa_handler;
5719 target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
5720 act.sa_flags = old_act->sa_flags;
5721 unlock_user_struct(old_act, arg2, 0);
5722 pact = &act;
5723 } else {
5724 pact = NULL;
5725 }
5726
5727 ret = get_errno(do_sigaction(arg1, pact, &oact));
5728
5729 if (!is_error(ret) && arg3) {
5730 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
5731 goto efault;
5732 old_act->_sa_handler = oact._sa_handler;
5733 old_act->sa_flags = oact.sa_flags;
5734 old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
5735 old_act->sa_mask.sig[1] = 0;
5736 old_act->sa_mask.sig[2] = 0;
5737 old_act->sa_mask.sig[3] = 0;
5738 unlock_user_struct(old_act, arg3, 1);
5739 }
5740#else
5741 struct target_old_sigaction *old_act;
5742 struct target_sigaction act, oact, *pact;
5743 if (arg2) {
5744 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
5745 goto efault;
5746 act._sa_handler = old_act->_sa_handler;
5747 target_siginitset(&act.sa_mask, old_act->sa_mask);
5748 act.sa_flags = old_act->sa_flags;
5749 act.sa_restorer = old_act->sa_restorer;
5750 unlock_user_struct(old_act, arg2, 0);
5751 pact = &act;
5752 } else {
5753 pact = NULL;
5754 }
5755 ret = get_errno(do_sigaction(arg1, pact, &oact));
5756 if (!is_error(ret) && arg3) {
5757 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
5758 goto efault;
5759 old_act->_sa_handler = oact._sa_handler;
5760 old_act->sa_mask = oact.sa_mask.sig[0];
5761 old_act->sa_flags = oact.sa_flags;
5762 old_act->sa_restorer = oact.sa_restorer;
5763 unlock_user_struct(old_act, arg3, 1);
5764 }
5765#endif
5766 }
5767 break;
5768#endif
5769 case TARGET_NR_rt_sigaction:
5770 {
5771#if defined(TARGET_ALPHA)
5772 struct target_sigaction act, oact, *pact = 0;
5773 struct target_rt_sigaction *rt_act;
5774
5775 if (arg2) {
5776 if (!lock_user_struct(VERIFY_READ, rt_act, arg2, 1))
5777 goto efault;
5778 act._sa_handler = rt_act->_sa_handler;
5779 act.sa_mask = rt_act->sa_mask;
5780 act.sa_flags = rt_act->sa_flags;
5781 act.sa_restorer = arg5;
5782 unlock_user_struct(rt_act, arg2, 0);
5783 pact = &act;
5784 }
5785 ret = get_errno(do_sigaction(arg1, pact, &oact));
5786 if (!is_error(ret) && arg3) {
5787 if (!lock_user_struct(VERIFY_WRITE, rt_act, arg3, 0))
5788 goto efault;
5789 rt_act->_sa_handler = oact._sa_handler;
5790 rt_act->sa_mask = oact.sa_mask;
5791 rt_act->sa_flags = oact.sa_flags;
5792 unlock_user_struct(rt_act, arg3, 1);
5793 }
5794#else
5795 struct target_sigaction *act;
5796 struct target_sigaction *oact;
5797
5798 if (arg2) {
5799 if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
5800 goto efault;
5801 } else
5802 act = NULL;
5803 if (arg3) {
5804 if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
5805 ret = -TARGET_EFAULT;
5806 goto rt_sigaction_fail;
5807 }
5808 } else
5809 oact = NULL;
5810 ret = get_errno(do_sigaction(arg1, act, oact));
5811 rt_sigaction_fail:
5812 if (act)
5813 unlock_user_struct(act, arg2, 0);
5814 if (oact)
5815 unlock_user_struct(oact, arg3, 1);
5816#endif
5817 }
5818 break;
5819#ifdef TARGET_NR_sgetmask
5820 case TARGET_NR_sgetmask:
5821 {
5822 sigset_t cur_set;
5823 abi_ulong target_set;
5824 sigprocmask(0, NULL, &cur_set);
5825 host_to_target_old_sigset(&target_set, &cur_set);
5826 ret = target_set;
5827 }
5828 break;
5829#endif
5830#ifdef TARGET_NR_ssetmask
5831 case TARGET_NR_ssetmask:
5832 {
5833 sigset_t set, oset, cur_set;
5834 abi_ulong target_set = arg1;
5835 sigprocmask(0, NULL, &cur_set);
5836 target_to_host_old_sigset(&set, &target_set);
5837 sigorset(&set, &set, &cur_set);
5838 sigprocmask(SIG_SETMASK, &set, &oset);
5839 host_to_target_old_sigset(&target_set, &oset);
5840 ret = target_set;
5841 }
5842 break;
5843#endif
5844#ifdef TARGET_NR_sigprocmask
5845 case TARGET_NR_sigprocmask:
5846 {
5847#if defined(TARGET_ALPHA)
5848 sigset_t set, oldset;
5849 abi_ulong mask;
5850 int how;
5851
5852 switch (arg1) {
5853 case TARGET_SIG_BLOCK:
5854 how = SIG_BLOCK;
5855 break;
5856 case TARGET_SIG_UNBLOCK:
5857 how = SIG_UNBLOCK;
5858 break;
5859 case TARGET_SIG_SETMASK:
5860 how = SIG_SETMASK;
5861 break;
5862 default:
5863 ret = -TARGET_EINVAL;
5864 goto fail;
5865 }
5866 mask = arg2;
5867 target_to_host_old_sigset(&set, &mask);
5868
5869 ret = get_errno(sigprocmask(how, &set, &oldset));
5870
5871 if (!is_error(ret)) {
5872 host_to_target_old_sigset(&mask, &oldset);
5873 ret = mask;
5874 ((CPUAlphaState *)cpu_env)->[IR_V0] = 0;
5875 }
5876#else
5877 sigset_t set, oldset, *set_ptr;
5878 int how;
5879
5880 if (arg2) {
5881 switch (arg1) {
5882 case TARGET_SIG_BLOCK:
5883 how = SIG_BLOCK;
5884 break;
5885 case TARGET_SIG_UNBLOCK:
5886 how = SIG_UNBLOCK;
5887 break;
5888 case TARGET_SIG_SETMASK:
5889 how = SIG_SETMASK;
5890 break;
5891 default:
5892 ret = -TARGET_EINVAL;
5893 goto fail;
5894 }
5895 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
5896 goto efault;
5897 target_to_host_old_sigset(&set, p);
5898 unlock_user(p, arg2, 0);
5899 set_ptr = &set;
5900 } else {
5901 how = 0;
5902 set_ptr = NULL;
5903 }
5904 ret = get_errno(sigprocmask(how, set_ptr, &oldset));
5905 if (!is_error(ret) && arg3) {
5906 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
5907 goto efault;
5908 host_to_target_old_sigset(p, &oldset);
5909 unlock_user(p, arg3, sizeof(target_sigset_t));
5910 }
5911#endif
5912 }
5913 break;
5914#endif
5915 case TARGET_NR_rt_sigprocmask:
5916 {
5917 int how = arg1;
5918 sigset_t set, oldset, *set_ptr;
5919
5920 if (arg2) {
5921 switch(how) {
5922 case TARGET_SIG_BLOCK:
5923 how = SIG_BLOCK;
5924 break;
5925 case TARGET_SIG_UNBLOCK:
5926 how = SIG_UNBLOCK;
5927 break;
5928 case TARGET_SIG_SETMASK:
5929 how = SIG_SETMASK;
5930 break;
5931 default:
5932 ret = -TARGET_EINVAL;
5933 goto fail;
5934 }
5935 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
5936 goto efault;
5937 target_to_host_sigset(&set, p);
5938 unlock_user(p, arg2, 0);
5939 set_ptr = &set;
5940 } else {
5941 how = 0;
5942 set_ptr = NULL;
5943 }
5944 ret = get_errno(sigprocmask(how, set_ptr, &oldset));
5945 if (!is_error(ret) && arg3) {
5946 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
5947 goto efault;
5948 host_to_target_sigset(p, &oldset);
5949 unlock_user(p, arg3, sizeof(target_sigset_t));
5950 }
5951 }
5952 break;
5953#ifdef TARGET_NR_sigpending
5954 case TARGET_NR_sigpending:
5955 {
5956 sigset_t set;
5957 ret = get_errno(sigpending(&set));
5958 if (!is_error(ret)) {
5959 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
5960 goto efault;
5961 host_to_target_old_sigset(p, &set);
5962 unlock_user(p, arg1, sizeof(target_sigset_t));
5963 }
5964 }
5965 break;
5966#endif
5967 case TARGET_NR_rt_sigpending:
5968 {
5969 sigset_t set;
5970 ret = get_errno(sigpending(&set));
5971 if (!is_error(ret)) {
5972 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
5973 goto efault;
5974 host_to_target_sigset(p, &set);
5975 unlock_user(p, arg1, sizeof(target_sigset_t));
5976 }
5977 }
5978 break;
5979#ifdef TARGET_NR_sigsuspend
5980 case TARGET_NR_sigsuspend:
5981 {
5982 sigset_t set;
5983#if defined(TARGET_ALPHA)
5984 abi_ulong mask = arg1;
5985 target_to_host_old_sigset(&set, &mask);
5986#else
5987 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
5988 goto efault;
5989 target_to_host_old_sigset(&set, p);
5990 unlock_user(p, arg1, 0);
5991#endif
5992 ret = get_errno(sigsuspend(&set));
5993 }
5994 break;
5995#endif
5996 case TARGET_NR_rt_sigsuspend:
5997 {
5998 sigset_t set;
5999 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
6000 goto efault;
6001 target_to_host_sigset(&set, p);
6002 unlock_user(p, arg1, 0);
6003 ret = get_errno(sigsuspend(&set));
6004 }
6005 break;
6006 case TARGET_NR_rt_sigtimedwait:
6007 {
6008 sigset_t set;
6009 struct timespec uts, *puts;
6010 siginfo_t uinfo;
6011
6012 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
6013 goto efault;
6014 target_to_host_sigset(&set, p);
6015 unlock_user(p, arg1, 0);
6016 if (arg3) {
6017 puts = &uts;
6018 target_to_host_timespec(puts, arg3);
6019 } else {
6020 puts = NULL;
6021 }
6022 ret = get_errno(sigtimedwait(&set, &uinfo, puts));
6023 if (!is_error(ret) && arg2) {
6024 if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
6025 goto efault;
6026 host_to_target_siginfo(p, &uinfo);
6027 unlock_user(p, arg2, sizeof(target_siginfo_t));
6028 }
6029 }
6030 break;
6031 case TARGET_NR_rt_sigqueueinfo:
6032 {
6033 siginfo_t uinfo;
6034 if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
6035 goto efault;
6036 target_to_host_siginfo(&uinfo, p);
6037 unlock_user(p, arg1, 0);
6038 ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
6039 }
6040 break;
6041#ifdef TARGET_NR_sigreturn
6042 case TARGET_NR_sigreturn:
6043
6044 ret = do_sigreturn(cpu_env);
6045 break;
6046#endif
6047 case TARGET_NR_rt_sigreturn:
6048
6049 ret = do_rt_sigreturn(cpu_env);
6050 break;
6051 case TARGET_NR_sethostname:
6052 if (!(p = lock_user_string(arg1)))
6053 goto efault;
6054 ret = get_errno(sethostname(p, arg2));
6055 unlock_user(p, arg1, 0);
6056 break;
6057 case TARGET_NR_setrlimit:
6058 {
6059 int resource = target_to_host_resource(arg1);
6060 struct target_rlimit *target_rlim;
6061 struct rlimit rlim;
6062 if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
6063 goto efault;
6064 rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur);
6065 rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max);
6066 unlock_user_struct(target_rlim, arg2, 0);
6067 ret = get_errno(setrlimit(resource, &rlim));
6068 }
6069 break;
6070 case TARGET_NR_getrlimit:
6071 {
6072 int resource = target_to_host_resource(arg1);
6073 struct target_rlimit *target_rlim;
6074 struct rlimit rlim;
6075
6076 ret = get_errno(getrlimit(resource, &rlim));
6077 if (!is_error(ret)) {
6078 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
6079 goto efault;
6080 target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
6081 target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
6082 unlock_user_struct(target_rlim, arg2, 1);
6083 }
6084 }
6085 break;
6086 case TARGET_NR_getrusage:
6087 {
6088 struct rusage rusage;
6089 ret = get_errno(getrusage(arg1, &rusage));
6090 if (!is_error(ret)) {
6091 host_to_target_rusage(arg2, &rusage);
6092 }
6093 }
6094 break;
6095 case TARGET_NR_gettimeofday:
6096 {
6097 struct timeval tv;
6098 ret = get_errno(gettimeofday(&tv, NULL));
6099 if (!is_error(ret)) {
6100 if (copy_to_user_timeval(arg1, &tv))
6101 goto efault;
6102 }
6103 }
6104 break;
6105 case TARGET_NR_settimeofday:
6106 {
6107 struct timeval tv;
6108 if (copy_from_user_timeval(&tv, arg1))
6109 goto efault;
6110 ret = get_errno(settimeofday(&tv, NULL));
6111 }
6112 break;
6113#if defined(TARGET_NR_select) && !defined(TARGET_S390X) && !defined(TARGET_S390)
6114 case TARGET_NR_select:
6115 {
6116 struct target_sel_arg_struct *sel;
6117 abi_ulong inp, outp, exp, tvp;
6118 long nsel;
6119
6120 if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
6121 goto efault;
6122 nsel = tswapal(sel->n);
6123 inp = tswapal(sel->inp);
6124 outp = tswapal(sel->outp);
6125 exp = tswapal(sel->exp);
6126 tvp = tswapal(sel->tvp);
6127 unlock_user_struct(sel, arg1, 0);
6128 ret = do_select(nsel, inp, outp, exp, tvp);
6129 }
6130 break;
6131#endif
6132#ifdef TARGET_NR_pselect6
6133 case TARGET_NR_pselect6:
6134 {
6135 abi_long rfd_addr, wfd_addr, efd_addr, n, ts_addr;
6136 fd_set rfds, wfds, efds;
6137 fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
6138 struct timespec ts, *ts_ptr;
6139
6140
6141
6142
6143
6144 sigset_t set;
6145 struct {
6146 sigset_t *set;
6147 size_t size;
6148 } sig, *sig_ptr;
6149
6150 abi_ulong arg_sigset, arg_sigsize, *arg7;
6151 target_sigset_t *target_sigset;
6152
6153 n = arg1;
6154 rfd_addr = arg2;
6155 wfd_addr = arg3;
6156 efd_addr = arg4;
6157 ts_addr = arg5;
6158
6159 ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
6160 if (ret) {
6161 goto fail;
6162 }
6163 ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
6164 if (ret) {
6165 goto fail;
6166 }
6167 ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
6168 if (ret) {
6169 goto fail;
6170 }
6171
6172
6173
6174
6175
6176 if (ts_addr) {
6177 if (target_to_host_timespec(&ts, ts_addr)) {
6178 goto efault;
6179 }
6180 ts_ptr = &ts;
6181 } else {
6182 ts_ptr = NULL;
6183 }
6184
6185
6186 if (arg6) {
6187 sig_ptr = &sig;
6188 sig.size = _NSIG / 8;
6189
6190 arg7 = lock_user(VERIFY_READ, arg6, sizeof(*arg7) * 2, 1);
6191 if (!arg7) {
6192 goto efault;
6193 }
6194 arg_sigset = tswapal(arg7[0]);
6195 arg_sigsize = tswapal(arg7[1]);
6196 unlock_user(arg7, arg6, 0);
6197
6198 if (arg_sigset) {
6199 sig.set = &set;
6200 if (arg_sigsize != sizeof(*target_sigset)) {
6201
6202 ret = -TARGET_EINVAL;
6203 goto fail;
6204 }
6205 target_sigset = lock_user(VERIFY_READ, arg_sigset,
6206 sizeof(*target_sigset), 1);
6207 if (!target_sigset) {
6208 goto efault;
6209 }
6210 target_to_host_sigset(&set, target_sigset);
6211 unlock_user(target_sigset, arg_sigset, 0);
6212 } else {
6213 sig.set = NULL;
6214 }
6215 } else {
6216 sig_ptr = NULL;
6217 }
6218
6219 ret = get_errno(sys_pselect6(n, rfds_ptr, wfds_ptr, efds_ptr,
6220 ts_ptr, sig_ptr));
6221
6222 if (!is_error(ret)) {
6223 if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
6224 goto efault;
6225 if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
6226 goto efault;
6227 if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
6228 goto efault;
6229
6230 if (ts_addr && host_to_target_timespec(ts_addr, &ts))
6231 goto efault;
6232 }
6233 }
6234 break;
6235#endif
6236 case TARGET_NR_symlink:
6237 {
6238 void *p2;
6239 p = lock_user_string(arg1);
6240 p2 = lock_user_string(arg2);
6241 if (!p || !p2)
6242 ret = -TARGET_EFAULT;
6243 else
6244 ret = get_errno(symlink(p, p2));
6245 unlock_user(p2, arg2, 0);
6246 unlock_user(p, arg1, 0);
6247 }
6248 break;
6249#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
6250 case TARGET_NR_symlinkat:
6251 {
6252 void *p2;
6253 p = lock_user_string(arg1);
6254 p2 = lock_user_string(arg3);
6255 if (!p || !p2)
6256 ret = -TARGET_EFAULT;
6257 else
6258 ret = get_errno(sys_symlinkat(p, arg2, p2));
6259 unlock_user(p2, arg3, 0);
6260 unlock_user(p, arg1, 0);
6261 }
6262 break;
6263#endif
6264#ifdef TARGET_NR_oldlstat
6265 case TARGET_NR_oldlstat:
6266 goto unimplemented;
6267#endif
6268 case TARGET_NR_readlink:
6269 {
6270 void *p2, *temp;
6271 p = lock_user_string(arg1);
6272 p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
6273 if (!p || !p2)
6274 ret = -TARGET_EFAULT;
6275 else {
6276 if (strncmp((const char *)p, "/proc/self/exe", 14) == 0) {
6277 char real[PATH_MAX];
6278 temp = realpath(exec_path,real);
6279 ret = (temp==NULL) ? get_errno(-1) : strlen(real) ;
6280 snprintf((char *)p2, arg3, "%s", real);
6281 }
6282 else
6283 ret = get_errno(readlink(path(p), p2, arg3));
6284 }
6285 unlock_user(p2, arg2, ret);
6286 unlock_user(p, arg1, 0);
6287 }
6288 break;
6289#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
6290 case TARGET_NR_readlinkat:
6291 {
6292 void *p2;
6293 p = lock_user_string(arg2);
6294 p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
6295 if (!p || !p2)
6296 ret = -TARGET_EFAULT;
6297 else
6298 ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
6299 unlock_user(p2, arg3, ret);
6300 unlock_user(p, arg2, 0);
6301 }
6302 break;
6303#endif
6304#ifdef TARGET_NR_uselib
6305 case TARGET_NR_uselib:
6306 goto unimplemented;
6307#endif
6308#ifdef TARGET_NR_swapon
6309 case TARGET_NR_swapon:
6310 if (!(p = lock_user_string(arg1)))
6311 goto efault;
6312 ret = get_errno(swapon(p, arg2));
6313 unlock_user(p, arg1, 0);
6314 break;
6315#endif
6316 case TARGET_NR_reboot:
6317 if (!(p = lock_user_string(arg4)))
6318 goto efault;
6319 ret = reboot(arg1, arg2, arg3, p);
6320 unlock_user(p, arg4, 0);
6321 break;
6322#ifdef TARGET_NR_readdir
6323 case TARGET_NR_readdir:
6324 goto unimplemented;
6325#endif
6326#ifdef TARGET_NR_mmap
6327 case TARGET_NR_mmap:
6328#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || \
6329 defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) \
6330 || defined(TARGET_S390X)
6331 {
6332 abi_ulong *v;
6333 abi_ulong v1, v2, v3, v4, v5, v6;
6334 if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
6335 goto efault;
6336 v1 = tswapal(v[0]);
6337 v2 = tswapal(v[1]);
6338 v3 = tswapal(v[2]);
6339 v4 = tswapal(v[3]);
6340 v5 = tswapal(v[4]);
6341 v6 = tswapal(v[5]);
6342 unlock_user(v, arg1, 0);
6343 ret = get_errno(target_mmap(v1, v2, v3,
6344 target_to_host_bitmask(v4, mmap_flags_tbl),
6345 v5, v6));
6346 }
6347#else
6348 ret = get_errno(target_mmap(arg1, arg2, arg3,
6349 target_to_host_bitmask(arg4, mmap_flags_tbl),
6350 arg5,
6351 arg6));
6352#endif
6353 break;
6354#endif
6355#ifdef TARGET_NR_mmap2
6356 case TARGET_NR_mmap2:
6357#ifndef MMAP_SHIFT
6358#define MMAP_SHIFT 12
6359#endif
6360 ret = get_errno(target_mmap(arg1, arg2, arg3,
6361 target_to_host_bitmask(arg4, mmap_flags_tbl),
6362 arg5,
6363 arg6 << MMAP_SHIFT));
6364 break;
6365#endif
6366 case TARGET_NR_munmap:
6367 ret = get_errno(target_munmap(arg1, arg2));
6368 break;
6369 case TARGET_NR_mprotect:
6370 {
6371 TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
6372
6373 if ((arg3 & PROT_GROWSDOWN)
6374 && arg1 >= ts->info->stack_limit
6375 && arg1 <= ts->info->start_stack) {
6376 arg3 &= ~PROT_GROWSDOWN;
6377 arg2 = arg2 + arg1 - ts->info->stack_limit;
6378 arg1 = ts->info->stack_limit;
6379 }
6380 }
6381 ret = get_errno(target_mprotect(arg1, arg2, arg3));
6382 break;
6383#ifdef TARGET_NR_mremap
6384 case TARGET_NR_mremap:
6385 ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
6386 break;
6387#endif
6388
6389#ifdef TARGET_NR_msync
6390 case TARGET_NR_msync:
6391 ret = get_errno(msync(g2h(arg1), arg2, arg3));
6392 break;
6393#endif
6394#ifdef TARGET_NR_mlock
6395 case TARGET_NR_mlock:
6396 ret = get_errno(mlock(g2h(arg1), arg2));
6397 break;
6398#endif
6399#ifdef TARGET_NR_munlock
6400 case TARGET_NR_munlock:
6401 ret = get_errno(munlock(g2h(arg1), arg2));
6402 break;
6403#endif
6404#ifdef TARGET_NR_mlockall
6405 case TARGET_NR_mlockall:
6406 ret = get_errno(mlockall(arg1));
6407 break;
6408#endif
6409#ifdef TARGET_NR_munlockall
6410 case TARGET_NR_munlockall:
6411 ret = get_errno(munlockall());
6412 break;
6413#endif
6414 case TARGET_NR_truncate:
6415 if (!(p = lock_user_string(arg1)))
6416 goto efault;
6417 ret = get_errno(truncate(p, arg2));
6418 unlock_user(p, arg1, 0);
6419 break;
6420 case TARGET_NR_ftruncate:
6421 ret = get_errno(ftruncate(arg1, arg2));
6422 break;
6423 case TARGET_NR_fchmod:
6424 ret = get_errno(fchmod(arg1, arg2));
6425 break;
6426#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
6427 case TARGET_NR_fchmodat:
6428 if (!(p = lock_user_string(arg2)))
6429 goto efault;
6430 ret = get_errno(sys_fchmodat(arg1, p, arg3));
6431 unlock_user(p, arg2, 0);
6432 break;
6433#endif
6434 case TARGET_NR_getpriority:
6435
6436
6437
6438 ret = get_errno(sys_getpriority(arg1, arg2));
6439 break;
6440 case TARGET_NR_setpriority:
6441 ret = get_errno(setpriority(arg1, arg2, arg3));
6442 break;
6443#ifdef TARGET_NR_profil
6444 case TARGET_NR_profil:
6445 goto unimplemented;
6446#endif
6447 case TARGET_NR_statfs:
6448 if (!(p = lock_user_string(arg1)))
6449 goto efault;
6450 ret = get_errno(statfs(path(p), &stfs));
6451 unlock_user(p, arg1, 0);
6452 convert_statfs:
6453 if (!is_error(ret)) {
6454 struct target_statfs *target_stfs;
6455
6456 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
6457 goto efault;
6458 __put_user(stfs.f_type, &target_stfs->f_type);
6459 __put_user(stfs.f_bsize, &target_stfs->f_bsize);
6460 __put_user(stfs.f_blocks, &target_stfs->f_blocks);
6461 __put_user(stfs.f_bfree, &target_stfs->f_bfree);
6462 __put_user(stfs.f_bavail, &target_stfs->f_bavail);
6463 __put_user(stfs.f_files, &target_stfs->f_files);
6464 __put_user(stfs.f_ffree, &target_stfs->f_ffree);
6465 __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
6466 __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
6467 __put_user(stfs.f_namelen, &target_stfs->f_namelen);
6468 unlock_user_struct(target_stfs, arg2, 1);
6469 }
6470 break;
6471 case TARGET_NR_fstatfs:
6472 ret = get_errno(fstatfs(arg1, &stfs));
6473 goto convert_statfs;
6474#ifdef TARGET_NR_statfs64
6475 case TARGET_NR_statfs64:
6476 if (!(p = lock_user_string(arg1)))
6477 goto efault;
6478 ret = get_errno(statfs(path(p), &stfs));
6479 unlock_user(p, arg1, 0);
6480 convert_statfs64:
6481 if (!is_error(ret)) {
6482 struct target_statfs64 *target_stfs;
6483
6484 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
6485 goto efault;
6486 __put_user(stfs.f_type, &target_stfs->f_type);
6487 __put_user(stfs.f_bsize, &target_stfs->f_bsize);
6488 __put_user(stfs.f_blocks, &target_stfs->f_blocks);
6489 __put_user(stfs.f_bfree, &target_stfs->f_bfree);
6490 __put_user(stfs.f_bavail, &target_stfs->f_bavail);
6491 __put_user(stfs.f_files, &target_stfs->f_files);
6492 __put_user(stfs.f_ffree, &target_stfs->f_ffree);
6493 __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
6494 __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
6495 __put_user(stfs.f_namelen, &target_stfs->f_namelen);
6496 unlock_user_struct(target_stfs, arg3, 1);
6497 }
6498 break;
6499 case TARGET_NR_fstatfs64:
6500 ret = get_errno(fstatfs(arg1, &stfs));
6501 goto convert_statfs64;
6502#endif
6503#ifdef TARGET_NR_ioperm
6504 case TARGET_NR_ioperm:
6505 goto unimplemented;
6506#endif
6507#ifdef TARGET_NR_socketcall
6508 case TARGET_NR_socketcall:
6509 ret = do_socketcall(arg1, arg2);
6510 break;
6511#endif
6512#ifdef TARGET_NR_accept
6513 case TARGET_NR_accept:
6514 ret = do_accept(arg1, arg2, arg3);
6515 break;
6516#endif
6517#ifdef TARGET_NR_bind
6518 case TARGET_NR_bind:
6519 ret = do_bind(arg1, arg2, arg3);
6520 break;
6521#endif
6522#ifdef TARGET_NR_connect
6523 case TARGET_NR_connect:
6524 ret = do_connect(arg1, arg2, arg3);
6525 break;
6526#endif
6527#ifdef TARGET_NR_getpeername
6528 case TARGET_NR_getpeername:
6529 ret = do_getpeername(arg1, arg2, arg3);
6530 break;
6531#endif
6532#ifdef TARGET_NR_getsockname
6533 case TARGET_NR_getsockname:
6534 ret = do_getsockname(arg1, arg2, arg3);
6535 break;
6536#endif
6537#ifdef TARGET_NR_getsockopt
6538 case TARGET_NR_getsockopt:
6539 ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
6540 break;
6541#endif
6542#ifdef TARGET_NR_listen
6543 case TARGET_NR_listen:
6544 ret = get_errno(listen(arg1, arg2));
6545 break;
6546#endif
6547#ifdef TARGET_NR_recv
6548 case TARGET_NR_recv:
6549 ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
6550 break;
6551#endif
6552#ifdef TARGET_NR_recvfrom
6553 case TARGET_NR_recvfrom:
6554 ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
6555 break;
6556#endif
6557#ifdef TARGET_NR_recvmsg
6558 case TARGET_NR_recvmsg:
6559 ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
6560 break;
6561#endif
6562#ifdef TARGET_NR_send
6563 case TARGET_NR_send:
6564 ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
6565 break;
6566#endif
6567#ifdef TARGET_NR_sendmsg
6568 case TARGET_NR_sendmsg:
6569 ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
6570 break;
6571#endif
6572#ifdef TARGET_NR_sendto
6573 case TARGET_NR_sendto:
6574 ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
6575 break;
6576#endif
6577#ifdef TARGET_NR_shutdown
6578 case TARGET_NR_shutdown:
6579 ret = get_errno(shutdown(arg1, arg2));
6580 break;
6581#endif
6582#ifdef TARGET_NR_socket
6583 case TARGET_NR_socket:
6584 ret = do_socket(arg1, arg2, arg3);
6585 break;
6586#endif
6587#ifdef TARGET_NR_socketpair
6588 case TARGET_NR_socketpair:
6589 ret = do_socketpair(arg1, arg2, arg3, arg4);
6590 break;
6591#endif
6592#ifdef TARGET_NR_setsockopt
6593 case TARGET_NR_setsockopt:
6594 ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
6595 break;
6596#endif
6597
6598 case TARGET_NR_syslog:
6599 if (!(p = lock_user_string(arg2)))
6600 goto efault;
6601 ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
6602 unlock_user(p, arg2, 0);
6603 break;
6604
6605 case TARGET_NR_setitimer:
6606 {
6607 struct itimerval value, ovalue, *pvalue;
6608
6609 if (arg2) {
6610 pvalue = &value;
6611 if (copy_from_user_timeval(&pvalue->it_interval, arg2)
6612 || copy_from_user_timeval(&pvalue->it_value,
6613 arg2 + sizeof(struct target_timeval)))
6614 goto efault;
6615 } else {
6616 pvalue = NULL;
6617 }
6618 ret = get_errno(setitimer(arg1, pvalue, &ovalue));
6619 if (!is_error(ret) && arg3) {
6620 if (copy_to_user_timeval(arg3,
6621 &ovalue.it_interval)
6622 || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
6623 &ovalue.it_value))
6624 goto efault;
6625 }
6626 }
6627 break;
6628 case TARGET_NR_getitimer:
6629 {
6630 struct itimerval value;
6631
6632 ret = get_errno(getitimer(arg1, &value));
6633 if (!is_error(ret) && arg2) {
6634 if (copy_to_user_timeval(arg2,
6635 &value.it_interval)
6636 || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
6637 &value.it_value))
6638 goto efault;
6639 }
6640 }
6641 break;
6642 case TARGET_NR_stat:
6643 if (!(p = lock_user_string(arg1)))
6644 goto efault;
6645 ret = get_errno(stat(path(p), &st));
6646 unlock_user(p, arg1, 0);
6647 goto do_stat;
6648 case TARGET_NR_lstat:
6649 if (!(p = lock_user_string(arg1)))
6650 goto efault;
6651 ret = get_errno(lstat(path(p), &st));
6652 unlock_user(p, arg1, 0);
6653 goto do_stat;
6654 case TARGET_NR_fstat:
6655 {
6656 ret = get_errno(fstat(arg1, &st));
6657 do_stat:
6658 if (!is_error(ret)) {
6659 struct target_stat *target_st;
6660
6661 if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
6662 goto efault;
6663 memset(target_st, 0, sizeof(*target_st));
6664 __put_user(st.st_dev, &target_st->st_dev);
6665 __put_user(st.st_ino, &target_st->st_ino);
6666 __put_user(st.st_mode, &target_st->st_mode);
6667 __put_user(st.st_uid, &target_st->st_uid);
6668 __put_user(st.st_gid, &target_st->st_gid);
6669 __put_user(st.st_nlink, &target_st->st_nlink);
6670 __put_user(st.st_rdev, &target_st->st_rdev);
6671 __put_user(st.st_size, &target_st->st_size);
6672 __put_user(st.st_blksize, &target_st->st_blksize);
6673 __put_user(st.st_blocks, &target_st->st_blocks);
6674 __put_user(st.st_atime, &target_st->target_st_atime);
6675 __put_user(st.st_mtime, &target_st->target_st_mtime);
6676 __put_user(st.st_ctime, &target_st->target_st_ctime);
6677 unlock_user_struct(target_st, arg2, 1);
6678 }
6679 }
6680 break;
6681#ifdef TARGET_NR_olduname
6682 case TARGET_NR_olduname:
6683 goto unimplemented;
6684#endif
6685#ifdef TARGET_NR_iopl
6686 case TARGET_NR_iopl:
6687 goto unimplemented;
6688#endif
6689 case TARGET_NR_vhangup:
6690 ret = get_errno(vhangup());
6691 break;
6692#ifdef TARGET_NR_idle
6693 case TARGET_NR_idle:
6694 goto unimplemented;
6695#endif
6696#ifdef TARGET_NR_syscall
6697 case TARGET_NR_syscall:
6698 ret = do_syscall(cpu_env, arg1 & 0xffff, arg2, arg3, arg4, arg5,
6699 arg6, arg7, arg8, 0);
6700 break;
6701#endif
6702 case TARGET_NR_wait4:
6703 {
6704 int status;
6705 abi_long status_ptr = arg2;
6706 struct rusage rusage, *rusage_ptr;
6707 abi_ulong target_rusage = arg4;
6708 if (target_rusage)
6709 rusage_ptr = &rusage;
6710 else
6711 rusage_ptr = NULL;
6712 ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
6713 if (!is_error(ret)) {
6714 if (status_ptr && ret) {
6715 status = host_to_target_waitstatus(status);
6716 if (put_user_s32(status, status_ptr))
6717 goto efault;
6718 }
6719 if (target_rusage)
6720 host_to_target_rusage(target_rusage, &rusage);
6721 }
6722 }
6723 break;
6724#ifdef TARGET_NR_swapoff
6725 case TARGET_NR_swapoff:
6726 if (!(p = lock_user_string(arg1)))
6727 goto efault;
6728 ret = get_errno(swapoff(p));
6729 unlock_user(p, arg1, 0);
6730 break;
6731#endif
6732 case TARGET_NR_sysinfo:
6733 {
6734 struct target_sysinfo *target_value;
6735 struct sysinfo value;
6736 ret = get_errno(sysinfo(&value));
6737 if (!is_error(ret) && arg1)
6738 {
6739 if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
6740 goto efault;
6741 __put_user(value.uptime, &target_value->uptime);
6742 __put_user(value.loads[0], &target_value->loads[0]);
6743 __put_user(value.loads[1], &target_value->loads[1]);
6744 __put_user(value.loads[2], &target_value->loads[2]);
6745 __put_user(value.totalram, &target_value->totalram);
6746 __put_user(value.freeram, &target_value->freeram);
6747 __put_user(value.sharedram, &target_value->sharedram);
6748 __put_user(value.bufferram, &target_value->bufferram);
6749 __put_user(value.totalswap, &target_value->totalswap);
6750 __put_user(value.freeswap, &target_value->freeswap);
6751 __put_user(value.procs, &target_value->procs);
6752 __put_user(value.totalhigh, &target_value->totalhigh);
6753 __put_user(value.freehigh, &target_value->freehigh);
6754 __put_user(value.mem_unit, &target_value->mem_unit);
6755 unlock_user_struct(target_value, arg1, 1);
6756 }
6757 }
6758 break;
6759#ifdef TARGET_NR_ipc
6760 case TARGET_NR_ipc:
6761 ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
6762 break;
6763#endif
6764#ifdef TARGET_NR_semget
6765 case TARGET_NR_semget:
6766 ret = get_errno(semget(arg1, arg2, arg3));
6767 break;
6768#endif
6769#ifdef TARGET_NR_semop
6770 case TARGET_NR_semop:
6771 ret = get_errno(do_semop(arg1, arg2, arg3));
6772 break;
6773#endif
6774#ifdef TARGET_NR_semctl
6775 case TARGET_NR_semctl:
6776 ret = do_semctl(arg1, arg2, arg3, (union target_semun)(abi_ulong)arg4);
6777 break;
6778#endif
6779#ifdef TARGET_NR_msgctl
6780 case TARGET_NR_msgctl:
6781 ret = do_msgctl(arg1, arg2, arg3);
6782 break;
6783#endif
6784#ifdef TARGET_NR_msgget
6785 case TARGET_NR_msgget:
6786 ret = get_errno(msgget(arg1, arg2));
6787 break;
6788#endif
6789#ifdef TARGET_NR_msgrcv
6790 case TARGET_NR_msgrcv:
6791 ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
6792 break;
6793#endif
6794#ifdef TARGET_NR_msgsnd
6795 case TARGET_NR_msgsnd:
6796 ret = do_msgsnd(arg1, arg2, arg3, arg4);
6797 break;
6798#endif
6799#ifdef TARGET_NR_shmget
6800 case TARGET_NR_shmget:
6801 ret = get_errno(shmget(arg1, arg2, arg3));
6802 break;
6803#endif
6804#ifdef TARGET_NR_shmctl
6805 case TARGET_NR_shmctl:
6806 ret = do_shmctl(arg1, arg2, arg3);
6807 break;
6808#endif
6809#ifdef TARGET_NR_shmat
6810 case TARGET_NR_shmat:
6811 ret = do_shmat(arg1, arg2, arg3);
6812 break;
6813#endif
6814#ifdef TARGET_NR_shmdt
6815 case TARGET_NR_shmdt:
6816 ret = do_shmdt(arg1);
6817 break;
6818#endif
6819 case TARGET_NR_fsync:
6820 ret = get_errno(fsync(arg1));
6821 break;
6822 case TARGET_NR_clone:
6823#if defined(TARGET_SH4) || defined(TARGET_ALPHA)
6824 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
6825#elif defined(TARGET_CRIS)
6826 ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg4, arg5));
6827#elif defined(TARGET_S390X)
6828 ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg5, arg4));
6829#else
6830 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
6831#endif
6832 break;
6833#ifdef __NR_exit_group
6834
6835 case TARGET_NR_exit_group:
6836#ifdef TARGET_GPROF
6837 _mcleanup();
6838#endif
6839 gdb_exit(cpu_env, arg1);
6840 ret = get_errno(exit_group(arg1));
6841 break;
6842#endif
6843 case TARGET_NR_setdomainname:
6844 if (!(p = lock_user_string(arg1)))
6845 goto efault;
6846 ret = get_errno(setdomainname(p, arg2));
6847 unlock_user(p, arg1, 0);
6848 break;
6849 case TARGET_NR_uname:
6850
6851 {
6852 struct new_utsname * buf;
6853
6854 if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
6855 goto efault;
6856 ret = get_errno(sys_uname(buf));
6857 if (!is_error(ret)) {
6858
6859
6860 strcpy (buf->machine, cpu_to_uname_machine(cpu_env));
6861
6862 if (qemu_uname_release && *qemu_uname_release)
6863 strcpy (buf->release, qemu_uname_release);
6864 }
6865 unlock_user_struct(buf, arg1, 1);
6866 }
6867 break;
6868#ifdef TARGET_I386
6869 case TARGET_NR_modify_ldt:
6870 ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
6871 break;
6872#if !defined(TARGET_X86_64)
6873 case TARGET_NR_vm86old:
6874 goto unimplemented;
6875 case TARGET_NR_vm86:
6876 ret = do_vm86(cpu_env, arg1, arg2);
6877 break;
6878#endif
6879#endif
6880 case TARGET_NR_adjtimex:
6881 goto unimplemented;
6882#ifdef TARGET_NR_create_module
6883 case TARGET_NR_create_module:
6884#endif
6885 case TARGET_NR_init_module:
6886 case TARGET_NR_delete_module:
6887#ifdef TARGET_NR_get_kernel_syms
6888 case TARGET_NR_get_kernel_syms:
6889#endif
6890 goto unimplemented;
6891 case TARGET_NR_quotactl:
6892 goto unimplemented;
6893 case TARGET_NR_getpgid:
6894 ret = get_errno(getpgid(arg1));
6895 break;
6896 case TARGET_NR_fchdir:
6897 ret = get_errno(fchdir(arg1));
6898 break;
6899#ifdef TARGET_NR_bdflush
6900 case TARGET_NR_bdflush:
6901 goto unimplemented;
6902#endif
6903#ifdef TARGET_NR_sysfs
6904 case TARGET_NR_sysfs:
6905 goto unimplemented;
6906#endif
6907 case TARGET_NR_personality:
6908 ret = get_errno(personality(arg1));
6909 break;
6910#ifdef TARGET_NR_afs_syscall
6911 case TARGET_NR_afs_syscall:
6912 goto unimplemented;
6913#endif
6914#ifdef TARGET_NR__llseek
6915 case TARGET_NR__llseek:
6916 {
6917 int64_t res;
6918#if !defined(__NR_llseek)
6919 res = lseek(arg1, ((uint64_t)arg2 << 32) | arg3, arg5);
6920 if (res == -1) {
6921 ret = get_errno(res);
6922 } else {
6923 ret = 0;
6924 }
6925#else
6926 ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
6927#endif
6928 if ((ret == 0) && put_user_s64(res, arg4)) {
6929 goto efault;
6930 }
6931 }
6932 break;
6933#endif
6934 case TARGET_NR_getdents:
6935#if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
6936 {
6937 struct target_dirent *target_dirp;
6938 struct linux_dirent *dirp;
6939 abi_long count = arg3;
6940
6941 dirp = malloc(count);
6942 if (!dirp) {
6943 ret = -TARGET_ENOMEM;
6944 goto fail;
6945 }
6946
6947 ret = get_errno(sys_getdents(arg1, dirp, count));
6948 if (!is_error(ret)) {
6949 struct linux_dirent *de;
6950 struct target_dirent *tde;
6951 int len = ret;
6952 int reclen, treclen;
6953 int count1, tnamelen;
6954
6955 count1 = 0;
6956 de = dirp;
6957 if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
6958 goto efault;
6959 tde = target_dirp;
6960 while (len > 0) {
6961 reclen = de->d_reclen;
6962 treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
6963 tde->d_reclen = tswap16(treclen);
6964 tde->d_ino = tswapal(de->d_ino);
6965 tde->d_off = tswapal(de->d_off);
6966 tnamelen = treclen - (2 * sizeof(abi_long) + 2);
6967 if (tnamelen > 256)
6968 tnamelen = 256;
6969
6970 pstrcpy(tde->d_name, tnamelen, de->d_name);
6971 de = (struct linux_dirent *)((char *)de + reclen);
6972 len -= reclen;
6973 tde = (struct target_dirent *)((char *)tde + treclen);
6974 count1 += treclen;
6975 }
6976 ret = count1;
6977 unlock_user(target_dirp, arg2, ret);
6978 }
6979 free(dirp);
6980 }
6981#else
6982 {
6983 struct linux_dirent *dirp;
6984 abi_long count = arg3;
6985
6986 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
6987 goto efault;
6988 ret = get_errno(sys_getdents(arg1, dirp, count));
6989 if (!is_error(ret)) {
6990 struct linux_dirent *de;
6991 int len = ret;
6992 int reclen;
6993 de = dirp;
6994 while (len > 0) {
6995 reclen = de->d_reclen;
6996 if (reclen > len)
6997 break;
6998 de->d_reclen = tswap16(reclen);
6999 tswapls(&de->d_ino);
7000 tswapls(&de->d_off);
7001 de = (struct linux_dirent *)((char *)de + reclen);
7002 len -= reclen;
7003 }
7004 }
7005 unlock_user(dirp, arg2, ret);
7006 }
7007#endif
7008 break;
7009#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
7010 case TARGET_NR_getdents64:
7011 {
7012 struct linux_dirent64 *dirp;
7013 abi_long count = arg3;
7014 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
7015 goto efault;
7016 ret = get_errno(sys_getdents64(arg1, dirp, count));
7017 if (!is_error(ret)) {
7018 struct linux_dirent64 *de;
7019 int len = ret;
7020 int reclen;
7021 de = dirp;
7022 while (len > 0) {
7023 reclen = de->d_reclen;
7024 if (reclen > len)
7025 break;
7026 de->d_reclen = tswap16(reclen);
7027 tswap64s((uint64_t *)&de->d_ino);
7028 tswap64s((uint64_t *)&de->d_off);
7029 de = (struct linux_dirent64 *)((char *)de + reclen);
7030 len -= reclen;
7031 }
7032 }
7033 unlock_user(dirp, arg2, ret);
7034 }
7035 break;
7036#endif
7037#if defined(TARGET_NR__newselect) || defined(TARGET_S390X)
7038#ifdef TARGET_S390X
7039 case TARGET_NR_select:
7040#else
7041 case TARGET_NR__newselect:
7042#endif
7043 ret = do_select(arg1, arg2, arg3, arg4, arg5);
7044 break;
7045#endif
7046#if defined(TARGET_NR_poll) || defined(TARGET_NR_ppoll)
7047# ifdef TARGET_NR_poll
7048 case TARGET_NR_poll:
7049# endif
7050# ifdef TARGET_NR_ppoll
7051 case TARGET_NR_ppoll:
7052# endif
7053 {
7054 struct target_pollfd *target_pfd;
7055 unsigned int nfds = arg2;
7056 int timeout = arg3;
7057 struct pollfd *pfd;
7058 unsigned int i;
7059
7060 target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
7061 if (!target_pfd)
7062 goto efault;
7063
7064 pfd = alloca(sizeof(struct pollfd) * nfds);
7065 for(i = 0; i < nfds; i++) {
7066 pfd[i].fd = tswap32(target_pfd[i].fd);
7067 pfd[i].events = tswap16(target_pfd[i].events);
7068 }
7069
7070# ifdef TARGET_NR_ppoll
7071 if (num == TARGET_NR_ppoll) {
7072 struct timespec _timeout_ts, *timeout_ts = &_timeout_ts;
7073 target_sigset_t *target_set;
7074 sigset_t _set, *set = &_set;
7075
7076 if (arg3) {
7077 if (target_to_host_timespec(timeout_ts, arg3)) {
7078 unlock_user(target_pfd, arg1, 0);
7079 goto efault;
7080 }
7081 } else {
7082 timeout_ts = NULL;
7083 }
7084
7085 if (arg4) {
7086 target_set = lock_user(VERIFY_READ, arg4, sizeof(target_sigset_t), 1);
7087 if (!target_set) {
7088 unlock_user(target_pfd, arg1, 0);
7089 goto efault;
7090 }
7091 target_to_host_sigset(set, target_set);
7092 } else {
7093 set = NULL;
7094 }
7095
7096 ret = get_errno(sys_ppoll(pfd, nfds, timeout_ts, set, _NSIG/8));
7097
7098 if (!is_error(ret) && arg3) {
7099 host_to_target_timespec(arg3, timeout_ts);
7100 }
7101 if (arg4) {
7102 unlock_user(target_set, arg4, 0);
7103 }
7104 } else
7105# endif
7106 ret = get_errno(poll(pfd, nfds, timeout));
7107
7108 if (!is_error(ret)) {
7109 for(i = 0; i < nfds; i++) {
7110 target_pfd[i].revents = tswap16(pfd[i].revents);
7111 }
7112 }
7113 unlock_user(target_pfd, arg1, sizeof(struct target_pollfd) * nfds);
7114 }
7115 break;
7116#endif
7117 case TARGET_NR_flock:
7118
7119
7120 ret = get_errno(flock(arg1, arg2));
7121 break;
7122 case TARGET_NR_readv:
7123 {
7124 int count = arg3;
7125 struct iovec *vec;
7126
7127 vec = alloca(count * sizeof(struct iovec));
7128 if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
7129 goto efault;
7130 ret = get_errno(readv(arg1, vec, count));
7131 unlock_iovec(vec, arg2, count, 1);
7132 }
7133 break;
7134 case TARGET_NR_writev:
7135 {
7136 int count = arg3;
7137 struct iovec *vec;
7138
7139 vec = alloca(count * sizeof(struct iovec));
7140 if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
7141 goto efault;
7142 ret = get_errno(writev(arg1, vec, count));
7143 unlock_iovec(vec, arg2, count, 0);
7144 }
7145 break;
7146 case TARGET_NR_getsid:
7147 ret = get_errno(getsid(arg1));
7148 break;
7149#if defined(TARGET_NR_fdatasync)
7150 case TARGET_NR_fdatasync:
7151 ret = get_errno(fdatasync(arg1));
7152 break;
7153#endif
7154 case TARGET_NR__sysctl:
7155
7156
7157 ret = -TARGET_ENOTDIR;
7158 break;
7159 case TARGET_NR_sched_getaffinity:
7160 {
7161 unsigned int mask_size;
7162 unsigned long *mask;
7163
7164
7165
7166
7167
7168 if (arg2 & (sizeof(abi_ulong) - 1)) {
7169 ret = -TARGET_EINVAL;
7170 break;
7171 }
7172 mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
7173
7174 mask = alloca(mask_size);
7175 ret = get_errno(sys_sched_getaffinity(arg1, mask_size, mask));
7176
7177 if (!is_error(ret)) {
7178 if (copy_to_user(arg3, mask, ret)) {
7179 goto efault;
7180 }
7181 }
7182 }
7183 break;
7184 case TARGET_NR_sched_setaffinity:
7185 {
7186 unsigned int mask_size;
7187 unsigned long *mask;
7188
7189
7190
7191
7192
7193 if (arg2 & (sizeof(abi_ulong) - 1)) {
7194 ret = -TARGET_EINVAL;
7195 break;
7196 }
7197 mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
7198
7199 mask = alloca(mask_size);
7200 if (!lock_user_struct(VERIFY_READ, p, arg3, 1)) {
7201 goto efault;
7202 }
7203 memcpy(mask, p, arg2);
7204 unlock_user_struct(p, arg2, 0);
7205
7206 ret = get_errno(sys_sched_setaffinity(arg1, mask_size, mask));
7207 }
7208 break;
7209 case TARGET_NR_sched_setparam:
7210 {
7211 struct sched_param *target_schp;
7212 struct sched_param schp;
7213
7214 if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
7215 goto efault;
7216 schp.sched_priority = tswap32(target_schp->sched_priority);
7217 unlock_user_struct(target_schp, arg2, 0);
7218 ret = get_errno(sched_setparam(arg1, &schp));
7219 }
7220 break;
7221 case TARGET_NR_sched_getparam:
7222 {
7223 struct sched_param *target_schp;
7224 struct sched_param schp;
7225 ret = get_errno(sched_getparam(arg1, &schp));
7226 if (!is_error(ret)) {
7227 if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
7228 goto efault;
7229 target_schp->sched_priority = tswap32(schp.sched_priority);
7230 unlock_user_struct(target_schp, arg2, 1);
7231 }
7232 }
7233 break;
7234 case TARGET_NR_sched_setscheduler:
7235 {
7236 struct sched_param *target_schp;
7237 struct sched_param schp;
7238 if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
7239 goto efault;
7240 schp.sched_priority = tswap32(target_schp->sched_priority);
7241 unlock_user_struct(target_schp, arg3, 0);
7242 ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
7243 }
7244 break;
7245 case TARGET_NR_sched_getscheduler:
7246 ret = get_errno(sched_getscheduler(arg1));
7247 break;
7248 case TARGET_NR_sched_yield:
7249 ret = get_errno(sched_yield());
7250 break;
7251 case TARGET_NR_sched_get_priority_max:
7252 ret = get_errno(sched_get_priority_max(arg1));
7253 break;
7254 case TARGET_NR_sched_get_priority_min:
7255 ret = get_errno(sched_get_priority_min(arg1));
7256 break;
7257 case TARGET_NR_sched_rr_get_interval:
7258 {
7259 struct timespec ts;
7260 ret = get_errno(sched_rr_get_interval(arg1, &ts));
7261 if (!is_error(ret)) {
7262 host_to_target_timespec(arg2, &ts);
7263 }
7264 }
7265 break;
7266 case TARGET_NR_nanosleep:
7267 {
7268 struct timespec req, rem;
7269 target_to_host_timespec(&req, arg1);
7270 ret = get_errno(nanosleep(&req, &rem));
7271 if (is_error(ret) && arg2) {
7272 host_to_target_timespec(arg2, &rem);
7273 }
7274 }
7275 break;
7276#ifdef TARGET_NR_query_module
7277 case TARGET_NR_query_module:
7278 goto unimplemented;
7279#endif
7280#ifdef TARGET_NR_nfsservctl
7281 case TARGET_NR_nfsservctl:
7282 goto unimplemented;
7283#endif
7284 case TARGET_NR_prctl:
7285 switch (arg1) {
7286 case PR_GET_PDEATHSIG:
7287 {
7288 int deathsig;
7289 ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
7290 if (!is_error(ret) && arg2
7291 && put_user_ual(deathsig, arg2)) {
7292 goto efault;
7293 }
7294 break;
7295 }
7296#ifdef PR_GET_NAME
7297 case PR_GET_NAME:
7298 {
7299 void *name = lock_user(VERIFY_WRITE, arg2, 16, 1);
7300 if (!name) {
7301 goto efault;
7302 }
7303 ret = get_errno(prctl(arg1, (unsigned long)name,
7304 arg3, arg4, arg5));
7305 unlock_user(name, arg2, 16);
7306 break;
7307 }
7308 case PR_SET_NAME:
7309 {
7310 void *name = lock_user(VERIFY_READ, arg2, 16, 1);
7311 if (!name) {
7312 goto efault;
7313 }
7314 ret = get_errno(prctl(arg1, (unsigned long)name,
7315 arg3, arg4, arg5));
7316 unlock_user(name, arg2, 0);
7317 break;
7318 }
7319#endif
7320 default:
7321
7322 ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
7323 break;
7324 }
7325 break;
7326#ifdef TARGET_NR_arch_prctl
7327 case TARGET_NR_arch_prctl:
7328#if defined(TARGET_I386) && !defined(TARGET_ABI32)
7329 ret = do_arch_prctl(cpu_env, arg1, arg2);
7330 break;
7331#else
7332 goto unimplemented;
7333#endif
7334#endif
7335#ifdef TARGET_NR_pread
7336 case TARGET_NR_pread:
7337 if (regpairs_aligned(cpu_env))
7338 arg4 = arg5;
7339 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
7340 goto efault;
7341 ret = get_errno(pread(arg1, p, arg3, arg4));
7342 unlock_user(p, arg2, ret);
7343 break;
7344 case TARGET_NR_pwrite:
7345 if (regpairs_aligned(cpu_env))
7346 arg4 = arg5;
7347 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
7348 goto efault;
7349 ret = get_errno(pwrite(arg1, p, arg3, arg4));
7350 unlock_user(p, arg2, 0);
7351 break;
7352#endif
7353#ifdef TARGET_NR_pread64
7354 case TARGET_NR_pread64:
7355 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
7356 goto efault;
7357 ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
7358 unlock_user(p, arg2, ret);
7359 break;
7360 case TARGET_NR_pwrite64:
7361 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
7362 goto efault;
7363 ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
7364 unlock_user(p, arg2, 0);
7365 break;
7366#endif
7367 case TARGET_NR_getcwd:
7368 if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
7369 goto efault;
7370 ret = get_errno(sys_getcwd1(p, arg2));
7371 unlock_user(p, arg1, ret);
7372 break;
7373 case TARGET_NR_capget:
7374 goto unimplemented;
7375 case TARGET_NR_capset:
7376 goto unimplemented;
7377 case TARGET_NR_sigaltstack:
7378#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
7379 defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA) || \
7380 defined(TARGET_M68K) || defined(TARGET_S390X)
7381 ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUArchState *)cpu_env));
7382 break;
7383#else
7384 goto unimplemented;
7385#endif
7386 case TARGET_NR_sendfile:
7387 goto unimplemented;
7388#ifdef TARGET_NR_getpmsg
7389 case TARGET_NR_getpmsg:
7390 goto unimplemented;
7391#endif
7392#ifdef TARGET_NR_putpmsg
7393 case TARGET_NR_putpmsg:
7394 goto unimplemented;
7395#endif
7396#ifdef TARGET_NR_vfork
7397 case TARGET_NR_vfork:
7398 ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
7399 0, 0, 0, 0));
7400 break;
7401#endif
7402#ifdef TARGET_NR_ugetrlimit
7403 case TARGET_NR_ugetrlimit:
7404 {
7405 struct rlimit rlim;
7406 int resource = target_to_host_resource(arg1);
7407 ret = get_errno(getrlimit(resource, &rlim));
7408 if (!is_error(ret)) {
7409 struct target_rlimit *target_rlim;
7410 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
7411 goto efault;
7412 target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
7413 target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
7414 unlock_user_struct(target_rlim, arg2, 1);
7415 }
7416 break;
7417 }
7418#endif
7419#ifdef TARGET_NR_truncate64
7420 case TARGET_NR_truncate64:
7421 if (!(p = lock_user_string(arg1)))
7422 goto efault;
7423 ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
7424 unlock_user(p, arg1, 0);
7425 break;
7426#endif
7427#ifdef TARGET_NR_ftruncate64
7428 case TARGET_NR_ftruncate64:
7429 ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
7430 break;
7431#endif
7432#ifdef TARGET_NR_stat64
7433 case TARGET_NR_stat64:
7434 if (!(p = lock_user_string(arg1)))
7435 goto efault;
7436 ret = get_errno(stat(path(p), &st));
7437 unlock_user(p, arg1, 0);
7438 if (!is_error(ret))
7439 ret = host_to_target_stat64(cpu_env, arg2, &st);
7440 break;
7441#endif
7442#ifdef TARGET_NR_lstat64
7443 case TARGET_NR_lstat64:
7444 if (!(p = lock_user_string(arg1)))
7445 goto efault;
7446 ret = get_errno(lstat(path(p), &st));
7447 unlock_user(p, arg1, 0);
7448 if (!is_error(ret))
7449 ret = host_to_target_stat64(cpu_env, arg2, &st);
7450 break;
7451#endif
7452#ifdef TARGET_NR_fstat64
7453 case TARGET_NR_fstat64:
7454 ret = get_errno(fstat(arg1, &st));
7455 if (!is_error(ret))
7456 ret = host_to_target_stat64(cpu_env, arg2, &st);
7457 break;
7458#endif
7459#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
7460 (defined(__NR_fstatat64) || defined(__NR_newfstatat))
7461#ifdef TARGET_NR_fstatat64
7462 case TARGET_NR_fstatat64:
7463#endif
7464#ifdef TARGET_NR_newfstatat
7465 case TARGET_NR_newfstatat:
7466#endif
7467 if (!(p = lock_user_string(arg2)))
7468 goto efault;
7469#ifdef __NR_fstatat64
7470 ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
7471#else
7472 ret = get_errno(sys_newfstatat(arg1, path(p), &st, arg4));
7473#endif
7474 if (!is_error(ret))
7475 ret = host_to_target_stat64(cpu_env, arg3, &st);
7476 break;
7477#endif
7478 case TARGET_NR_lchown:
7479 if (!(p = lock_user_string(arg1)))
7480 goto efault;
7481 ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
7482 unlock_user(p, arg1, 0);
7483 break;
7484#ifdef TARGET_NR_getuid
7485 case TARGET_NR_getuid:
7486 ret = get_errno(high2lowuid(getuid()));
7487 break;
7488#endif
7489#ifdef TARGET_NR_getgid
7490 case TARGET_NR_getgid:
7491 ret = get_errno(high2lowgid(getgid()));
7492 break;
7493#endif
7494#ifdef TARGET_NR_geteuid
7495 case TARGET_NR_geteuid:
7496 ret = get_errno(high2lowuid(geteuid()));
7497 break;
7498#endif
7499#ifdef TARGET_NR_getegid
7500 case TARGET_NR_getegid:
7501 ret = get_errno(high2lowgid(getegid()));
7502 break;
7503#endif
7504 case TARGET_NR_setreuid:
7505 ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
7506 break;
7507 case TARGET_NR_setregid:
7508 ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
7509 break;
7510 case TARGET_NR_getgroups:
7511 {
7512 int gidsetsize = arg1;
7513 target_id *target_grouplist;
7514 gid_t *grouplist;
7515 int i;
7516
7517 grouplist = alloca(gidsetsize * sizeof(gid_t));
7518 ret = get_errno(getgroups(gidsetsize, grouplist));
7519 if (gidsetsize == 0)
7520 break;
7521 if (!is_error(ret)) {
7522 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
7523 if (!target_grouplist)
7524 goto efault;
7525 for(i = 0;i < ret; i++)
7526 target_grouplist[i] = tswapid(high2lowgid(grouplist[i]));
7527 unlock_user(target_grouplist, arg2, gidsetsize * 2);
7528 }
7529 }
7530 break;
7531 case TARGET_NR_setgroups:
7532 {
7533 int gidsetsize = arg1;
7534 target_id *target_grouplist;
7535 gid_t *grouplist;
7536 int i;
7537
7538 grouplist = alloca(gidsetsize * sizeof(gid_t));
7539 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
7540 if (!target_grouplist) {
7541 ret = -TARGET_EFAULT;
7542 goto fail;
7543 }
7544 for(i = 0;i < gidsetsize; i++)
7545 grouplist[i] = low2highgid(tswapid(target_grouplist[i]));
7546 unlock_user(target_grouplist, arg2, 0);
7547 ret = get_errno(setgroups(gidsetsize, grouplist));
7548 }
7549 break;
7550 case TARGET_NR_fchown:
7551 ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
7552 break;
7553#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
7554 case TARGET_NR_fchownat:
7555 if (!(p = lock_user_string(arg2)))
7556 goto efault;
7557 ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
7558 unlock_user(p, arg2, 0);
7559 break;
7560#endif
7561#ifdef TARGET_NR_setresuid
7562 case TARGET_NR_setresuid:
7563 ret = get_errno(setresuid(low2highuid(arg1),
7564 low2highuid(arg2),
7565 low2highuid(arg3)));
7566 break;
7567#endif
7568#ifdef TARGET_NR_getresuid
7569 case TARGET_NR_getresuid:
7570 {
7571 uid_t ruid, euid, suid;
7572 ret = get_errno(getresuid(&ruid, &euid, &suid));
7573 if (!is_error(ret)) {
7574 if (put_user_u16(high2lowuid(ruid), arg1)
7575 || put_user_u16(high2lowuid(euid), arg2)
7576 || put_user_u16(high2lowuid(suid), arg3))
7577 goto efault;
7578 }
7579 }
7580 break;
7581#endif
7582#ifdef TARGET_NR_getresgid
7583 case TARGET_NR_setresgid:
7584 ret = get_errno(setresgid(low2highgid(arg1),
7585 low2highgid(arg2),
7586 low2highgid(arg3)));
7587 break;
7588#endif
7589#ifdef TARGET_NR_getresgid
7590 case TARGET_NR_getresgid:
7591 {
7592 gid_t rgid, egid, sgid;
7593 ret = get_errno(getresgid(&rgid, &egid, &sgid));
7594 if (!is_error(ret)) {
7595 if (put_user_u16(high2lowgid(rgid), arg1)
7596 || put_user_u16(high2lowgid(egid), arg2)
7597 || put_user_u16(high2lowgid(sgid), arg3))
7598 goto efault;
7599 }
7600 }
7601 break;
7602#endif
7603 case TARGET_NR_chown:
7604 if (!(p = lock_user_string(arg1)))
7605 goto efault;
7606 ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
7607 unlock_user(p, arg1, 0);
7608 break;
7609 case TARGET_NR_setuid:
7610 ret = get_errno(setuid(low2highuid(arg1)));
7611 break;
7612 case TARGET_NR_setgid:
7613 ret = get_errno(setgid(low2highgid(arg1)));
7614 break;
7615 case TARGET_NR_setfsuid:
7616 ret = get_errno(setfsuid(arg1));
7617 break;
7618 case TARGET_NR_setfsgid:
7619 ret = get_errno(setfsgid(arg1));
7620 break;
7621
7622#ifdef TARGET_NR_lchown32
7623 case TARGET_NR_lchown32:
7624 if (!(p = lock_user_string(arg1)))
7625 goto efault;
7626 ret = get_errno(lchown(p, arg2, arg3));
7627 unlock_user(p, arg1, 0);
7628 break;
7629#endif
7630#ifdef TARGET_NR_getuid32
7631 case TARGET_NR_getuid32:
7632 ret = get_errno(getuid());
7633 break;
7634#endif
7635
7636#if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
7637
7638 case TARGET_NR_getxuid:
7639 {
7640 uid_t euid;
7641 euid=geteuid();
7642 ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
7643 }
7644 ret = get_errno(getuid());
7645 break;
7646#endif
7647#if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
7648
7649 case TARGET_NR_getxgid:
7650 {
7651 uid_t egid;
7652 egid=getegid();
7653 ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
7654 }
7655 ret = get_errno(getgid());
7656 break;
7657#endif
7658#if defined(TARGET_NR_osf_getsysinfo) && defined(TARGET_ALPHA)
7659
7660 case TARGET_NR_osf_getsysinfo:
7661 ret = -TARGET_EOPNOTSUPP;
7662 switch (arg1) {
7663 case TARGET_GSI_IEEE_FP_CONTROL:
7664 {
7665 uint64_t swcr, fpcr = cpu_alpha_load_fpcr (cpu_env);
7666
7667
7668 swcr = (fpcr >> 35) & SWCR_STATUS_MASK;
7669 swcr |= (fpcr >> 36) & SWCR_MAP_DMZ;
7670 swcr |= (~fpcr >> 48) & (SWCR_TRAP_ENABLE_INV
7671 | SWCR_TRAP_ENABLE_DZE
7672 | SWCR_TRAP_ENABLE_OVF);
7673 swcr |= (~fpcr >> 57) & (SWCR_TRAP_ENABLE_UNF
7674 | SWCR_TRAP_ENABLE_INE);
7675 swcr |= (fpcr >> 47) & SWCR_MAP_UMZ;
7676 swcr |= (~fpcr >> 41) & SWCR_TRAP_ENABLE_DNO;
7677
7678 if (put_user_u64 (swcr, arg2))
7679 goto efault;
7680 ret = 0;
7681 }
7682 break;
7683
7684
7685
7686
7687
7688
7689
7690
7691
7692
7693 }
7694 break;
7695#endif
7696#if defined(TARGET_NR_osf_setsysinfo) && defined(TARGET_ALPHA)
7697
7698 case TARGET_NR_osf_setsysinfo:
7699 ret = -TARGET_EOPNOTSUPP;
7700 switch (arg1) {
7701 case TARGET_SSI_IEEE_FP_CONTROL:
7702 case TARGET_SSI_IEEE_RAISE_EXCEPTION:
7703 {
7704 uint64_t swcr, fpcr, orig_fpcr;
7705
7706 if (get_user_u64 (swcr, arg2))
7707 goto efault;
7708 orig_fpcr = cpu_alpha_load_fpcr (cpu_env);
7709 fpcr = orig_fpcr & FPCR_DYN_MASK;
7710
7711
7712 fpcr |= (swcr & SWCR_STATUS_MASK) << 35;
7713 fpcr |= (swcr & SWCR_MAP_DMZ) << 36;
7714 fpcr |= (~swcr & (SWCR_TRAP_ENABLE_INV
7715 | SWCR_TRAP_ENABLE_DZE
7716 | SWCR_TRAP_ENABLE_OVF)) << 48;
7717 fpcr |= (~swcr & (SWCR_TRAP_ENABLE_UNF
7718 | SWCR_TRAP_ENABLE_INE)) << 57;
7719 fpcr |= (swcr & SWCR_MAP_UMZ ? FPCR_UNDZ | FPCR_UNFD : 0);
7720 fpcr |= (~swcr & SWCR_TRAP_ENABLE_DNO) << 41;
7721
7722 cpu_alpha_store_fpcr (cpu_env, fpcr);
7723 ret = 0;
7724
7725 if (arg1 == TARGET_SSI_IEEE_RAISE_EXCEPTION) {
7726
7727 fpcr &= ~(orig_fpcr & FPCR_STATUS_MASK);
7728
7729
7730
7731
7732 }
7733 }
7734 break;
7735
7736
7737
7738
7739
7740
7741
7742 }
7743 break;
7744#endif
7745#ifdef TARGET_NR_osf_sigprocmask
7746
7747 case TARGET_NR_osf_sigprocmask:
7748 {
7749 abi_ulong mask;
7750 int how;
7751 sigset_t set, oldset;
7752
7753 switch(arg1) {
7754 case TARGET_SIG_BLOCK:
7755 how = SIG_BLOCK;
7756 break;
7757 case TARGET_SIG_UNBLOCK:
7758 how = SIG_UNBLOCK;
7759 break;
7760 case TARGET_SIG_SETMASK:
7761 how = SIG_SETMASK;
7762 break;
7763 default:
7764 ret = -TARGET_EINVAL;
7765 goto fail;
7766 }
7767 mask = arg2;
7768 target_to_host_old_sigset(&set, &mask);
7769 sigprocmask(how, &set, &oldset);
7770 host_to_target_old_sigset(&mask, &oldset);
7771 ret = mask;
7772 }
7773 break;
7774#endif
7775
7776#ifdef TARGET_NR_getgid32
7777 case TARGET_NR_getgid32:
7778 ret = get_errno(getgid());
7779 break;
7780#endif
7781#ifdef TARGET_NR_geteuid32
7782 case TARGET_NR_geteuid32:
7783 ret = get_errno(geteuid());
7784 break;
7785#endif
7786#ifdef TARGET_NR_getegid32
7787 case TARGET_NR_getegid32:
7788 ret = get_errno(getegid());
7789 break;
7790#endif
7791#ifdef TARGET_NR_setreuid32
7792 case TARGET_NR_setreuid32:
7793 ret = get_errno(setreuid(arg1, arg2));
7794 break;
7795#endif
7796#ifdef TARGET_NR_setregid32
7797 case TARGET_NR_setregid32:
7798 ret = get_errno(setregid(arg1, arg2));
7799 break;
7800#endif
7801#ifdef TARGET_NR_getgroups32
7802 case TARGET_NR_getgroups32:
7803 {
7804 int gidsetsize = arg1;
7805 uint32_t *target_grouplist;
7806 gid_t *grouplist;
7807 int i;
7808
7809 grouplist = alloca(gidsetsize * sizeof(gid_t));
7810 ret = get_errno(getgroups(gidsetsize, grouplist));
7811 if (gidsetsize == 0)
7812 break;
7813 if (!is_error(ret)) {
7814 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
7815 if (!target_grouplist) {
7816 ret = -TARGET_EFAULT;
7817 goto fail;
7818 }
7819 for(i = 0;i < ret; i++)
7820 target_grouplist[i] = tswap32(grouplist[i]);
7821 unlock_user(target_grouplist, arg2, gidsetsize * 4);
7822 }
7823 }
7824 break;
7825#endif
7826#ifdef TARGET_NR_setgroups32
7827 case TARGET_NR_setgroups32:
7828 {
7829 int gidsetsize = arg1;
7830 uint32_t *target_grouplist;
7831 gid_t *grouplist;
7832 int i;
7833
7834 grouplist = alloca(gidsetsize * sizeof(gid_t));
7835 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
7836 if (!target_grouplist) {
7837 ret = -TARGET_EFAULT;
7838 goto fail;
7839 }
7840 for(i = 0;i < gidsetsize; i++)
7841 grouplist[i] = tswap32(target_grouplist[i]);
7842 unlock_user(target_grouplist, arg2, 0);
7843 ret = get_errno(setgroups(gidsetsize, grouplist));
7844 }
7845 break;
7846#endif
7847#ifdef TARGET_NR_fchown32
7848 case TARGET_NR_fchown32:
7849 ret = get_errno(fchown(arg1, arg2, arg3));
7850 break;
7851#endif
7852#ifdef TARGET_NR_setresuid32
7853 case TARGET_NR_setresuid32:
7854 ret = get_errno(setresuid(arg1, arg2, arg3));
7855 break;
7856#endif
7857#ifdef TARGET_NR_getresuid32
7858 case TARGET_NR_getresuid32:
7859 {
7860 uid_t ruid, euid, suid;
7861 ret = get_errno(getresuid(&ruid, &euid, &suid));
7862 if (!is_error(ret)) {
7863 if (put_user_u32(ruid, arg1)
7864 || put_user_u32(euid, arg2)
7865 || put_user_u32(suid, arg3))
7866 goto efault;
7867 }
7868 }
7869 break;
7870#endif
7871#ifdef TARGET_NR_setresgid32
7872 case TARGET_NR_setresgid32:
7873 ret = get_errno(setresgid(arg1, arg2, arg3));
7874 break;
7875#endif
7876#ifdef TARGET_NR_getresgid32
7877 case TARGET_NR_getresgid32:
7878 {
7879 gid_t rgid, egid, sgid;
7880 ret = get_errno(getresgid(&rgid, &egid, &sgid));
7881 if (!is_error(ret)) {
7882 if (put_user_u32(rgid, arg1)
7883 || put_user_u32(egid, arg2)
7884 || put_user_u32(sgid, arg3))
7885 goto efault;
7886 }
7887 }
7888 break;
7889#endif
7890#ifdef TARGET_NR_chown32
7891 case TARGET_NR_chown32:
7892 if (!(p = lock_user_string(arg1)))
7893 goto efault;
7894 ret = get_errno(chown(p, arg2, arg3));
7895 unlock_user(p, arg1, 0);
7896 break;
7897#endif
7898#ifdef TARGET_NR_setuid32
7899 case TARGET_NR_setuid32:
7900 ret = get_errno(setuid(arg1));
7901 break;
7902#endif
7903#ifdef TARGET_NR_setgid32
7904 case TARGET_NR_setgid32:
7905 ret = get_errno(setgid(arg1));
7906 break;
7907#endif
7908#ifdef TARGET_NR_setfsuid32
7909 case TARGET_NR_setfsuid32:
7910 ret = get_errno(setfsuid(arg1));
7911 break;
7912#endif
7913#ifdef TARGET_NR_setfsgid32
7914 case TARGET_NR_setfsgid32:
7915 ret = get_errno(setfsgid(arg1));
7916 break;
7917#endif
7918
7919 case TARGET_NR_pivot_root:
7920 goto unimplemented;
7921#ifdef TARGET_NR_mincore
7922 case TARGET_NR_mincore:
7923 {
7924 void *a;
7925 ret = -TARGET_EFAULT;
7926 if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
7927 goto efault;
7928 if (!(p = lock_user_string(arg3)))
7929 goto mincore_fail;
7930 ret = get_errno(mincore(a, arg2, p));
7931 unlock_user(p, arg3, ret);
7932 mincore_fail:
7933 unlock_user(a, arg1, 0);
7934 }
7935 break;
7936#endif
7937#ifdef TARGET_NR_arm_fadvise64_64
7938 case TARGET_NR_arm_fadvise64_64:
7939 {
7940
7941
7942
7943
7944 abi_long temp;
7945 temp = arg3;
7946 arg3 = arg4;
7947 arg4 = temp;
7948 }
7949#endif
7950#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64) || defined(TARGET_NR_fadvise64)
7951#ifdef TARGET_NR_fadvise64_64
7952 case TARGET_NR_fadvise64_64:
7953#endif
7954#ifdef TARGET_NR_fadvise64
7955 case TARGET_NR_fadvise64:
7956#endif
7957#ifdef TARGET_S390X
7958 switch (arg4) {
7959 case 4: arg4 = POSIX_FADV_NOREUSE + 1; break;
7960 case 5: arg4 = POSIX_FADV_NOREUSE + 2; break;
7961 case 6: arg4 = POSIX_FADV_DONTNEED; break;
7962 case 7: arg4 = POSIX_FADV_NOREUSE; break;
7963 default: break;
7964 }
7965#endif
7966 ret = -posix_fadvise(arg1, arg2, arg3, arg4);
7967 break;
7968#endif
7969#ifdef TARGET_NR_madvise
7970 case TARGET_NR_madvise:
7971
7972
7973
7974
7975 ret = get_errno(0);
7976 break;
7977#endif
7978#if TARGET_ABI_BITS == 32
7979 case TARGET_NR_fcntl64:
7980 {
7981 int cmd;
7982 struct flock64 fl;
7983 struct target_flock64 *target_fl;
7984#ifdef TARGET_ARM
7985 struct target_eabi_flock64 *target_efl;
7986#endif
7987
7988 cmd = target_to_host_fcntl_cmd(arg2);
7989 if (cmd == -TARGET_EINVAL) {
7990 ret = cmd;
7991 break;
7992 }
7993
7994 switch(arg2) {
7995 case TARGET_F_GETLK64:
7996#ifdef TARGET_ARM
7997 if (((CPUARMState *)cpu_env)->eabi) {
7998 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1))
7999 goto efault;
8000 fl.l_type = tswap16(target_efl->l_type);
8001 fl.l_whence = tswap16(target_efl->l_whence);
8002 fl.l_start = tswap64(target_efl->l_start);
8003 fl.l_len = tswap64(target_efl->l_len);
8004 fl.l_pid = tswap32(target_efl->l_pid);
8005 unlock_user_struct(target_efl, arg3, 0);
8006 } else
8007#endif
8008 {
8009 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1))
8010 goto efault;
8011 fl.l_type = tswap16(target_fl->l_type);
8012 fl.l_whence = tswap16(target_fl->l_whence);
8013 fl.l_start = tswap64(target_fl->l_start);
8014 fl.l_len = tswap64(target_fl->l_len);
8015 fl.l_pid = tswap32(target_fl->l_pid);
8016 unlock_user_struct(target_fl, arg3, 0);
8017 }
8018 ret = get_errno(fcntl(arg1, cmd, &fl));
8019 if (ret == 0) {
8020#ifdef TARGET_ARM
8021 if (((CPUARMState *)cpu_env)->eabi) {
8022 if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0))
8023 goto efault;
8024 target_efl->l_type = tswap16(fl.l_type);
8025 target_efl->l_whence = tswap16(fl.l_whence);
8026 target_efl->l_start = tswap64(fl.l_start);
8027 target_efl->l_len = tswap64(fl.l_len);
8028 target_efl->l_pid = tswap32(fl.l_pid);
8029 unlock_user_struct(target_efl, arg3, 1);
8030 } else
8031#endif
8032 {
8033 if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0))
8034 goto efault;
8035 target_fl->l_type = tswap16(fl.l_type);
8036 target_fl->l_whence = tswap16(fl.l_whence);
8037 target_fl->l_start = tswap64(fl.l_start);
8038 target_fl->l_len = tswap64(fl.l_len);
8039 target_fl->l_pid = tswap32(fl.l_pid);
8040 unlock_user_struct(target_fl, arg3, 1);
8041 }
8042 }
8043 break;
8044
8045 case TARGET_F_SETLK64:
8046 case TARGET_F_SETLKW64:
8047#ifdef TARGET_ARM
8048 if (((CPUARMState *)cpu_env)->eabi) {
8049 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1))
8050 goto efault;
8051 fl.l_type = tswap16(target_efl->l_type);
8052 fl.l_whence = tswap16(target_efl->l_whence);
8053 fl.l_start = tswap64(target_efl->l_start);
8054 fl.l_len = tswap64(target_efl->l_len);
8055 fl.l_pid = tswap32(target_efl->l_pid);
8056 unlock_user_struct(target_efl, arg3, 0);
8057 } else
8058#endif
8059 {
8060 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1))
8061 goto efault;
8062 fl.l_type = tswap16(target_fl->l_type);
8063 fl.l_whence = tswap16(target_fl->l_whence);
8064 fl.l_start = tswap64(target_fl->l_start);
8065 fl.l_len = tswap64(target_fl->l_len);
8066 fl.l_pid = tswap32(target_fl->l_pid);
8067 unlock_user_struct(target_fl, arg3, 0);
8068 }
8069 ret = get_errno(fcntl(arg1, cmd, &fl));
8070 break;
8071 default:
8072 ret = do_fcntl(arg1, arg2, arg3);
8073 break;
8074 }
8075 break;
8076 }
8077#endif
8078#ifdef TARGET_NR_cacheflush
8079 case TARGET_NR_cacheflush:
8080
8081 ret = 0;
8082 break;
8083#endif
8084#ifdef TARGET_NR_security
8085 case TARGET_NR_security:
8086 goto unimplemented;
8087#endif
8088#ifdef TARGET_NR_getpagesize
8089 case TARGET_NR_getpagesize:
8090 ret = TARGET_PAGE_SIZE;
8091 break;
8092#endif
8093 case TARGET_NR_gettid:
8094 ret = get_errno(gettid());
8095 break;
8096#ifdef TARGET_NR_readahead
8097 case TARGET_NR_readahead:
8098#if TARGET_ABI_BITS == 32
8099 if (regpairs_aligned(cpu_env)) {
8100 arg2 = arg3;
8101 arg3 = arg4;
8102 arg4 = arg5;
8103 }
8104 ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
8105#else
8106 ret = get_errno(readahead(arg1, arg2, arg3));
8107#endif
8108 break;
8109#endif
8110#ifdef CONFIG_ATTR
8111#ifdef TARGET_NR_setxattr
8112 case TARGET_NR_listxattr:
8113 case TARGET_NR_llistxattr:
8114 {
8115 void *p, *b = 0;
8116 if (arg2) {
8117 b = lock_user(VERIFY_WRITE, arg2, arg3, 0);
8118 if (!b) {
8119 ret = -TARGET_EFAULT;
8120 break;
8121 }
8122 }
8123 p = lock_user_string(arg1);
8124 if (p) {
8125 if (num == TARGET_NR_listxattr) {
8126 ret = get_errno(listxattr(p, b, arg3));
8127 } else {
8128 ret = get_errno(llistxattr(p, b, arg3));
8129 }
8130 } else {
8131 ret = -TARGET_EFAULT;
8132 }
8133 unlock_user(p, arg1, 0);
8134 unlock_user(b, arg2, arg3);
8135 break;
8136 }
8137 case TARGET_NR_flistxattr:
8138 {
8139 void *b = 0;
8140 if (arg2) {
8141 b = lock_user(VERIFY_WRITE, arg2, arg3, 0);
8142 if (!b) {
8143 ret = -TARGET_EFAULT;
8144 break;
8145 }
8146 }
8147 ret = get_errno(flistxattr(arg1, b, arg3));
8148 unlock_user(b, arg2, arg3);
8149 break;
8150 }
8151 case TARGET_NR_setxattr:
8152 case TARGET_NR_lsetxattr:
8153 {
8154 void *p, *n, *v = 0;
8155 if (arg3) {
8156 v = lock_user(VERIFY_READ, arg3, arg4, 1);
8157 if (!v) {
8158 ret = -TARGET_EFAULT;
8159 break;
8160 }
8161 }
8162 p = lock_user_string(arg1);
8163 n = lock_user_string(arg2);
8164 if (p && n) {
8165 if (num == TARGET_NR_setxattr) {
8166 ret = get_errno(setxattr(p, n, v, arg4, arg5));
8167 } else {
8168 ret = get_errno(lsetxattr(p, n, v, arg4, arg5));
8169 }
8170 } else {
8171 ret = -TARGET_EFAULT;
8172 }
8173 unlock_user(p, arg1, 0);
8174 unlock_user(n, arg2, 0);
8175 unlock_user(v, arg3, 0);
8176 }
8177 break;
8178 case TARGET_NR_fsetxattr:
8179 {
8180 void *n, *v = 0;
8181 if (arg3) {
8182 v = lock_user(VERIFY_READ, arg3, arg4, 1);
8183 if (!v) {
8184 ret = -TARGET_EFAULT;
8185 break;
8186 }
8187 }
8188 n = lock_user_string(arg2);
8189 if (n) {
8190 ret = get_errno(fsetxattr(arg1, n, v, arg4, arg5));
8191 } else {
8192 ret = -TARGET_EFAULT;
8193 }
8194 unlock_user(n, arg2, 0);
8195 unlock_user(v, arg3, 0);
8196 }
8197 break;
8198 case TARGET_NR_getxattr:
8199 case TARGET_NR_lgetxattr:
8200 {
8201 void *p, *n, *v = 0;
8202 if (arg3) {
8203 v = lock_user(VERIFY_WRITE, arg3, arg4, 0);
8204 if (!v) {
8205 ret = -TARGET_EFAULT;
8206 break;
8207 }
8208 }
8209 p = lock_user_string(arg1);
8210 n = lock_user_string(arg2);
8211 if (p && n) {
8212 if (num == TARGET_NR_getxattr) {
8213 ret = get_errno(getxattr(p, n, v, arg4));
8214 } else {
8215 ret = get_errno(lgetxattr(p, n, v, arg4));
8216 }
8217 } else {
8218 ret = -TARGET_EFAULT;
8219 }
8220 unlock_user(p, arg1, 0);
8221 unlock_user(n, arg2, 0);
8222 unlock_user(v, arg3, arg4);
8223 }
8224 break;
8225 case TARGET_NR_fgetxattr:
8226 {
8227 void *n, *v = 0;
8228 if (arg3) {
8229 v = lock_user(VERIFY_WRITE, arg3, arg4, 0);
8230 if (!v) {
8231 ret = -TARGET_EFAULT;
8232 break;
8233 }
8234 }
8235 n = lock_user_string(arg2);
8236 if (n) {
8237 ret = get_errno(fgetxattr(arg1, n, v, arg4));
8238 } else {
8239 ret = -TARGET_EFAULT;
8240 }
8241 unlock_user(n, arg2, 0);
8242 unlock_user(v, arg3, arg4);
8243 }
8244 break;
8245 case TARGET_NR_removexattr:
8246 case TARGET_NR_lremovexattr:
8247 {
8248 void *p, *n;
8249 p = lock_user_string(arg1);
8250 n = lock_user_string(arg2);
8251 if (p && n) {
8252 if (num == TARGET_NR_removexattr) {
8253 ret = get_errno(removexattr(p, n));
8254 } else {
8255 ret = get_errno(lremovexattr(p, n));
8256 }
8257 } else {
8258 ret = -TARGET_EFAULT;
8259 }
8260 unlock_user(p, arg1, 0);
8261 unlock_user(n, arg2, 0);
8262 }
8263 break;
8264 case TARGET_NR_fremovexattr:
8265 {
8266 void *n;
8267 n = lock_user_string(arg2);
8268 if (n) {
8269 ret = get_errno(fremovexattr(arg1, n));
8270 } else {
8271 ret = -TARGET_EFAULT;
8272 }
8273 unlock_user(n, arg2, 0);
8274 }
8275 break;
8276#endif
8277#endif
8278#ifdef TARGET_NR_set_thread_area
8279 case TARGET_NR_set_thread_area:
8280#if defined(TARGET_MIPS)
8281 ((CPUMIPSState *) cpu_env)->tls_value = arg1;
8282 ret = 0;
8283 break;
8284#elif defined(TARGET_CRIS)
8285 if (arg1 & 0xff)
8286 ret = -TARGET_EINVAL;
8287 else {
8288 ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
8289 ret = 0;
8290 }
8291 break;
8292#elif defined(TARGET_I386) && defined(TARGET_ABI32)
8293 ret = do_set_thread_area(cpu_env, arg1);
8294 break;
8295#else
8296 goto unimplemented_nowarn;
8297#endif
8298#endif
8299#ifdef TARGET_NR_get_thread_area
8300 case TARGET_NR_get_thread_area:
8301#if defined(TARGET_I386) && defined(TARGET_ABI32)
8302 ret = do_get_thread_area(cpu_env, arg1);
8303#else
8304 goto unimplemented_nowarn;
8305#endif
8306#endif
8307#ifdef TARGET_NR_getdomainname
8308 case TARGET_NR_getdomainname:
8309 goto unimplemented_nowarn;
8310#endif
8311
8312#ifdef TARGET_NR_clock_gettime
8313 case TARGET_NR_clock_gettime:
8314 {
8315 struct timespec ts;
8316 ret = get_errno(clock_gettime(arg1, &ts));
8317 if (!is_error(ret)) {
8318 host_to_target_timespec(arg2, &ts);
8319 }
8320 break;
8321 }
8322#endif
8323#ifdef TARGET_NR_clock_getres
8324 case TARGET_NR_clock_getres:
8325 {
8326 struct timespec ts;
8327 ret = get_errno(clock_getres(arg1, &ts));
8328 if (!is_error(ret)) {
8329 host_to_target_timespec(arg2, &ts);
8330 }
8331 break;
8332 }
8333#endif
8334#ifdef TARGET_NR_clock_nanosleep
8335 case TARGET_NR_clock_nanosleep:
8336 {
8337 struct timespec ts;
8338 target_to_host_timespec(&ts, arg3);
8339 ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
8340 if (arg4)
8341 host_to_target_timespec(arg4, &ts);
8342 break;
8343 }
8344#endif
8345
8346#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
8347 case TARGET_NR_set_tid_address:
8348 ret = get_errno(set_tid_address((int *)g2h(arg1)));
8349 break;
8350#endif
8351
8352#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
8353 case TARGET_NR_tkill:
8354 ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
8355 break;
8356#endif
8357
8358#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
8359 case TARGET_NR_tgkill:
8360 ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
8361 target_to_host_signal(arg3)));
8362 break;
8363#endif
8364
8365#ifdef TARGET_NR_set_robust_list
8366 case TARGET_NR_set_robust_list:
8367 goto unimplemented_nowarn;
8368#endif
8369
8370#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
8371 case TARGET_NR_utimensat:
8372 {
8373 struct timespec *tsp, ts[2];
8374 if (!arg3) {
8375 tsp = NULL;
8376 } else {
8377 target_to_host_timespec(ts, arg3);
8378 target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
8379 tsp = ts;
8380 }
8381 if (!arg2)
8382 ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4));
8383 else {
8384 if (!(p = lock_user_string(arg2))) {
8385 ret = -TARGET_EFAULT;
8386 goto fail;
8387 }
8388 ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4));
8389 unlock_user(p, arg2, 0);
8390 }
8391 }
8392 break;
8393#endif
8394#if defined(CONFIG_USE_NPTL)
8395 case TARGET_NR_futex:
8396 ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
8397 break;
8398#endif
8399#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
8400 case TARGET_NR_inotify_init:
8401 ret = get_errno(sys_inotify_init());
8402 break;
8403#endif
8404#ifdef CONFIG_INOTIFY1
8405#if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
8406 case TARGET_NR_inotify_init1:
8407 ret = get_errno(sys_inotify_init1(arg1));
8408 break;
8409#endif
8410#endif
8411#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
8412 case TARGET_NR_inotify_add_watch:
8413 p = lock_user_string(arg2);
8414 ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
8415 unlock_user(p, arg2, 0);
8416 break;
8417#endif
8418#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
8419 case TARGET_NR_inotify_rm_watch:
8420 ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
8421 break;
8422#endif
8423
8424#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
8425 case TARGET_NR_mq_open:
8426 {
8427 struct mq_attr posix_mq_attr;
8428
8429 p = lock_user_string(arg1 - 1);
8430 if (arg4 != 0)
8431 copy_from_user_mq_attr (&posix_mq_attr, arg4);
8432 ret = get_errno(mq_open(p, arg2, arg3, &posix_mq_attr));
8433 unlock_user (p, arg1, 0);
8434 }
8435 break;
8436
8437 case TARGET_NR_mq_unlink:
8438 p = lock_user_string(arg1 - 1);
8439 ret = get_errno(mq_unlink(p));
8440 unlock_user (p, arg1, 0);
8441 break;
8442
8443 case TARGET_NR_mq_timedsend:
8444 {
8445 struct timespec ts;
8446
8447 p = lock_user (VERIFY_READ, arg2, arg3, 1);
8448 if (arg5 != 0) {
8449 target_to_host_timespec(&ts, arg5);
8450 ret = get_errno(mq_timedsend(arg1, p, arg3, arg4, &ts));
8451 host_to_target_timespec(arg5, &ts);
8452 }
8453 else
8454 ret = get_errno(mq_send(arg1, p, arg3, arg4));
8455 unlock_user (p, arg2, arg3);
8456 }
8457 break;
8458
8459 case TARGET_NR_mq_timedreceive:
8460 {
8461 struct timespec ts;
8462 unsigned int prio;
8463
8464 p = lock_user (VERIFY_READ, arg2, arg3, 1);
8465 if (arg5 != 0) {
8466 target_to_host_timespec(&ts, arg5);
8467 ret = get_errno(mq_timedreceive(arg1, p, arg3, &prio, &ts));
8468 host_to_target_timespec(arg5, &ts);
8469 }
8470 else
8471 ret = get_errno(mq_receive(arg1, p, arg3, &prio));
8472 unlock_user (p, arg2, arg3);
8473 if (arg4 != 0)
8474 put_user_u32(prio, arg4);
8475 }
8476 break;
8477
8478
8479
8480
8481
8482 case TARGET_NR_mq_getsetattr:
8483 {
8484 struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
8485 ret = 0;
8486 if (arg3 != 0) {
8487 ret = mq_getattr(arg1, &posix_mq_attr_out);
8488 copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
8489 }
8490 if (arg2 != 0) {
8491 copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
8492 ret |= mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_attr_out);
8493 }
8494
8495 }
8496 break;
8497#endif
8498
8499#ifdef CONFIG_SPLICE
8500#ifdef TARGET_NR_tee
8501 case TARGET_NR_tee:
8502 {
8503 ret = get_errno(tee(arg1,arg2,arg3,arg4));
8504 }
8505 break;
8506#endif
8507#ifdef TARGET_NR_splice
8508 case TARGET_NR_splice:
8509 {
8510 loff_t loff_in, loff_out;
8511 loff_t *ploff_in = NULL, *ploff_out = NULL;
8512 if(arg2) {
8513 get_user_u64(loff_in, arg2);
8514 ploff_in = &loff_in;
8515 }
8516 if(arg4) {
8517 get_user_u64(loff_out, arg2);
8518 ploff_out = &loff_out;
8519 }
8520 ret = get_errno(splice(arg1, ploff_in, arg3, ploff_out, arg5, arg6));
8521 }
8522 break;
8523#endif
8524#ifdef TARGET_NR_vmsplice
8525 case TARGET_NR_vmsplice:
8526 {
8527 int count = arg3;
8528 struct iovec *vec;
8529
8530 vec = alloca(count * sizeof(struct iovec));
8531 if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
8532 goto efault;
8533 ret = get_errno(vmsplice(arg1, vec, count, arg4));
8534 unlock_iovec(vec, arg2, count, 0);
8535 }
8536 break;
8537#endif
8538#endif
8539#ifdef CONFIG_EVENTFD
8540#if defined(TARGET_NR_eventfd)
8541 case TARGET_NR_eventfd:
8542 ret = get_errno(eventfd(arg1, 0));
8543 break;
8544#endif
8545#if defined(TARGET_NR_eventfd2)
8546 case TARGET_NR_eventfd2:
8547 ret = get_errno(eventfd(arg1, arg2));
8548 break;
8549#endif
8550#endif
8551#if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate)
8552 case TARGET_NR_fallocate:
8553#if TARGET_ABI_BITS == 32
8554 ret = get_errno(fallocate(arg1, arg2, target_offset64(arg3, arg4),
8555 target_offset64(arg5, arg6)));
8556#else
8557 ret = get_errno(fallocate(arg1, arg2, arg3, arg4));
8558#endif
8559 break;
8560#endif
8561#if defined(CONFIG_SYNC_FILE_RANGE)
8562#if defined(TARGET_NR_sync_file_range)
8563 case TARGET_NR_sync_file_range:
8564#if TARGET_ABI_BITS == 32
8565#if defined(TARGET_MIPS)
8566 ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
8567 target_offset64(arg5, arg6), arg7));
8568#else
8569 ret = get_errno(sync_file_range(arg1, target_offset64(arg2, arg3),
8570 target_offset64(arg4, arg5), arg6));
8571#endif
8572#else
8573 ret = get_errno(sync_file_range(arg1, arg2, arg3, arg4));
8574#endif
8575 break;
8576#endif
8577#if defined(TARGET_NR_sync_file_range2)
8578 case TARGET_NR_sync_file_range2:
8579
8580#if TARGET_ABI_BITS == 32
8581 ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
8582 target_offset64(arg5, arg6), arg2));
8583#else
8584 ret = get_errno(sync_file_range(arg1, arg3, arg4, arg2));
8585#endif
8586 break;
8587#endif
8588#endif
8589#if defined(CONFIG_EPOLL)
8590#if defined(TARGET_NR_epoll_create)
8591 case TARGET_NR_epoll_create:
8592 ret = get_errno(epoll_create(arg1));
8593 break;
8594#endif
8595#if defined(TARGET_NR_epoll_create1) && defined(CONFIG_EPOLL_CREATE1)
8596 case TARGET_NR_epoll_create1:
8597 ret = get_errno(epoll_create1(arg1));
8598 break;
8599#endif
8600#if defined(TARGET_NR_epoll_ctl)
8601 case TARGET_NR_epoll_ctl:
8602 {
8603 struct epoll_event ep;
8604 struct epoll_event *epp = 0;
8605 if (arg4) {
8606 struct target_epoll_event *target_ep;
8607 if (!lock_user_struct(VERIFY_READ, target_ep, arg4, 1)) {
8608 goto efault;
8609 }
8610 ep.events = tswap32(target_ep->events);
8611
8612
8613
8614
8615 ep.data.u64 = tswap64(target_ep->data.u64);
8616 unlock_user_struct(target_ep, arg4, 0);
8617 epp = &ep;
8618 }
8619 ret = get_errno(epoll_ctl(arg1, arg2, arg3, epp));
8620 break;
8621 }
8622#endif
8623
8624#if defined(TARGET_NR_epoll_pwait) && defined(CONFIG_EPOLL_PWAIT)
8625#define IMPLEMENT_EPOLL_PWAIT
8626#endif
8627#if defined(TARGET_NR_epoll_wait) || defined(IMPLEMENT_EPOLL_PWAIT)
8628#if defined(TARGET_NR_epoll_wait)
8629 case TARGET_NR_epoll_wait:
8630#endif
8631#if defined(IMPLEMENT_EPOLL_PWAIT)
8632 case TARGET_NR_epoll_pwait:
8633#endif
8634 {
8635 struct target_epoll_event *target_ep;
8636 struct epoll_event *ep;
8637 int epfd = arg1;
8638 int maxevents = arg3;
8639 int timeout = arg4;
8640
8641 target_ep = lock_user(VERIFY_WRITE, arg2,
8642 maxevents * sizeof(struct target_epoll_event), 1);
8643 if (!target_ep) {
8644 goto efault;
8645 }
8646
8647 ep = alloca(maxevents * sizeof(struct epoll_event));
8648
8649 switch (num) {
8650#if defined(IMPLEMENT_EPOLL_PWAIT)
8651 case TARGET_NR_epoll_pwait:
8652 {
8653 target_sigset_t *target_set;
8654 sigset_t _set, *set = &_set;
8655
8656 if (arg5) {
8657 target_set = lock_user(VERIFY_READ, arg5,
8658 sizeof(target_sigset_t), 1);
8659 if (!target_set) {
8660 unlock_user(target_ep, arg2, 0);
8661 goto efault;
8662 }
8663 target_to_host_sigset(set, target_set);
8664 unlock_user(target_set, arg5, 0);
8665 } else {
8666 set = NULL;
8667 }
8668
8669 ret = get_errno(epoll_pwait(epfd, ep, maxevents, timeout, set));
8670 break;
8671 }
8672#endif
8673#if defined(TARGET_NR_epoll_wait)
8674 case TARGET_NR_epoll_wait:
8675 ret = get_errno(epoll_wait(epfd, ep, maxevents, timeout));
8676 break;
8677#endif
8678 default:
8679 ret = -TARGET_ENOSYS;
8680 }
8681 if (!is_error(ret)) {
8682 int i;
8683 for (i = 0; i < ret; i++) {
8684 target_ep[i].events = tswap32(ep[i].events);
8685 target_ep[i].data.u64 = tswap64(ep[i].data.u64);
8686 }
8687 }
8688 unlock_user(target_ep, arg2, ret * sizeof(struct target_epoll_event));
8689 break;
8690 }
8691#endif
8692#endif
8693#ifdef TARGET_NR_prlimit64
8694 case TARGET_NR_prlimit64:
8695 {
8696
8697 struct target_rlimit64 *target_rnew, *target_rold;
8698 struct host_rlimit64 rnew, rold, *rnewp = 0;
8699 if (arg3) {
8700 if (!lock_user_struct(VERIFY_READ, target_rnew, arg3, 1)) {
8701 goto efault;
8702 }
8703 rnew.rlim_cur = tswap64(target_rnew->rlim_cur);
8704 rnew.rlim_max = tswap64(target_rnew->rlim_max);
8705 unlock_user_struct(target_rnew, arg3, 0);
8706 rnewp = &rnew;
8707 }
8708
8709 ret = get_errno(sys_prlimit64(arg1, arg2, rnewp, arg4 ? &rold : 0));
8710 if (!is_error(ret) && arg4) {
8711 if (!lock_user_struct(VERIFY_WRITE, target_rold, arg4, 1)) {
8712 goto efault;
8713 }
8714 target_rold->rlim_cur = tswap64(rold.rlim_cur);
8715 target_rold->rlim_max = tswap64(rold.rlim_max);
8716 unlock_user_struct(target_rold, arg4, 1);
8717 }
8718 break;
8719 }
8720#endif
8721 default:
8722 unimplemented:
8723 gemu_log("qemu: Unsupported syscall: %d\n", num);
8724#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
8725 unimplemented_nowarn:
8726#endif
8727 ret = -TARGET_ENOSYS;
8728 break;
8729 }
8730fail:
8731#ifdef DEBUG
8732 gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
8733#endif
8734 if(do_strace)
8735 print_syscall_ret(num, ret);
8736 return ret;
8737efault:
8738 ret = -TARGET_EFAULT;
8739 goto fail;
8740}
8741