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