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_semid_ds
2421{
2422 struct target_ipc_perm sem_perm;
2423 abi_ulong sem_otime;
2424 abi_ulong __unused1;
2425 abi_ulong sem_ctime;
2426 abi_ulong __unused2;
2427 abi_ulong sem_nsems;
2428 abi_ulong __unused3;
2429 abi_ulong __unused4;
2430};
2431
2432static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
2433 abi_ulong target_addr)
2434{
2435 struct target_ipc_perm *target_ip;
2436 struct target_semid_ds *target_sd;
2437
2438 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2439 return -TARGET_EFAULT;
2440 target_ip = &(target_sd->sem_perm);
2441 host_ip->__key = tswap32(target_ip->__key);
2442 host_ip->uid = tswap32(target_ip->uid);
2443 host_ip->gid = tswap32(target_ip->gid);
2444 host_ip->cuid = tswap32(target_ip->cuid);
2445 host_ip->cgid = tswap32(target_ip->cgid);
2446#if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_PPC)
2447 host_ip->mode = tswap32(target_ip->mode);
2448#else
2449 host_ip->mode = tswap16(target_ip->mode);
2450#endif
2451#if defined(TARGET_PPC)
2452 host_ip->__seq = tswap32(target_ip->__seq);
2453#else
2454 host_ip->__seq = tswap16(target_ip->__seq);
2455#endif
2456 unlock_user_struct(target_sd, target_addr, 0);
2457 return 0;
2458}
2459
2460static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
2461 struct ipc_perm *host_ip)
2462{
2463 struct target_ipc_perm *target_ip;
2464 struct target_semid_ds *target_sd;
2465
2466 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2467 return -TARGET_EFAULT;
2468 target_ip = &(target_sd->sem_perm);
2469 target_ip->__key = tswap32(host_ip->__key);
2470 target_ip->uid = tswap32(host_ip->uid);
2471 target_ip->gid = tswap32(host_ip->gid);
2472 target_ip->cuid = tswap32(host_ip->cuid);
2473 target_ip->cgid = tswap32(host_ip->cgid);
2474#if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_PPC)
2475 target_ip->mode = tswap32(host_ip->mode);
2476#else
2477 target_ip->mode = tswap16(host_ip->mode);
2478#endif
2479#if defined(TARGET_PPC)
2480 target_ip->__seq = tswap32(host_ip->__seq);
2481#else
2482 target_ip->__seq = tswap16(host_ip->__seq);
2483#endif
2484 unlock_user_struct(target_sd, target_addr, 1);
2485 return 0;
2486}
2487
2488static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
2489 abi_ulong target_addr)
2490{
2491 struct target_semid_ds *target_sd;
2492
2493 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2494 return -TARGET_EFAULT;
2495 if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr))
2496 return -TARGET_EFAULT;
2497 host_sd->sem_nsems = tswapal(target_sd->sem_nsems);
2498 host_sd->sem_otime = tswapal(target_sd->sem_otime);
2499 host_sd->sem_ctime = tswapal(target_sd->sem_ctime);
2500 unlock_user_struct(target_sd, target_addr, 0);
2501 return 0;
2502}
2503
2504static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
2505 struct semid_ds *host_sd)
2506{
2507 struct target_semid_ds *target_sd;
2508
2509 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2510 return -TARGET_EFAULT;
2511 if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
2512 return -TARGET_EFAULT;
2513 target_sd->sem_nsems = tswapal(host_sd->sem_nsems);
2514 target_sd->sem_otime = tswapal(host_sd->sem_otime);
2515 target_sd->sem_ctime = tswapal(host_sd->sem_ctime);
2516 unlock_user_struct(target_sd, target_addr, 1);
2517 return 0;
2518}
2519
2520struct target_seminfo {
2521 int semmap;
2522 int semmni;
2523 int semmns;
2524 int semmnu;
2525 int semmsl;
2526 int semopm;
2527 int semume;
2528 int semusz;
2529 int semvmx;
2530 int semaem;
2531};
2532
2533static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
2534 struct seminfo *host_seminfo)
2535{
2536 struct target_seminfo *target_seminfo;
2537 if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
2538 return -TARGET_EFAULT;
2539 __put_user(host_seminfo->semmap, &target_seminfo->semmap);
2540 __put_user(host_seminfo->semmni, &target_seminfo->semmni);
2541 __put_user(host_seminfo->semmns, &target_seminfo->semmns);
2542 __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
2543 __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
2544 __put_user(host_seminfo->semopm, &target_seminfo->semopm);
2545 __put_user(host_seminfo->semume, &target_seminfo->semume);
2546 __put_user(host_seminfo->semusz, &target_seminfo->semusz);
2547 __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
2548 __put_user(host_seminfo->semaem, &target_seminfo->semaem);
2549 unlock_user_struct(target_seminfo, target_addr, 1);
2550 return 0;
2551}
2552
2553union semun {
2554 int val;
2555 struct semid_ds *buf;
2556 unsigned short *array;
2557 struct seminfo *__buf;
2558};
2559
2560union target_semun {
2561 int val;
2562 abi_ulong buf;
2563 abi_ulong array;
2564 abi_ulong __buf;
2565};
2566
2567static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
2568 abi_ulong target_addr)
2569{
2570 int nsems;
2571 unsigned short *array;
2572 union semun semun;
2573 struct semid_ds semid_ds;
2574 int i, ret;
2575
2576 semun.buf = &semid_ds;
2577
2578 ret = semctl(semid, 0, IPC_STAT, semun);
2579 if (ret == -1)
2580 return get_errno(ret);
2581
2582 nsems = semid_ds.sem_nsems;
2583
2584 *host_array = malloc(nsems*sizeof(unsigned short));
2585 array = lock_user(VERIFY_READ, target_addr,
2586 nsems*sizeof(unsigned short), 1);
2587 if (!array)
2588 return -TARGET_EFAULT;
2589
2590 for(i=0; i<nsems; i++) {
2591 __get_user((*host_array)[i], &array[i]);
2592 }
2593 unlock_user(array, target_addr, 0);
2594
2595 return 0;
2596}
2597
2598static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
2599 unsigned short **host_array)
2600{
2601 int nsems;
2602 unsigned short *array;
2603 union semun semun;
2604 struct semid_ds semid_ds;
2605 int i, ret;
2606
2607 semun.buf = &semid_ds;
2608
2609 ret = semctl(semid, 0, IPC_STAT, semun);
2610 if (ret == -1)
2611 return get_errno(ret);
2612
2613 nsems = semid_ds.sem_nsems;
2614
2615 array = lock_user(VERIFY_WRITE, target_addr,
2616 nsems*sizeof(unsigned short), 0);
2617 if (!array)
2618 return -TARGET_EFAULT;
2619
2620 for(i=0; i<nsems; i++) {
2621 __put_user((*host_array)[i], &array[i]);
2622 }
2623 free(*host_array);
2624 unlock_user(array, target_addr, 1);
2625
2626 return 0;
2627}
2628
2629static inline abi_long do_semctl(int semid, int semnum, int cmd,
2630 union target_semun target_su)
2631{
2632 union semun arg;
2633 struct semid_ds dsarg;
2634 unsigned short *array = NULL;
2635 struct seminfo seminfo;
2636 abi_long ret = -TARGET_EINVAL;
2637 abi_long err;
2638 cmd &= 0xff;
2639
2640 switch( cmd ) {
2641 case GETVAL:
2642 case SETVAL:
2643 arg.val = tswap32(target_su.val);
2644 ret = get_errno(semctl(semid, semnum, cmd, arg));
2645 target_su.val = tswap32(arg.val);
2646 break;
2647 case GETALL:
2648 case SETALL:
2649 err = target_to_host_semarray(semid, &array, target_su.array);
2650 if (err)
2651 return err;
2652 arg.array = array;
2653 ret = get_errno(semctl(semid, semnum, cmd, arg));
2654 err = host_to_target_semarray(semid, target_su.array, &array);
2655 if (err)
2656 return err;
2657 break;
2658 case IPC_STAT:
2659 case IPC_SET:
2660 case SEM_STAT:
2661 err = target_to_host_semid_ds(&dsarg, target_su.buf);
2662 if (err)
2663 return err;
2664 arg.buf = &dsarg;
2665 ret = get_errno(semctl(semid, semnum, cmd, arg));
2666 err = host_to_target_semid_ds(target_su.buf, &dsarg);
2667 if (err)
2668 return err;
2669 break;
2670 case IPC_INFO:
2671 case SEM_INFO:
2672 arg.__buf = &seminfo;
2673 ret = get_errno(semctl(semid, semnum, cmd, arg));
2674 err = host_to_target_seminfo(target_su.__buf, &seminfo);
2675 if (err)
2676 return err;
2677 break;
2678 case IPC_RMID:
2679 case GETPID:
2680 case GETNCNT:
2681 case GETZCNT:
2682 ret = get_errno(semctl(semid, semnum, cmd, NULL));
2683 break;
2684 }
2685
2686 return ret;
2687}
2688
2689struct target_sembuf {
2690 unsigned short sem_num;
2691 short sem_op;
2692 short sem_flg;
2693};
2694
2695static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
2696 abi_ulong target_addr,
2697 unsigned nsops)
2698{
2699 struct target_sembuf *target_sembuf;
2700 int i;
2701
2702 target_sembuf = lock_user(VERIFY_READ, target_addr,
2703 nsops*sizeof(struct target_sembuf), 1);
2704 if (!target_sembuf)
2705 return -TARGET_EFAULT;
2706
2707 for(i=0; i<nsops; i++) {
2708 __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
2709 __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
2710 __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
2711 }
2712
2713 unlock_user(target_sembuf, target_addr, 0);
2714
2715 return 0;
2716}
2717
2718static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
2719{
2720 struct sembuf sops[nsops];
2721
2722 if (target_to_host_sembuf(sops, ptr, nsops))
2723 return -TARGET_EFAULT;
2724
2725 return get_errno(semop(semid, sops, nsops));
2726}
2727
2728struct target_msqid_ds
2729{
2730 struct target_ipc_perm msg_perm;
2731 abi_ulong msg_stime;
2732#if TARGET_ABI_BITS == 32
2733 abi_ulong __unused1;
2734#endif
2735 abi_ulong msg_rtime;
2736#if TARGET_ABI_BITS == 32
2737 abi_ulong __unused2;
2738#endif
2739 abi_ulong msg_ctime;
2740#if TARGET_ABI_BITS == 32
2741 abi_ulong __unused3;
2742#endif
2743 abi_ulong __msg_cbytes;
2744 abi_ulong msg_qnum;
2745 abi_ulong msg_qbytes;
2746 abi_ulong msg_lspid;
2747 abi_ulong msg_lrpid;
2748 abi_ulong __unused4;
2749 abi_ulong __unused5;
2750};
2751
2752static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
2753 abi_ulong target_addr)
2754{
2755 struct target_msqid_ds *target_md;
2756
2757 if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
2758 return -TARGET_EFAULT;
2759 if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
2760 return -TARGET_EFAULT;
2761 host_md->msg_stime = tswapal(target_md->msg_stime);
2762 host_md->msg_rtime = tswapal(target_md->msg_rtime);
2763 host_md->msg_ctime = tswapal(target_md->msg_ctime);
2764 host_md->__msg_cbytes = tswapal(target_md->__msg_cbytes);
2765 host_md->msg_qnum = tswapal(target_md->msg_qnum);
2766 host_md->msg_qbytes = tswapal(target_md->msg_qbytes);
2767 host_md->msg_lspid = tswapal(target_md->msg_lspid);
2768 host_md->msg_lrpid = tswapal(target_md->msg_lrpid);
2769 unlock_user_struct(target_md, target_addr, 0);
2770 return 0;
2771}
2772
2773static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
2774 struct msqid_ds *host_md)
2775{
2776 struct target_msqid_ds *target_md;
2777
2778 if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
2779 return -TARGET_EFAULT;
2780 if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
2781 return -TARGET_EFAULT;
2782 target_md->msg_stime = tswapal(host_md->msg_stime);
2783 target_md->msg_rtime = tswapal(host_md->msg_rtime);
2784 target_md->msg_ctime = tswapal(host_md->msg_ctime);
2785 target_md->__msg_cbytes = tswapal(host_md->__msg_cbytes);
2786 target_md->msg_qnum = tswapal(host_md->msg_qnum);
2787 target_md->msg_qbytes = tswapal(host_md->msg_qbytes);
2788 target_md->msg_lspid = tswapal(host_md->msg_lspid);
2789 target_md->msg_lrpid = tswapal(host_md->msg_lrpid);
2790 unlock_user_struct(target_md, target_addr, 1);
2791 return 0;
2792}
2793
2794struct target_msginfo {
2795 int msgpool;
2796 int msgmap;
2797 int msgmax;
2798 int msgmnb;
2799 int msgmni;
2800 int msgssz;
2801 int msgtql;
2802 unsigned short int msgseg;
2803};
2804
2805static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
2806 struct msginfo *host_msginfo)
2807{
2808 struct target_msginfo *target_msginfo;
2809 if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
2810 return -TARGET_EFAULT;
2811 __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
2812 __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
2813 __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
2814 __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
2815 __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
2816 __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
2817 __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
2818 __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
2819 unlock_user_struct(target_msginfo, target_addr, 1);
2820 return 0;
2821}
2822
2823static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
2824{
2825 struct msqid_ds dsarg;
2826 struct msginfo msginfo;
2827 abi_long ret = -TARGET_EINVAL;
2828
2829 cmd &= 0xff;
2830
2831 switch (cmd) {
2832 case IPC_STAT:
2833 case IPC_SET:
2834 case MSG_STAT:
2835 if (target_to_host_msqid_ds(&dsarg,ptr))
2836 return -TARGET_EFAULT;
2837 ret = get_errno(msgctl(msgid, cmd, &dsarg));
2838 if (host_to_target_msqid_ds(ptr,&dsarg))
2839 return -TARGET_EFAULT;
2840 break;
2841 case IPC_RMID:
2842 ret = get_errno(msgctl(msgid, cmd, NULL));
2843 break;
2844 case IPC_INFO:
2845 case MSG_INFO:
2846 ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
2847 if (host_to_target_msginfo(ptr, &msginfo))
2848 return -TARGET_EFAULT;
2849 break;
2850 }
2851
2852 return ret;
2853}
2854
2855struct target_msgbuf {
2856 abi_long mtype;
2857 char mtext[1];
2858};
2859
2860static inline abi_long do_msgsnd(int msqid, abi_long msgp,
2861 unsigned int msgsz, int msgflg)
2862{
2863 struct target_msgbuf *target_mb;
2864 struct msgbuf *host_mb;
2865 abi_long ret = 0;
2866
2867 if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
2868 return -TARGET_EFAULT;
2869 host_mb = malloc(msgsz+sizeof(long));
2870 host_mb->mtype = (abi_long) tswapal(target_mb->mtype);
2871 memcpy(host_mb->mtext, target_mb->mtext, msgsz);
2872 ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
2873 free(host_mb);
2874 unlock_user_struct(target_mb, msgp, 0);
2875
2876 return ret;
2877}
2878
2879static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2880 unsigned int msgsz, abi_long msgtyp,
2881 int msgflg)
2882{
2883 struct target_msgbuf *target_mb;
2884 char *target_mtext;
2885 struct msgbuf *host_mb;
2886 abi_long ret = 0;
2887
2888 if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2889 return -TARGET_EFAULT;
2890
2891 host_mb = g_malloc(msgsz+sizeof(long));
2892 ret = get_errno(msgrcv(msqid, host_mb, msgsz, msgtyp, msgflg));
2893
2894 if (ret > 0) {
2895 abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2896 target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2897 if (!target_mtext) {
2898 ret = -TARGET_EFAULT;
2899 goto end;
2900 }
2901 memcpy(target_mb->mtext, host_mb->mtext, ret);
2902 unlock_user(target_mtext, target_mtext_addr, ret);
2903 }
2904
2905 target_mb->mtype = tswapal(host_mb->mtype);
2906
2907end:
2908 if (target_mb)
2909 unlock_user_struct(target_mb, msgp, 1);
2910 g_free(host_mb);
2911 return ret;
2912}
2913
2914static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
2915 abi_ulong target_addr)
2916{
2917 struct target_shmid_ds *target_sd;
2918
2919 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2920 return -TARGET_EFAULT;
2921 if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr))
2922 return -TARGET_EFAULT;
2923 __get_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2924 __get_user(host_sd->shm_atime, &target_sd->shm_atime);
2925 __get_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2926 __get_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2927 __get_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2928 __get_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2929 __get_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2930 unlock_user_struct(target_sd, target_addr, 0);
2931 return 0;
2932}
2933
2934static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
2935 struct shmid_ds *host_sd)
2936{
2937 struct target_shmid_ds *target_sd;
2938
2939 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2940 return -TARGET_EFAULT;
2941 if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm)))
2942 return -TARGET_EFAULT;
2943 __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2944 __put_user(host_sd->shm_atime, &target_sd->shm_atime);
2945 __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2946 __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2947 __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2948 __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2949 __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2950 unlock_user_struct(target_sd, target_addr, 1);
2951 return 0;
2952}
2953
2954struct target_shminfo {
2955 abi_ulong shmmax;
2956 abi_ulong shmmin;
2957 abi_ulong shmmni;
2958 abi_ulong shmseg;
2959 abi_ulong shmall;
2960};
2961
2962static inline abi_long host_to_target_shminfo(abi_ulong target_addr,
2963 struct shminfo *host_shminfo)
2964{
2965 struct target_shminfo *target_shminfo;
2966 if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0))
2967 return -TARGET_EFAULT;
2968 __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
2969 __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
2970 __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
2971 __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
2972 __put_user(host_shminfo->shmall, &target_shminfo->shmall);
2973 unlock_user_struct(target_shminfo, target_addr, 1);
2974 return 0;
2975}
2976
2977struct target_shm_info {
2978 int used_ids;
2979 abi_ulong shm_tot;
2980 abi_ulong shm_rss;
2981 abi_ulong shm_swp;
2982 abi_ulong swap_attempts;
2983 abi_ulong swap_successes;
2984};
2985
2986static inline abi_long host_to_target_shm_info(abi_ulong target_addr,
2987 struct shm_info *host_shm_info)
2988{
2989 struct target_shm_info *target_shm_info;
2990 if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0))
2991 return -TARGET_EFAULT;
2992 __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
2993 __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
2994 __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
2995 __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
2996 __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts);
2997 __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes);
2998 unlock_user_struct(target_shm_info, target_addr, 1);
2999 return 0;
3000}
3001
3002static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
3003{
3004 struct shmid_ds dsarg;
3005 struct shminfo shminfo;
3006 struct shm_info shm_info;
3007 abi_long ret = -TARGET_EINVAL;
3008
3009 cmd &= 0xff;
3010
3011 switch(cmd) {
3012 case IPC_STAT:
3013 case IPC_SET:
3014 case SHM_STAT:
3015 if (target_to_host_shmid_ds(&dsarg, buf))
3016 return -TARGET_EFAULT;
3017 ret = get_errno(shmctl(shmid, cmd, &dsarg));
3018 if (host_to_target_shmid_ds(buf, &dsarg))
3019 return -TARGET_EFAULT;
3020 break;
3021 case IPC_INFO:
3022 ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
3023 if (host_to_target_shminfo(buf, &shminfo))
3024 return -TARGET_EFAULT;
3025 break;
3026 case SHM_INFO:
3027 ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
3028 if (host_to_target_shm_info(buf, &shm_info))
3029 return -TARGET_EFAULT;
3030 break;
3031 case IPC_RMID:
3032 case SHM_LOCK:
3033 case SHM_UNLOCK:
3034 ret = get_errno(shmctl(shmid, cmd, NULL));
3035 break;
3036 }
3037
3038 return ret;
3039}
3040
3041static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
3042{
3043 abi_long raddr;
3044 void *host_raddr;
3045 struct shmid_ds shm_info;
3046 int i,ret;
3047
3048
3049 ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
3050 if (is_error(ret)) {
3051
3052 return ret;
3053 }
3054
3055 mmap_lock();
3056
3057 if (shmaddr)
3058 host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
3059 else {
3060 abi_ulong mmap_start;
3061
3062 mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
3063
3064 if (mmap_start == -1) {
3065 errno = ENOMEM;
3066 host_raddr = (void *)-1;
3067 } else
3068 host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);
3069 }
3070
3071 if (host_raddr == (void *)-1) {
3072 mmap_unlock();
3073 return get_errno((long)host_raddr);
3074 }
3075 raddr=h2g((unsigned long)host_raddr);
3076
3077 page_set_flags(raddr, raddr + shm_info.shm_segsz,
3078 PAGE_VALID | PAGE_READ |
3079 ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
3080
3081 for (i = 0; i < N_SHM_REGIONS; i++) {
3082 if (shm_regions[i].start == 0) {
3083 shm_regions[i].start = raddr;
3084 shm_regions[i].size = shm_info.shm_segsz;
3085 break;
3086 }
3087 }
3088
3089 mmap_unlock();
3090 return raddr;
3091
3092}
3093
3094static inline abi_long do_shmdt(abi_ulong shmaddr)
3095{
3096 int i;
3097
3098 for (i = 0; i < N_SHM_REGIONS; ++i) {
3099 if (shm_regions[i].start == shmaddr) {
3100 shm_regions[i].start = 0;
3101 page_set_flags(shmaddr, shmaddr + shm_regions[i].size, 0);
3102 break;
3103 }
3104 }
3105
3106 return get_errno(shmdt(g2h(shmaddr)));
3107}
3108
3109#ifdef TARGET_NR_ipc
3110
3111
3112static abi_long do_ipc(unsigned int call, int first,
3113 int second, int third,
3114 abi_long ptr, abi_long fifth)
3115{
3116 int version;
3117 abi_long ret = 0;
3118
3119 version = call >> 16;
3120 call &= 0xffff;
3121
3122 switch (call) {
3123 case IPCOP_semop:
3124 ret = do_semop(first, ptr, second);
3125 break;
3126
3127 case IPCOP_semget:
3128 ret = get_errno(semget(first, second, third));
3129 break;
3130
3131 case IPCOP_semctl:
3132 ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr);
3133 break;
3134
3135 case IPCOP_msgget:
3136 ret = get_errno(msgget(first, second));
3137 break;
3138
3139 case IPCOP_msgsnd:
3140 ret = do_msgsnd(first, ptr, second, third);
3141 break;
3142
3143 case IPCOP_msgctl:
3144 ret = do_msgctl(first, second, ptr);
3145 break;
3146
3147 case IPCOP_msgrcv:
3148 switch (version) {
3149 case 0:
3150 {
3151 struct target_ipc_kludge {
3152 abi_long msgp;
3153 abi_long msgtyp;
3154 } *tmp;
3155
3156 if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
3157 ret = -TARGET_EFAULT;
3158 break;
3159 }
3160
3161 ret = do_msgrcv(first, tswapal(tmp->msgp), second, tswapal(tmp->msgtyp), third);
3162
3163 unlock_user_struct(tmp, ptr, 0);
3164 break;
3165 }
3166 default:
3167 ret = do_msgrcv(first, ptr, second, fifth, third);
3168 }
3169 break;
3170
3171 case IPCOP_shmat:
3172 switch (version) {
3173 default:
3174 {
3175 abi_ulong raddr;
3176 raddr = do_shmat(first, ptr, second);
3177 if (is_error(raddr))
3178 return get_errno(raddr);
3179 if (put_user_ual(raddr, third))
3180 return -TARGET_EFAULT;
3181 break;
3182 }
3183 case 1:
3184 ret = -TARGET_EINVAL;
3185 break;
3186 }
3187 break;
3188 case IPCOP_shmdt:
3189 ret = do_shmdt(ptr);
3190 break;
3191
3192 case IPCOP_shmget:
3193
3194 ret = get_errno(shmget(first, second, third));
3195 break;
3196
3197
3198 case IPCOP_shmctl:
3199 ret = do_shmctl(first, second, ptr);
3200 break;
3201 default:
3202 gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
3203 ret = -TARGET_ENOSYS;
3204 break;
3205 }
3206 return ret;
3207}
3208#endif
3209
3210
3211
3212#define STRUCT(name, ...) STRUCT_ ## name,
3213#define STRUCT_SPECIAL(name) STRUCT_ ## name,
3214enum {
3215#include "syscall_types.h"
3216};
3217#undef STRUCT
3218#undef STRUCT_SPECIAL
3219
3220#define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = { __VA_ARGS__, TYPE_NULL };
3221#define STRUCT_SPECIAL(name)
3222#include "syscall_types.h"
3223#undef STRUCT
3224#undef STRUCT_SPECIAL
3225
3226typedef struct IOCTLEntry IOCTLEntry;
3227
3228typedef abi_long do_ioctl_fn(const IOCTLEntry *ie, uint8_t *buf_temp,
3229 int fd, abi_long cmd, abi_long arg);
3230
3231struct IOCTLEntry {
3232 unsigned int target_cmd;
3233 unsigned int host_cmd;
3234 const char *name;
3235 int access;
3236 do_ioctl_fn *do_ioctl;
3237 const argtype arg_type[5];
3238};
3239
3240#define IOC_R 0x0001
3241#define IOC_W 0x0002
3242#define IOC_RW (IOC_R | IOC_W)
3243
3244#define MAX_STRUCT_SIZE 4096
3245
3246#ifdef CONFIG_FIEMAP
3247
3248
3249
3250
3251#define FIEMAP_MAX_EXTENTS ((UINT_MAX - sizeof(struct fiemap)) \
3252 / sizeof(struct fiemap_extent))
3253
3254static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp,
3255 int fd, abi_long cmd, abi_long arg)
3256{
3257
3258
3259
3260
3261
3262 int target_size_in, target_size_out;
3263 struct fiemap *fm;
3264 const argtype *arg_type = ie->arg_type;
3265 const argtype extent_arg_type[] = { MK_STRUCT(STRUCT_fiemap_extent) };
3266 void *argptr, *p;
3267 abi_long ret;
3268 int i, extent_size = thunk_type_size(extent_arg_type, 0);
3269 uint32_t outbufsz;
3270 int free_fm = 0;
3271
3272 assert(arg_type[0] == TYPE_PTR);
3273 assert(ie->access == IOC_RW);
3274 arg_type++;
3275 target_size_in = thunk_type_size(arg_type, 0);
3276 argptr = lock_user(VERIFY_READ, arg, target_size_in, 1);
3277 if (!argptr) {
3278 return -TARGET_EFAULT;
3279 }
3280 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3281 unlock_user(argptr, arg, 0);
3282 fm = (struct fiemap *)buf_temp;
3283 if (fm->fm_extent_count > FIEMAP_MAX_EXTENTS) {
3284 return -TARGET_EINVAL;
3285 }
3286
3287 outbufsz = sizeof (*fm) +
3288 (sizeof(struct fiemap_extent) * fm->fm_extent_count);
3289
3290 if (outbufsz > MAX_STRUCT_SIZE) {
3291
3292
3293
3294 fm = malloc(outbufsz);
3295 if (!fm) {
3296 return -TARGET_ENOMEM;
3297 }
3298 memcpy(fm, buf_temp, sizeof(struct fiemap));
3299 free_fm = 1;
3300 }
3301 ret = get_errno(ioctl(fd, ie->host_cmd, fm));
3302 if (!is_error(ret)) {
3303 target_size_out = target_size_in;
3304
3305
3306
3307 if (fm->fm_extent_count != 0) {
3308 target_size_out += fm->fm_mapped_extents * extent_size;
3309 }
3310 argptr = lock_user(VERIFY_WRITE, arg, target_size_out, 0);
3311 if (!argptr) {
3312 ret = -TARGET_EFAULT;
3313 } else {
3314
3315 thunk_convert(argptr, fm, arg_type, THUNK_TARGET);
3316 if (fm->fm_extent_count != 0) {
3317 p = argptr + target_size_in;
3318
3319 for (i = 0; i < fm->fm_mapped_extents; i++) {
3320 thunk_convert(p, &fm->fm_extents[i], extent_arg_type,
3321 THUNK_TARGET);
3322 p += extent_size;
3323 }
3324 }
3325 unlock_user(argptr, arg, target_size_out);
3326 }
3327 }
3328 if (free_fm) {
3329 free(fm);
3330 }
3331 return ret;
3332}
3333#endif
3334
3335static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp,
3336 int fd, abi_long cmd, abi_long arg)
3337{
3338 const argtype *arg_type = ie->arg_type;
3339 int target_size;
3340 void *argptr;
3341 int ret;
3342 struct ifconf *host_ifconf;
3343 uint32_t outbufsz;
3344 const argtype ifreq_arg_type[] = { MK_STRUCT(STRUCT_sockaddr_ifreq) };
3345 int target_ifreq_size;
3346 int nb_ifreq;
3347 int free_buf = 0;
3348 int i;
3349 int target_ifc_len;
3350 abi_long target_ifc_buf;
3351 int host_ifc_len;
3352 char *host_ifc_buf;
3353
3354 assert(arg_type[0] == TYPE_PTR);
3355 assert(ie->access == IOC_RW);
3356
3357 arg_type++;
3358 target_size = thunk_type_size(arg_type, 0);
3359
3360 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3361 if (!argptr)
3362 return -TARGET_EFAULT;
3363 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3364 unlock_user(argptr, arg, 0);
3365
3366 host_ifconf = (struct ifconf *)(unsigned long)buf_temp;
3367 target_ifc_len = host_ifconf->ifc_len;
3368 target_ifc_buf = (abi_long)(unsigned long)host_ifconf->ifc_buf;
3369
3370 target_ifreq_size = thunk_type_size(ifreq_arg_type, 0);
3371 nb_ifreq = target_ifc_len / target_ifreq_size;
3372 host_ifc_len = nb_ifreq * sizeof(struct ifreq);
3373
3374 outbufsz = sizeof(*host_ifconf) + host_ifc_len;
3375 if (outbufsz > MAX_STRUCT_SIZE) {
3376
3377
3378
3379 host_ifconf = malloc(outbufsz);
3380 if (!host_ifconf) {
3381 return -TARGET_ENOMEM;
3382 }
3383 memcpy(host_ifconf, buf_temp, sizeof(*host_ifconf));
3384 free_buf = 1;
3385 }
3386 host_ifc_buf = (char*)host_ifconf + sizeof(*host_ifconf);
3387
3388 host_ifconf->ifc_len = host_ifc_len;
3389 host_ifconf->ifc_buf = host_ifc_buf;
3390
3391 ret = get_errno(ioctl(fd, ie->host_cmd, host_ifconf));
3392 if (!is_error(ret)) {
3393
3394
3395 nb_ifreq = host_ifconf->ifc_len / sizeof(struct ifreq);
3396 target_ifc_len = nb_ifreq * target_ifreq_size;
3397 host_ifconf->ifc_len = target_ifc_len;
3398
3399
3400
3401 host_ifconf->ifc_buf = (char *)(unsigned long)target_ifc_buf;
3402
3403
3404
3405 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3406 if (!argptr)
3407 return -TARGET_EFAULT;
3408 thunk_convert(argptr, host_ifconf, arg_type, THUNK_TARGET);
3409 unlock_user(argptr, arg, target_size);
3410
3411
3412
3413 argptr = lock_user(VERIFY_WRITE, target_ifc_buf, target_ifc_len, 0);
3414 for (i = 0; i < nb_ifreq ; i++) {
3415 thunk_convert(argptr + i * target_ifreq_size,
3416 host_ifc_buf + i * sizeof(struct ifreq),
3417 ifreq_arg_type, THUNK_TARGET);
3418 }
3419 unlock_user(argptr, target_ifc_buf, target_ifc_len);
3420 }
3421
3422 if (free_buf) {
3423 free(host_ifconf);
3424 }
3425
3426 return ret;
3427}
3428
3429static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
3430 abi_long cmd, abi_long arg)
3431{
3432 void *argptr;
3433 struct dm_ioctl *host_dm;
3434 abi_long guest_data;
3435 uint32_t guest_data_size;
3436 int target_size;
3437 const argtype *arg_type = ie->arg_type;
3438 abi_long ret;
3439 void *big_buf = NULL;
3440 char *host_data;
3441
3442 arg_type++;
3443 target_size = thunk_type_size(arg_type, 0);
3444 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3445 if (!argptr) {
3446 ret = -TARGET_EFAULT;
3447 goto out;
3448 }
3449 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3450 unlock_user(argptr, arg, 0);
3451
3452
3453 big_buf = g_malloc0(((struct dm_ioctl*)buf_temp)->data_size * 2);
3454 memcpy(big_buf, buf_temp, target_size);
3455 buf_temp = big_buf;
3456 host_dm = big_buf;
3457
3458 guest_data = arg + host_dm->data_start;
3459 if ((guest_data - arg) < 0) {
3460 ret = -EINVAL;
3461 goto out;
3462 }
3463 guest_data_size = host_dm->data_size - host_dm->data_start;
3464 host_data = (char*)host_dm + host_dm->data_start;
3465
3466 argptr = lock_user(VERIFY_READ, guest_data, guest_data_size, 1);
3467 switch (ie->host_cmd) {
3468 case DM_REMOVE_ALL:
3469 case DM_LIST_DEVICES:
3470 case DM_DEV_CREATE:
3471 case DM_DEV_REMOVE:
3472 case DM_DEV_SUSPEND:
3473 case DM_DEV_STATUS:
3474 case DM_DEV_WAIT:
3475 case DM_TABLE_STATUS:
3476 case DM_TABLE_CLEAR:
3477 case DM_TABLE_DEPS:
3478 case DM_LIST_VERSIONS:
3479
3480 break;
3481 case DM_DEV_RENAME:
3482 case DM_DEV_SET_GEOMETRY:
3483
3484 memcpy(host_data, argptr, guest_data_size);
3485 break;
3486 case DM_TARGET_MSG:
3487 memcpy(host_data, argptr, guest_data_size);
3488 *(uint64_t*)host_data = tswap64(*(uint64_t*)argptr);
3489 break;
3490 case DM_TABLE_LOAD:
3491 {
3492 void *gspec = argptr;
3493 void *cur_data = host_data;
3494 const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };
3495 int spec_size = thunk_type_size(arg_type, 0);
3496 int i;
3497
3498 for (i = 0; i < host_dm->target_count; i++) {
3499 struct dm_target_spec *spec = cur_data;
3500 uint32_t next;
3501 int slen;
3502
3503 thunk_convert(spec, gspec, arg_type, THUNK_HOST);
3504 slen = strlen((char*)gspec + spec_size) + 1;
3505 next = spec->next;
3506 spec->next = sizeof(*spec) + slen;
3507 strcpy((char*)&spec[1], gspec + spec_size);
3508 gspec += next;
3509 cur_data += spec->next;
3510 }
3511 break;
3512 }
3513 default:
3514 ret = -TARGET_EINVAL;
3515 goto out;
3516 }
3517 unlock_user(argptr, guest_data, 0);
3518
3519 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3520 if (!is_error(ret)) {
3521 guest_data = arg + host_dm->data_start;
3522 guest_data_size = host_dm->data_size - host_dm->data_start;
3523 argptr = lock_user(VERIFY_WRITE, guest_data, guest_data_size, 0);
3524 switch (ie->host_cmd) {
3525 case DM_REMOVE_ALL:
3526 case DM_DEV_CREATE:
3527 case DM_DEV_REMOVE:
3528 case DM_DEV_RENAME:
3529 case DM_DEV_SUSPEND:
3530 case DM_DEV_STATUS:
3531 case DM_TABLE_LOAD:
3532 case DM_TABLE_CLEAR:
3533 case DM_TARGET_MSG:
3534 case DM_DEV_SET_GEOMETRY:
3535
3536 break;
3537 case DM_LIST_DEVICES:
3538 {
3539 struct dm_name_list *nl = (void*)host_dm + host_dm->data_start;
3540 uint32_t remaining_data = guest_data_size;
3541 void *cur_data = argptr;
3542 const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_name_list) };
3543 int nl_size = 12;
3544
3545 while (1) {
3546 uint32_t next = nl->next;
3547 if (next) {
3548 nl->next = nl_size + (strlen(nl->name) + 1);
3549 }
3550 if (remaining_data < nl->next) {
3551 host_dm->flags |= DM_BUFFER_FULL_FLAG;
3552 break;
3553 }
3554 thunk_convert(cur_data, nl, arg_type, THUNK_TARGET);
3555 strcpy(cur_data + nl_size, nl->name);
3556 cur_data += nl->next;
3557 remaining_data -= nl->next;
3558 if (!next) {
3559 break;
3560 }
3561 nl = (void*)nl + next;
3562 }
3563 break;
3564 }
3565 case DM_DEV_WAIT:
3566 case DM_TABLE_STATUS:
3567 {
3568 struct dm_target_spec *spec = (void*)host_dm + host_dm->data_start;
3569 void *cur_data = argptr;
3570 const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };
3571 int spec_size = thunk_type_size(arg_type, 0);
3572 int i;
3573
3574 for (i = 0; i < host_dm->target_count; i++) {
3575 uint32_t next = spec->next;
3576 int slen = strlen((char*)&spec[1]) + 1;
3577 spec->next = (cur_data - argptr) + spec_size + slen;
3578 if (guest_data_size < spec->next) {
3579 host_dm->flags |= DM_BUFFER_FULL_FLAG;
3580 break;
3581 }
3582 thunk_convert(cur_data, spec, arg_type, THUNK_TARGET);
3583 strcpy(cur_data + spec_size, (char*)&spec[1]);
3584 cur_data = argptr + spec->next;
3585 spec = (void*)host_dm + host_dm->data_start + next;
3586 }
3587 break;
3588 }
3589 case DM_TABLE_DEPS:
3590 {
3591 void *hdata = (void*)host_dm + host_dm->data_start;
3592 int count = *(uint32_t*)hdata;
3593 uint64_t *hdev = hdata + 8;
3594 uint64_t *gdev = argptr + 8;
3595 int i;
3596
3597 *(uint32_t*)argptr = tswap32(count);
3598 for (i = 0; i < count; i++) {
3599 *gdev = tswap64(*hdev);
3600 gdev++;
3601 hdev++;
3602 }
3603 break;
3604 }
3605 case DM_LIST_VERSIONS:
3606 {
3607 struct dm_target_versions *vers = (void*)host_dm + host_dm->data_start;
3608 uint32_t remaining_data = guest_data_size;
3609 void *cur_data = argptr;
3610 const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_versions) };
3611 int vers_size = thunk_type_size(arg_type, 0);
3612
3613 while (1) {
3614 uint32_t next = vers->next;
3615 if (next) {
3616 vers->next = vers_size + (strlen(vers->name) + 1);
3617 }
3618 if (remaining_data < vers->next) {
3619 host_dm->flags |= DM_BUFFER_FULL_FLAG;
3620 break;
3621 }
3622 thunk_convert(cur_data, vers, arg_type, THUNK_TARGET);
3623 strcpy(cur_data + vers_size, vers->name);
3624 cur_data += vers->next;
3625 remaining_data -= vers->next;
3626 if (!next) {
3627 break;
3628 }
3629 vers = (void*)vers + next;
3630 }
3631 break;
3632 }
3633 default:
3634 ret = -TARGET_EINVAL;
3635 goto out;
3636 }
3637 unlock_user(argptr, guest_data, guest_data_size);
3638
3639 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3640 if (!argptr) {
3641 ret = -TARGET_EFAULT;
3642 goto out;
3643 }
3644 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
3645 unlock_user(argptr, arg, target_size);
3646 }
3647out:
3648 g_free(big_buf);
3649 return ret;
3650}
3651
3652static abi_long do_ioctl_rt(const IOCTLEntry *ie, uint8_t *buf_temp,
3653 int fd, abi_long cmd, abi_long arg)
3654{
3655 const argtype *arg_type = ie->arg_type;
3656 const StructEntry *se;
3657 const argtype *field_types;
3658 const int *dst_offsets, *src_offsets;
3659 int target_size;
3660 void *argptr;
3661 abi_ulong *target_rt_dev_ptr;
3662 unsigned long *host_rt_dev_ptr;
3663 abi_long ret;
3664 int i;
3665
3666 assert(ie->access == IOC_W);
3667 assert(*arg_type == TYPE_PTR);
3668 arg_type++;
3669 assert(*arg_type == TYPE_STRUCT);
3670 target_size = thunk_type_size(arg_type, 0);
3671 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3672 if (!argptr) {
3673 return -TARGET_EFAULT;
3674 }
3675 arg_type++;
3676 assert(*arg_type == (int)STRUCT_rtentry);
3677 se = struct_entries + *arg_type++;
3678 assert(se->convert[0] == NULL);
3679
3680 field_types = se->field_types;
3681 dst_offsets = se->field_offsets[THUNK_HOST];
3682 src_offsets = se->field_offsets[THUNK_TARGET];
3683 for (i = 0; i < se->nb_fields; i++) {
3684 if (dst_offsets[i] == offsetof(struct rtentry, rt_dev)) {
3685 assert(*field_types == TYPE_PTRVOID);
3686 target_rt_dev_ptr = (abi_ulong *)(argptr + src_offsets[i]);
3687 host_rt_dev_ptr = (unsigned long *)(buf_temp + dst_offsets[i]);
3688 if (*target_rt_dev_ptr != 0) {
3689 *host_rt_dev_ptr = (unsigned long)lock_user_string(
3690 tswapal(*target_rt_dev_ptr));
3691 if (!*host_rt_dev_ptr) {
3692 unlock_user(argptr, arg, 0);
3693 return -TARGET_EFAULT;
3694 }
3695 } else {
3696 *host_rt_dev_ptr = 0;
3697 }
3698 field_types++;
3699 continue;
3700 }
3701 field_types = thunk_convert(buf_temp + dst_offsets[i],
3702 argptr + src_offsets[i],
3703 field_types, THUNK_HOST);
3704 }
3705 unlock_user(argptr, arg, 0);
3706
3707 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3708 if (*host_rt_dev_ptr != 0) {
3709 unlock_user((void *)*host_rt_dev_ptr,
3710 *target_rt_dev_ptr, 0);
3711 }
3712 return ret;
3713}
3714
3715static IOCTLEntry ioctl_entries[] = {
3716#define IOCTL(cmd, access, ...) \
3717 { TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } },
3718#define IOCTL_SPECIAL(cmd, access, dofn, ...) \
3719 { TARGET_ ## cmd, cmd, #cmd, access, dofn, { __VA_ARGS__ } },
3720#include "ioctls.h"
3721 { 0, 0, },
3722};
3723
3724
3725
3726static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
3727{
3728 const IOCTLEntry *ie;
3729 const argtype *arg_type;
3730 abi_long ret;
3731 uint8_t buf_temp[MAX_STRUCT_SIZE];
3732 int target_size;
3733 void *argptr;
3734
3735 ie = ioctl_entries;
3736 for(;;) {
3737 if (ie->target_cmd == 0) {
3738 gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
3739 return -TARGET_ENOSYS;
3740 }
3741 if (ie->target_cmd == cmd)
3742 break;
3743 ie++;
3744 }
3745 arg_type = ie->arg_type;
3746#if defined(DEBUG)
3747 gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
3748#endif
3749 if (ie->do_ioctl) {
3750 return ie->do_ioctl(ie, buf_temp, fd, cmd, arg);
3751 }
3752
3753 switch(arg_type[0]) {
3754 case TYPE_NULL:
3755
3756 ret = get_errno(ioctl(fd, ie->host_cmd));
3757 break;
3758 case TYPE_PTRVOID:
3759 case TYPE_INT:
3760
3761 ret = get_errno(ioctl(fd, ie->host_cmd, arg));
3762 break;
3763 case TYPE_PTR:
3764 arg_type++;
3765 target_size = thunk_type_size(arg_type, 0);
3766 switch(ie->access) {
3767 case IOC_R:
3768 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3769 if (!is_error(ret)) {
3770 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3771 if (!argptr)
3772 return -TARGET_EFAULT;
3773 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
3774 unlock_user(argptr, arg, target_size);
3775 }
3776 break;
3777 case IOC_W:
3778 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3779 if (!argptr)
3780 return -TARGET_EFAULT;
3781 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3782 unlock_user(argptr, arg, 0);
3783 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3784 break;
3785 default:
3786 case IOC_RW:
3787 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3788 if (!argptr)
3789 return -TARGET_EFAULT;
3790 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3791 unlock_user(argptr, arg, 0);
3792 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3793 if (!is_error(ret)) {
3794 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3795 if (!argptr)
3796 return -TARGET_EFAULT;
3797 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
3798 unlock_user(argptr, arg, target_size);
3799 }
3800 break;
3801 }
3802 break;
3803 default:
3804 gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
3805 (long)cmd, arg_type[0]);
3806 ret = -TARGET_ENOSYS;
3807 break;
3808 }
3809 return ret;
3810}
3811
3812static const bitmask_transtbl iflag_tbl[] = {
3813 { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
3814 { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
3815 { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
3816 { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
3817 { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
3818 { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
3819 { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
3820 { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
3821 { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
3822 { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
3823 { TARGET_IXON, TARGET_IXON, IXON, IXON },
3824 { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
3825 { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
3826 { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
3827 { 0, 0, 0, 0 }
3828};
3829
3830static const bitmask_transtbl oflag_tbl[] = {
3831 { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
3832 { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
3833 { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
3834 { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
3835 { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
3836 { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
3837 { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
3838 { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
3839 { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
3840 { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
3841 { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
3842 { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
3843 { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
3844 { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
3845 { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
3846 { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
3847 { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
3848 { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
3849 { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
3850 { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
3851 { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
3852 { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
3853 { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
3854 { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
3855 { 0, 0, 0, 0 }
3856};
3857
3858static const bitmask_transtbl cflag_tbl[] = {
3859 { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
3860 { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
3861 { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
3862 { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
3863 { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
3864 { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
3865 { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
3866 { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
3867 { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
3868 { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
3869 { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
3870 { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
3871 { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
3872 { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
3873 { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
3874 { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
3875 { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
3876 { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
3877 { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
3878 { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
3879 { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
3880 { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
3881 { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
3882 { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
3883 { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
3884 { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
3885 { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
3886 { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
3887 { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
3888 { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
3889 { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
3890 { 0, 0, 0, 0 }
3891};
3892
3893static const bitmask_transtbl lflag_tbl[] = {
3894 { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
3895 { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
3896 { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
3897 { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
3898 { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
3899 { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
3900 { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
3901 { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
3902 { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
3903 { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
3904 { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
3905 { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
3906 { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
3907 { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
3908 { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
3909 { 0, 0, 0, 0 }
3910};
3911
3912static void target_to_host_termios (void *dst, const void *src)
3913{
3914 struct host_termios *host = dst;
3915 const struct target_termios *target = src;
3916
3917 host->c_iflag =
3918 target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
3919 host->c_oflag =
3920 target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
3921 host->c_cflag =
3922 target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
3923 host->c_lflag =
3924 target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
3925 host->c_line = target->c_line;
3926
3927 memset(host->c_cc, 0, sizeof(host->c_cc));
3928 host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
3929 host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
3930 host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
3931 host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
3932 host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
3933 host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
3934 host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
3935 host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
3936 host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
3937 host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
3938 host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
3939 host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
3940 host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
3941 host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
3942 host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
3943 host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
3944 host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
3945}
3946
3947static void host_to_target_termios (void *dst, const void *src)
3948{
3949 struct target_termios *target = dst;
3950 const struct host_termios *host = src;
3951
3952 target->c_iflag =
3953 tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
3954 target->c_oflag =
3955 tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
3956 target->c_cflag =
3957 tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
3958 target->c_lflag =
3959 tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
3960 target->c_line = host->c_line;
3961
3962 memset(target->c_cc, 0, sizeof(target->c_cc));
3963 target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
3964 target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
3965 target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
3966 target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
3967 target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
3968 target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
3969 target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
3970 target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
3971 target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
3972 target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
3973 target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
3974 target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
3975 target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
3976 target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
3977 target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
3978 target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
3979 target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
3980}
3981
3982static const StructEntry struct_termios_def = {
3983 .convert = { host_to_target_termios, target_to_host_termios },
3984 .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
3985 .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
3986};
3987
3988static bitmask_transtbl mmap_flags_tbl[] = {
3989 { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
3990 { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
3991 { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
3992 { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
3993 { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
3994 { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
3995 { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
3996 { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
3997 { 0, 0, 0, 0 }
3998};
3999
4000#if defined(TARGET_I386)
4001
4002
4003static uint8_t *ldt_table;
4004
4005static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
4006{
4007 int size;
4008 void *p;
4009
4010 if (!ldt_table)
4011 return 0;
4012 size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
4013 if (size > bytecount)
4014 size = bytecount;
4015 p = lock_user(VERIFY_WRITE, ptr, size, 0);
4016 if (!p)
4017 return -TARGET_EFAULT;
4018
4019 memcpy(p, ldt_table, size);
4020 unlock_user(p, ptr, size);
4021 return size;
4022}
4023
4024
4025static abi_long write_ldt(CPUX86State *env,
4026 abi_ulong ptr, unsigned long bytecount, int oldmode)
4027{
4028 struct target_modify_ldt_ldt_s ldt_info;
4029 struct target_modify_ldt_ldt_s *target_ldt_info;
4030 int seg_32bit, contents, read_exec_only, limit_in_pages;
4031 int seg_not_present, useable, lm;
4032 uint32_t *lp, entry_1, entry_2;
4033
4034 if (bytecount != sizeof(ldt_info))
4035 return -TARGET_EINVAL;
4036 if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
4037 return -TARGET_EFAULT;
4038 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
4039 ldt_info.base_addr = tswapal(target_ldt_info->base_addr);
4040 ldt_info.limit = tswap32(target_ldt_info->limit);
4041 ldt_info.flags = tswap32(target_ldt_info->flags);
4042 unlock_user_struct(target_ldt_info, ptr, 0);
4043
4044 if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
4045 return -TARGET_EINVAL;
4046 seg_32bit = ldt_info.flags & 1;
4047 contents = (ldt_info.flags >> 1) & 3;
4048 read_exec_only = (ldt_info.flags >> 3) & 1;
4049 limit_in_pages = (ldt_info.flags >> 4) & 1;
4050 seg_not_present = (ldt_info.flags >> 5) & 1;
4051 useable = (ldt_info.flags >> 6) & 1;
4052#ifdef TARGET_ABI32
4053 lm = 0;
4054#else
4055 lm = (ldt_info.flags >> 7) & 1;
4056#endif
4057 if (contents == 3) {
4058 if (oldmode)
4059 return -TARGET_EINVAL;
4060 if (seg_not_present == 0)
4061 return -TARGET_EINVAL;
4062 }
4063
4064 if (!ldt_table) {
4065 env->ldt.base = target_mmap(0,
4066 TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
4067 PROT_READ|PROT_WRITE,
4068 MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
4069 if (env->ldt.base == -1)
4070 return -TARGET_ENOMEM;
4071 memset(g2h(env->ldt.base), 0,
4072 TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
4073 env->ldt.limit = 0xffff;
4074 ldt_table = g2h(env->ldt.base);
4075 }
4076
4077
4078
4079 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
4080 if (oldmode ||
4081 (contents == 0 &&
4082 read_exec_only == 1 &&
4083 seg_32bit == 0 &&
4084 limit_in_pages == 0 &&
4085 seg_not_present == 1 &&
4086 useable == 0 )) {
4087 entry_1 = 0;
4088 entry_2 = 0;
4089 goto install;
4090 }
4091 }
4092
4093 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
4094 (ldt_info.limit & 0x0ffff);
4095 entry_2 = (ldt_info.base_addr & 0xff000000) |
4096 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
4097 (ldt_info.limit & 0xf0000) |
4098 ((read_exec_only ^ 1) << 9) |
4099 (contents << 10) |
4100 ((seg_not_present ^ 1) << 15) |
4101 (seg_32bit << 22) |
4102 (limit_in_pages << 23) |
4103 (lm << 21) |
4104 0x7000;
4105 if (!oldmode)
4106 entry_2 |= (useable << 20);
4107
4108
4109install:
4110 lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
4111 lp[0] = tswap32(entry_1);
4112 lp[1] = tswap32(entry_2);
4113 return 0;
4114}
4115
4116
4117static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
4118 unsigned long bytecount)
4119{
4120 abi_long ret;
4121
4122 switch (func) {
4123 case 0:
4124 ret = read_ldt(ptr, bytecount);
4125 break;
4126 case 1:
4127 ret = write_ldt(env, ptr, bytecount, 1);
4128 break;
4129 case 0x11:
4130 ret = write_ldt(env, ptr, bytecount, 0);
4131 break;
4132 default:
4133 ret = -TARGET_ENOSYS;
4134 break;
4135 }
4136 return ret;
4137}
4138
4139#if defined(TARGET_I386) && defined(TARGET_ABI32)
4140abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
4141{
4142 uint64_t *gdt_table = g2h(env->gdt.base);
4143 struct target_modify_ldt_ldt_s ldt_info;
4144 struct target_modify_ldt_ldt_s *target_ldt_info;
4145 int seg_32bit, contents, read_exec_only, limit_in_pages;
4146 int seg_not_present, useable, lm;
4147 uint32_t *lp, entry_1, entry_2;
4148 int i;
4149
4150 lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
4151 if (!target_ldt_info)
4152 return -TARGET_EFAULT;
4153 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
4154 ldt_info.base_addr = tswapal(target_ldt_info->base_addr);
4155 ldt_info.limit = tswap32(target_ldt_info->limit);
4156 ldt_info.flags = tswap32(target_ldt_info->flags);
4157 if (ldt_info.entry_number == -1) {
4158 for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
4159 if (gdt_table[i] == 0) {
4160 ldt_info.entry_number = i;
4161 target_ldt_info->entry_number = tswap32(i);
4162 break;
4163 }
4164 }
4165 }
4166 unlock_user_struct(target_ldt_info, ptr, 1);
4167
4168 if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN ||
4169 ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
4170 return -TARGET_EINVAL;
4171 seg_32bit = ldt_info.flags & 1;
4172 contents = (ldt_info.flags >> 1) & 3;
4173 read_exec_only = (ldt_info.flags >> 3) & 1;
4174 limit_in_pages = (ldt_info.flags >> 4) & 1;
4175 seg_not_present = (ldt_info.flags >> 5) & 1;
4176 useable = (ldt_info.flags >> 6) & 1;
4177#ifdef TARGET_ABI32
4178 lm = 0;
4179#else
4180 lm = (ldt_info.flags >> 7) & 1;
4181#endif
4182
4183 if (contents == 3) {
4184 if (seg_not_present == 0)
4185 return -TARGET_EINVAL;
4186 }
4187
4188
4189
4190 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
4191 if ((contents == 0 &&
4192 read_exec_only == 1 &&
4193 seg_32bit == 0 &&
4194 limit_in_pages == 0 &&
4195 seg_not_present == 1 &&
4196 useable == 0 )) {
4197 entry_1 = 0;
4198 entry_2 = 0;
4199 goto install;
4200 }
4201 }
4202
4203 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
4204 (ldt_info.limit & 0x0ffff);
4205 entry_2 = (ldt_info.base_addr & 0xff000000) |
4206 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
4207 (ldt_info.limit & 0xf0000) |
4208 ((read_exec_only ^ 1) << 9) |
4209 (contents << 10) |
4210 ((seg_not_present ^ 1) << 15) |
4211 (seg_32bit << 22) |
4212 (limit_in_pages << 23) |
4213 (useable << 20) |
4214 (lm << 21) |
4215 0x7000;
4216
4217
4218install:
4219 lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
4220 lp[0] = tswap32(entry_1);
4221 lp[1] = tswap32(entry_2);
4222 return 0;
4223}
4224
4225static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
4226{
4227 struct target_modify_ldt_ldt_s *target_ldt_info;
4228 uint64_t *gdt_table = g2h(env->gdt.base);
4229 uint32_t base_addr, limit, flags;
4230 int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
4231 int seg_not_present, useable, lm;
4232 uint32_t *lp, entry_1, entry_2;
4233
4234 lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
4235 if (!target_ldt_info)
4236 return -TARGET_EFAULT;
4237 idx = tswap32(target_ldt_info->entry_number);
4238 if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
4239 idx > TARGET_GDT_ENTRY_TLS_MAX) {
4240 unlock_user_struct(target_ldt_info, ptr, 1);
4241 return -TARGET_EINVAL;
4242 }
4243 lp = (uint32_t *)(gdt_table + idx);
4244 entry_1 = tswap32(lp[0]);
4245 entry_2 = tswap32(lp[1]);
4246
4247 read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
4248 contents = (entry_2 >> 10) & 3;
4249 seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
4250 seg_32bit = (entry_2 >> 22) & 1;
4251 limit_in_pages = (entry_2 >> 23) & 1;
4252 useable = (entry_2 >> 20) & 1;
4253#ifdef TARGET_ABI32
4254 lm = 0;
4255#else
4256 lm = (entry_2 >> 21) & 1;
4257#endif
4258 flags = (seg_32bit << 0) | (contents << 1) |
4259 (read_exec_only << 3) | (limit_in_pages << 4) |
4260 (seg_not_present << 5) | (useable << 6) | (lm << 7);
4261 limit = (entry_1 & 0xffff) | (entry_2 & 0xf0000);
4262 base_addr = (entry_1 >> 16) |
4263 (entry_2 & 0xff000000) |
4264 ((entry_2 & 0xff) << 16);
4265 target_ldt_info->base_addr = tswapal(base_addr);
4266 target_ldt_info->limit = tswap32(limit);
4267 target_ldt_info->flags = tswap32(flags);
4268 unlock_user_struct(target_ldt_info, ptr, 1);
4269 return 0;
4270}
4271#endif
4272
4273#ifndef TARGET_ABI32
4274abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
4275{
4276 abi_long ret = 0;
4277 abi_ulong val;
4278 int idx;
4279
4280 switch(code) {
4281 case TARGET_ARCH_SET_GS:
4282 case TARGET_ARCH_SET_FS:
4283 if (code == TARGET_ARCH_SET_GS)
4284 idx = R_GS;
4285 else
4286 idx = R_FS;
4287 cpu_x86_load_seg(env, idx, 0);
4288 env->segs[idx].base = addr;
4289 break;
4290 case TARGET_ARCH_GET_GS:
4291 case TARGET_ARCH_GET_FS:
4292 if (code == TARGET_ARCH_GET_GS)
4293 idx = R_GS;
4294 else
4295 idx = R_FS;
4296 val = env->segs[idx].base;
4297 if (put_user(val, addr, abi_ulong))
4298 ret = -TARGET_EFAULT;
4299 break;
4300 default:
4301 ret = -TARGET_EINVAL;
4302 break;
4303 }
4304 return ret;
4305}
4306#endif
4307
4308#endif
4309
4310#define NEW_STACK_SIZE 0x40000
4311
4312
4313static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
4314typedef struct {
4315 CPUArchState *env;
4316 pthread_mutex_t mutex;
4317 pthread_cond_t cond;
4318 pthread_t thread;
4319 uint32_t tid;
4320 abi_ulong child_tidptr;
4321 abi_ulong parent_tidptr;
4322 sigset_t sigmask;
4323} new_thread_info;
4324
4325static void *clone_func(void *arg)
4326{
4327 new_thread_info *info = arg;
4328 CPUArchState *env;
4329 CPUState *cpu;
4330 TaskState *ts;
4331
4332 env = info->env;
4333 cpu = ENV_GET_CPU(env);
4334 thread_cpu = cpu;
4335 ts = (TaskState *)env->opaque;
4336 info->tid = gettid();
4337 cpu->host_tid = info->tid;
4338 task_settid(ts);
4339 if (info->child_tidptr)
4340 put_user_u32(info->tid, info->child_tidptr);
4341 if (info->parent_tidptr)
4342 put_user_u32(info->tid, info->parent_tidptr);
4343
4344 sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
4345
4346 pthread_mutex_lock(&info->mutex);
4347 pthread_cond_broadcast(&info->cond);
4348 pthread_mutex_unlock(&info->mutex);
4349
4350 pthread_mutex_lock(&clone_lock);
4351 pthread_mutex_unlock(&clone_lock);
4352 cpu_loop(env);
4353
4354 return NULL;
4355}
4356
4357
4358
4359static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
4360 abi_ulong parent_tidptr, target_ulong newtls,
4361 abi_ulong child_tidptr)
4362{
4363 int ret;
4364 TaskState *ts;
4365 CPUArchState *new_env;
4366 unsigned int nptl_flags;
4367 sigset_t sigmask;
4368
4369
4370 if (flags & CLONE_VFORK)
4371 flags &= ~(CLONE_VFORK | CLONE_VM);
4372
4373 if (flags & CLONE_VM) {
4374 TaskState *parent_ts = (TaskState *)env->opaque;
4375 new_thread_info info;
4376 pthread_attr_t attr;
4377
4378 ts = g_malloc0(sizeof(TaskState));
4379 init_task_state(ts);
4380
4381 new_env = cpu_copy(env);
4382
4383 cpu_clone_regs(new_env, newsp);
4384 new_env->opaque = ts;
4385 ts->bprm = parent_ts->bprm;
4386 ts->info = parent_ts->info;
4387 nptl_flags = flags;
4388 flags &= ~CLONE_NPTL_FLAGS2;
4389
4390 if (nptl_flags & CLONE_CHILD_CLEARTID) {
4391 ts->child_tidptr = child_tidptr;
4392 }
4393
4394 if (nptl_flags & CLONE_SETTLS)
4395 cpu_set_tls (new_env, newtls);
4396
4397
4398 pthread_mutex_lock(&clone_lock);
4399
4400 memset(&info, 0, sizeof(info));
4401 pthread_mutex_init(&info.mutex, NULL);
4402 pthread_mutex_lock(&info.mutex);
4403 pthread_cond_init(&info.cond, NULL);
4404 info.env = new_env;
4405 if (nptl_flags & CLONE_CHILD_SETTID)
4406 info.child_tidptr = child_tidptr;
4407 if (nptl_flags & CLONE_PARENT_SETTID)
4408 info.parent_tidptr = parent_tidptr;
4409
4410 ret = pthread_attr_init(&attr);
4411 ret = pthread_attr_setstacksize(&attr, NEW_STACK_SIZE);
4412 ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
4413
4414
4415 sigfillset(&sigmask);
4416 sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
4417
4418 ret = pthread_create(&info.thread, &attr, clone_func, &info);
4419
4420
4421 sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
4422 pthread_attr_destroy(&attr);
4423 if (ret == 0) {
4424
4425 pthread_cond_wait(&info.cond, &info.mutex);
4426 ret = info.tid;
4427 if (flags & CLONE_PARENT_SETTID)
4428 put_user_u32(ret, parent_tidptr);
4429 } else {
4430 ret = -1;
4431 }
4432 pthread_mutex_unlock(&info.mutex);
4433 pthread_cond_destroy(&info.cond);
4434 pthread_mutex_destroy(&info.mutex);
4435 pthread_mutex_unlock(&clone_lock);
4436 } else {
4437
4438 if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
4439 return -EINVAL;
4440 fork_start();
4441 ret = fork();
4442 if (ret == 0) {
4443
4444 cpu_clone_regs(env, newsp);
4445 fork_end(1);
4446
4447
4448
4449
4450
4451
4452 if (flags & CLONE_CHILD_SETTID)
4453 put_user_u32(gettid(), child_tidptr);
4454 if (flags & CLONE_PARENT_SETTID)
4455 put_user_u32(gettid(), parent_tidptr);
4456 ts = (TaskState *)env->opaque;
4457 if (flags & CLONE_SETTLS)
4458 cpu_set_tls (env, newtls);
4459 if (flags & CLONE_CHILD_CLEARTID)
4460 ts->child_tidptr = child_tidptr;
4461 } else {
4462 fork_end(0);
4463 }
4464 }
4465 return ret;
4466}
4467
4468
4469static int target_to_host_fcntl_cmd(int cmd)
4470{
4471 switch(cmd) {
4472 case TARGET_F_DUPFD:
4473 case TARGET_F_GETFD:
4474 case TARGET_F_SETFD:
4475 case TARGET_F_GETFL:
4476 case TARGET_F_SETFL:
4477 return cmd;
4478 case TARGET_F_GETLK:
4479 return F_GETLK;
4480 case TARGET_F_SETLK:
4481 return F_SETLK;
4482 case TARGET_F_SETLKW:
4483 return F_SETLKW;
4484 case TARGET_F_GETOWN:
4485 return F_GETOWN;
4486 case TARGET_F_SETOWN:
4487 return F_SETOWN;
4488 case TARGET_F_GETSIG:
4489 return F_GETSIG;
4490 case TARGET_F_SETSIG:
4491 return F_SETSIG;
4492#if TARGET_ABI_BITS == 32
4493 case TARGET_F_GETLK64:
4494 return F_GETLK64;
4495 case TARGET_F_SETLK64:
4496 return F_SETLK64;
4497 case TARGET_F_SETLKW64:
4498 return F_SETLKW64;
4499#endif
4500 case TARGET_F_SETLEASE:
4501 return F_SETLEASE;
4502 case TARGET_F_GETLEASE:
4503 return F_GETLEASE;
4504#ifdef F_DUPFD_CLOEXEC
4505 case TARGET_F_DUPFD_CLOEXEC:
4506 return F_DUPFD_CLOEXEC;
4507#endif
4508 case TARGET_F_NOTIFY:
4509 return F_NOTIFY;
4510 default:
4511 return -TARGET_EINVAL;
4512 }
4513 return -TARGET_EINVAL;
4514}
4515
4516#define TRANSTBL_CONVERT(a) { -1, TARGET_##a, -1, a }
4517static const bitmask_transtbl flock_tbl[] = {
4518 TRANSTBL_CONVERT(F_RDLCK),
4519 TRANSTBL_CONVERT(F_WRLCK),
4520 TRANSTBL_CONVERT(F_UNLCK),
4521 TRANSTBL_CONVERT(F_EXLCK),
4522 TRANSTBL_CONVERT(F_SHLCK),
4523 { 0, 0, 0, 0 }
4524};
4525
4526static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
4527{
4528 struct flock fl;
4529 struct target_flock *target_fl;
4530 struct flock64 fl64;
4531 struct target_flock64 *target_fl64;
4532 abi_long ret;
4533 int host_cmd = target_to_host_fcntl_cmd(cmd);
4534
4535 if (host_cmd == -TARGET_EINVAL)
4536 return host_cmd;
4537
4538 switch(cmd) {
4539 case TARGET_F_GETLK:
4540 if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
4541 return -TARGET_EFAULT;
4542 fl.l_type =
4543 target_to_host_bitmask(tswap16(target_fl->l_type), flock_tbl);
4544 fl.l_whence = tswap16(target_fl->l_whence);
4545 fl.l_start = tswapal(target_fl->l_start);
4546 fl.l_len = tswapal(target_fl->l_len);
4547 fl.l_pid = tswap32(target_fl->l_pid);
4548 unlock_user_struct(target_fl, arg, 0);
4549 ret = get_errno(fcntl(fd, host_cmd, &fl));
4550 if (ret == 0) {
4551 if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
4552 return -TARGET_EFAULT;
4553 target_fl->l_type =
4554 host_to_target_bitmask(tswap16(fl.l_type), flock_tbl);
4555 target_fl->l_whence = tswap16(fl.l_whence);
4556 target_fl->l_start = tswapal(fl.l_start);
4557 target_fl->l_len = tswapal(fl.l_len);
4558 target_fl->l_pid = tswap32(fl.l_pid);
4559 unlock_user_struct(target_fl, arg, 1);
4560 }
4561 break;
4562
4563 case TARGET_F_SETLK:
4564 case TARGET_F_SETLKW:
4565 if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
4566 return -TARGET_EFAULT;
4567 fl.l_type =
4568 target_to_host_bitmask(tswap16(target_fl->l_type), flock_tbl);
4569 fl.l_whence = tswap16(target_fl->l_whence);
4570 fl.l_start = tswapal(target_fl->l_start);
4571 fl.l_len = tswapal(target_fl->l_len);
4572 fl.l_pid = tswap32(target_fl->l_pid);
4573 unlock_user_struct(target_fl, arg, 0);
4574 ret = get_errno(fcntl(fd, host_cmd, &fl));
4575 break;
4576
4577 case TARGET_F_GETLK64:
4578 if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
4579 return -TARGET_EFAULT;
4580 fl64.l_type =
4581 target_to_host_bitmask(tswap16(target_fl64->l_type), flock_tbl) >> 1;
4582 fl64.l_whence = tswap16(target_fl64->l_whence);
4583 fl64.l_start = tswap64(target_fl64->l_start);
4584 fl64.l_len = tswap64(target_fl64->l_len);
4585 fl64.l_pid = tswap32(target_fl64->l_pid);
4586 unlock_user_struct(target_fl64, arg, 0);
4587 ret = get_errno(fcntl(fd, host_cmd, &fl64));
4588 if (ret == 0) {
4589 if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
4590 return -TARGET_EFAULT;
4591 target_fl64->l_type =
4592 host_to_target_bitmask(tswap16(fl64.l_type), flock_tbl) >> 1;
4593 target_fl64->l_whence = tswap16(fl64.l_whence);
4594 target_fl64->l_start = tswap64(fl64.l_start);
4595 target_fl64->l_len = tswap64(fl64.l_len);
4596 target_fl64->l_pid = tswap32(fl64.l_pid);
4597 unlock_user_struct(target_fl64, arg, 1);
4598 }
4599 break;
4600 case TARGET_F_SETLK64:
4601 case TARGET_F_SETLKW64:
4602 if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
4603 return -TARGET_EFAULT;
4604 fl64.l_type =
4605 target_to_host_bitmask(tswap16(target_fl64->l_type), flock_tbl) >> 1;
4606 fl64.l_whence = tswap16(target_fl64->l_whence);
4607 fl64.l_start = tswap64(target_fl64->l_start);
4608 fl64.l_len = tswap64(target_fl64->l_len);
4609 fl64.l_pid = tswap32(target_fl64->l_pid);
4610 unlock_user_struct(target_fl64, arg, 0);
4611 ret = get_errno(fcntl(fd, host_cmd, &fl64));
4612 break;
4613
4614 case TARGET_F_GETFL:
4615 ret = get_errno(fcntl(fd, host_cmd, arg));
4616 if (ret >= 0) {
4617 ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
4618 }
4619 break;
4620
4621 case TARGET_F_SETFL:
4622 ret = get_errno(fcntl(fd, host_cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
4623 break;
4624
4625 case TARGET_F_SETOWN:
4626 case TARGET_F_GETOWN:
4627 case TARGET_F_SETSIG:
4628 case TARGET_F_GETSIG:
4629 case TARGET_F_SETLEASE:
4630 case TARGET_F_GETLEASE:
4631 ret = get_errno(fcntl(fd, host_cmd, arg));
4632 break;
4633
4634 default:
4635 ret = get_errno(fcntl(fd, cmd, arg));
4636 break;
4637 }
4638 return ret;
4639}
4640
4641#ifdef USE_UID16
4642
4643static inline int high2lowuid(int uid)
4644{
4645 if (uid > 65535)
4646 return 65534;
4647 else
4648 return uid;
4649}
4650
4651static inline int high2lowgid(int gid)
4652{
4653 if (gid > 65535)
4654 return 65534;
4655 else
4656 return gid;
4657}
4658
4659static inline int low2highuid(int uid)
4660{
4661 if ((int16_t)uid == -1)
4662 return -1;
4663 else
4664 return uid;
4665}
4666
4667static inline int low2highgid(int gid)
4668{
4669 if ((int16_t)gid == -1)
4670 return -1;
4671 else
4672 return gid;
4673}
4674static inline int tswapid(int id)
4675{
4676 return tswap16(id);
4677}
4678#else
4679static inline int high2lowuid(int uid)
4680{
4681 return uid;
4682}
4683static inline int high2lowgid(int gid)
4684{
4685 return gid;
4686}
4687static inline int low2highuid(int uid)
4688{
4689 return uid;
4690}
4691static inline int low2highgid(int gid)
4692{
4693 return gid;
4694}
4695static inline int tswapid(int id)
4696{
4697 return tswap32(id);
4698}
4699#endif
4700
4701void syscall_init(void)
4702{
4703 IOCTLEntry *ie;
4704 const argtype *arg_type;
4705 int size;
4706 int i;
4707
4708#define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
4709#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
4710#include "syscall_types.h"
4711#undef STRUCT
4712#undef STRUCT_SPECIAL
4713
4714
4715
4716 for (i = 0; i < ERRNO_TABLE_SIZE; i++) {
4717 target_to_host_errno_table[host_to_target_errno_table[i]] = i;
4718 }
4719
4720
4721
4722 ie = ioctl_entries;
4723 while (ie->target_cmd != 0) {
4724 if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
4725 TARGET_IOC_SIZEMASK) {
4726 arg_type = ie->arg_type;
4727 if (arg_type[0] != TYPE_PTR) {
4728 fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
4729 ie->target_cmd);
4730 exit(1);
4731 }
4732 arg_type++;
4733 size = thunk_type_size(arg_type, 0);
4734 ie->target_cmd = (ie->target_cmd &
4735 ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
4736 (size << TARGET_IOC_SIZESHIFT);
4737 }
4738
4739
4740#if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
4741 (defined(__x86_64__) && defined(TARGET_X86_64))
4742 if (unlikely(ie->target_cmd != ie->host_cmd)) {
4743 fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
4744 ie->name, ie->target_cmd, ie->host_cmd);
4745 }
4746#endif
4747 ie++;
4748 }
4749}
4750
4751#if TARGET_ABI_BITS == 32
4752static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
4753{
4754#ifdef TARGET_WORDS_BIGENDIAN
4755 return ((uint64_t)word0 << 32) | word1;
4756#else
4757 return ((uint64_t)word1 << 32) | word0;
4758#endif
4759}
4760#else
4761static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
4762{
4763 return word0;
4764}
4765#endif
4766
4767#ifdef TARGET_NR_truncate64
4768static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
4769 abi_long arg2,
4770 abi_long arg3,
4771 abi_long arg4)
4772{
4773 if (regpairs_aligned(cpu_env)) {
4774 arg2 = arg3;
4775 arg3 = arg4;
4776 }
4777 return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
4778}
4779#endif
4780
4781#ifdef TARGET_NR_ftruncate64
4782static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
4783 abi_long arg2,
4784 abi_long arg3,
4785 abi_long arg4)
4786{
4787 if (regpairs_aligned(cpu_env)) {
4788 arg2 = arg3;
4789 arg3 = arg4;
4790 }
4791 return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
4792}
4793#endif
4794
4795static inline abi_long target_to_host_timespec(struct timespec *host_ts,
4796 abi_ulong target_addr)
4797{
4798 struct target_timespec *target_ts;
4799
4800 if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
4801 return -TARGET_EFAULT;
4802 host_ts->tv_sec = tswapal(target_ts->tv_sec);
4803 host_ts->tv_nsec = tswapal(target_ts->tv_nsec);
4804 unlock_user_struct(target_ts, target_addr, 0);
4805 return 0;
4806}
4807
4808static inline abi_long host_to_target_timespec(abi_ulong target_addr,
4809 struct timespec *host_ts)
4810{
4811 struct target_timespec *target_ts;
4812
4813 if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
4814 return -TARGET_EFAULT;
4815 target_ts->tv_sec = tswapal(host_ts->tv_sec);
4816 target_ts->tv_nsec = tswapal(host_ts->tv_nsec);
4817 unlock_user_struct(target_ts, target_addr, 1);
4818 return 0;
4819}
4820
4821#if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
4822static inline abi_long host_to_target_stat64(void *cpu_env,
4823 abi_ulong target_addr,
4824 struct stat *host_st)
4825{
4826#if defined(TARGET_ARM) && defined(TARGET_ABI32)
4827 if (((CPUARMState *)cpu_env)->eabi) {
4828 struct target_eabi_stat64 *target_st;
4829
4830 if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
4831 return -TARGET_EFAULT;
4832 memset(target_st, 0, sizeof(struct target_eabi_stat64));
4833 __put_user(host_st->st_dev, &target_st->st_dev);
4834 __put_user(host_st->st_ino, &target_st->st_ino);
4835#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4836 __put_user(host_st->st_ino, &target_st->__st_ino);
4837#endif
4838 __put_user(host_st->st_mode, &target_st->st_mode);
4839 __put_user(host_st->st_nlink, &target_st->st_nlink);
4840 __put_user(host_st->st_uid, &target_st->st_uid);
4841 __put_user(host_st->st_gid, &target_st->st_gid);
4842 __put_user(host_st->st_rdev, &target_st->st_rdev);
4843 __put_user(host_st->st_size, &target_st->st_size);
4844 __put_user(host_st->st_blksize, &target_st->st_blksize);
4845 __put_user(host_st->st_blocks, &target_st->st_blocks);
4846 __put_user(host_st->st_atime, &target_st->target_st_atime);
4847 __put_user(host_st->st_mtime, &target_st->target_st_mtime);
4848 __put_user(host_st->st_ctime, &target_st->target_st_ctime);
4849 unlock_user_struct(target_st, target_addr, 1);
4850 } else
4851#endif
4852 {
4853#if defined(TARGET_HAS_STRUCT_STAT64)
4854 struct target_stat64 *target_st;
4855#else
4856 struct target_stat *target_st;
4857#endif
4858
4859 if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
4860 return -TARGET_EFAULT;
4861 memset(target_st, 0, sizeof(*target_st));
4862 __put_user(host_st->st_dev, &target_st->st_dev);
4863 __put_user(host_st->st_ino, &target_st->st_ino);
4864#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4865 __put_user(host_st->st_ino, &target_st->__st_ino);
4866#endif
4867 __put_user(host_st->st_mode, &target_st->st_mode);
4868 __put_user(host_st->st_nlink, &target_st->st_nlink);
4869 __put_user(host_st->st_uid, &target_st->st_uid);
4870 __put_user(host_st->st_gid, &target_st->st_gid);
4871 __put_user(host_st->st_rdev, &target_st->st_rdev);
4872
4873 __put_user(host_st->st_size, &target_st->st_size);
4874 __put_user(host_st->st_blksize, &target_st->st_blksize);
4875 __put_user(host_st->st_blocks, &target_st->st_blocks);
4876 __put_user(host_st->st_atime, &target_st->target_st_atime);
4877 __put_user(host_st->st_mtime, &target_st->target_st_mtime);
4878 __put_user(host_st->st_ctime, &target_st->target_st_ctime);
4879 unlock_user_struct(target_st, target_addr, 1);
4880 }
4881
4882 return 0;
4883}
4884#endif
4885
4886
4887
4888
4889
4890
4891static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
4892 target_ulong uaddr2, int val3)
4893{
4894 struct timespec ts, *pts;
4895 int base_op;
4896
4897
4898
4899#ifdef FUTEX_CMD_MASK
4900 base_op = op & FUTEX_CMD_MASK;
4901#else
4902 base_op = op;
4903#endif
4904 switch (base_op) {
4905 case FUTEX_WAIT:
4906 case FUTEX_WAIT_BITSET:
4907 if (timeout) {
4908 pts = &ts;
4909 target_to_host_timespec(pts, timeout);
4910 } else {
4911 pts = NULL;
4912 }
4913 return get_errno(sys_futex(g2h(uaddr), op, tswap32(val),
4914 pts, NULL, val3));
4915 case FUTEX_WAKE:
4916 return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4917 case FUTEX_FD:
4918 return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4919 case FUTEX_REQUEUE:
4920 case FUTEX_CMP_REQUEUE:
4921 case FUTEX_WAKE_OP:
4922
4923
4924
4925
4926
4927 pts = (struct timespec *)(uintptr_t) timeout;
4928 return get_errno(sys_futex(g2h(uaddr), op, val, pts,
4929 g2h(uaddr2),
4930 (base_op == FUTEX_CMP_REQUEUE
4931 ? tswap32(val3)
4932 : val3)));
4933 default:
4934 return -TARGET_ENOSYS;
4935 }
4936}
4937
4938
4939
4940int host_to_target_waitstatus(int status)
4941{
4942 if (WIFSIGNALED(status)) {
4943 return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f);
4944 }
4945 if (WIFSTOPPED(status)) {
4946 return (host_to_target_signal(WSTOPSIG(status)) << 8)
4947 | (status & 0xff);
4948 }
4949 return status;
4950}
4951
4952static int relstr_to_int(const char *s)
4953{
4954
4955
4956
4957 int i, n, tmp;
4958
4959 tmp = 0;
4960 for (i = 0; i < 3; i++) {
4961 n = 0;
4962 while (*s >= '0' && *s <= '9') {
4963 n *= 10;
4964 n += *s - '0';
4965 s++;
4966 }
4967 tmp = (tmp << 8) + n;
4968 if (*s == '.') {
4969 s++;
4970 }
4971 }
4972 return tmp;
4973}
4974
4975int get_osversion(void)
4976{
4977 static int osversion;
4978 struct new_utsname buf;
4979 const char *s;
4980
4981 if (osversion)
4982 return osversion;
4983 if (qemu_uname_release && *qemu_uname_release) {
4984 s = qemu_uname_release;
4985 } else {
4986 if (sys_uname(&buf))
4987 return 0;
4988 s = buf.release;
4989 }
4990 osversion = relstr_to_int(s);
4991 return osversion;
4992}
4993
4994void init_qemu_uname_release(void)
4995{
4996
4997
4998
4999
5000
5001#ifdef UNAME_MINIMUM_RELEASE
5002 struct new_utsname buf;
5003
5004 if (qemu_uname_release && *qemu_uname_release) {
5005 return;
5006 }
5007
5008 if (sys_uname(&buf)) {
5009 return;
5010 }
5011
5012 if (relstr_to_int(buf.release) < relstr_to_int(UNAME_MINIMUM_RELEASE)) {
5013 qemu_uname_release = UNAME_MINIMUM_RELEASE;
5014 }
5015#endif
5016}
5017
5018static int open_self_maps(void *cpu_env, int fd)
5019{
5020#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
5021 TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
5022#endif
5023 FILE *fp;
5024 char *line = NULL;
5025 size_t len = 0;
5026 ssize_t read;
5027
5028 fp = fopen("/proc/self/maps", "r");
5029 if (fp == NULL) {
5030 return -EACCES;
5031 }
5032
5033 while ((read = getline(&line, &len, fp)) != -1) {
5034 int fields, dev_maj, dev_min, inode;
5035 uint64_t min, max, offset;
5036 char flag_r, flag_w, flag_x, flag_p;
5037 char path[512] = "";
5038 fields = sscanf(line, "%"PRIx64"-%"PRIx64" %c%c%c%c %"PRIx64" %x:%x %d"
5039 " %512s", &min, &max, &flag_r, &flag_w, &flag_x,
5040 &flag_p, &offset, &dev_maj, &dev_min, &inode, path);
5041
5042 if ((fields < 10) || (fields > 11)) {
5043 continue;
5044 }
5045 if (!strncmp(path, "[stack]", 7)) {
5046 continue;
5047 }
5048 if (h2g_valid(min) && h2g_valid(max)) {
5049 dprintf(fd, TARGET_ABI_FMT_lx "-" TARGET_ABI_FMT_lx
5050 " %c%c%c%c %08" PRIx64 " %02x:%02x %d %s%s\n",
5051 h2g(min), h2g(max), flag_r, flag_w,
5052 flag_x, flag_p, offset, dev_maj, dev_min, inode,
5053 path[0] ? " " : "", path);
5054 }
5055 }
5056
5057 free(line);
5058 fclose(fp);
5059
5060#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
5061 dprintf(fd, "%08llx-%08llx rw-p %08llx 00:00 0 [stack]\n",
5062 (unsigned long long)ts->info->stack_limit,
5063 (unsigned long long)(ts->info->start_stack +
5064 (TARGET_PAGE_SIZE - 1)) & TARGET_PAGE_MASK,
5065 (unsigned long long)0);
5066#endif
5067
5068 return 0;
5069}
5070
5071static int open_self_stat(void *cpu_env, int fd)
5072{
5073 TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
5074 abi_ulong start_stack = ts->info->start_stack;
5075 int i;
5076
5077 for (i = 0; i < 44; i++) {
5078 char buf[128];
5079 int len;
5080 uint64_t val = 0;
5081
5082 if (i == 0) {
5083
5084 val = getpid();
5085 snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
5086 } else if (i == 1) {
5087
5088 snprintf(buf, sizeof(buf), "(%s) ", ts->bprm->argv[0]);
5089 } else if (i == 27) {
5090
5091 val = start_stack;
5092 snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
5093 } else {
5094
5095 snprintf(buf, sizeof(buf), "0%c", i == 43 ? '\n' : ' ');
5096 }
5097
5098 len = strlen(buf);
5099 if (write(fd, buf, len) != len) {
5100 return -1;
5101 }
5102 }
5103
5104 return 0;
5105}
5106
5107static int open_self_auxv(void *cpu_env, int fd)
5108{
5109 TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
5110 abi_ulong auxv = ts->info->saved_auxv;
5111 abi_ulong len = ts->info->auxv_len;
5112 char *ptr;
5113
5114
5115
5116
5117
5118 ptr = lock_user(VERIFY_READ, auxv, len, 0);
5119 if (ptr != NULL) {
5120 while (len > 0) {
5121 ssize_t r;
5122 r = write(fd, ptr, len);
5123 if (r <= 0) {
5124 break;
5125 }
5126 len -= r;
5127 ptr += r;
5128 }
5129 lseek(fd, 0, SEEK_SET);
5130 unlock_user(ptr, auxv, len);
5131 }
5132
5133 return 0;
5134}
5135
5136static int is_proc_myself(const char *filename, const char *entry)
5137{
5138 if (!strncmp(filename, "/proc/", strlen("/proc/"))) {
5139 filename += strlen("/proc/");
5140 if (!strncmp(filename, "self/", strlen("self/"))) {
5141 filename += strlen("self/");
5142 } else if (*filename >= '1' && *filename <= '9') {
5143 char myself[80];
5144 snprintf(myself, sizeof(myself), "%d/", getpid());
5145 if (!strncmp(filename, myself, strlen(myself))) {
5146 filename += strlen(myself);
5147 } else {
5148 return 0;
5149 }
5150 } else {
5151 return 0;
5152 }
5153 if (!strcmp(filename, entry)) {
5154 return 1;
5155 }
5156 }
5157 return 0;
5158}
5159
5160#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
5161static int is_proc(const char *filename, const char *entry)
5162{
5163 return strcmp(filename, entry) == 0;
5164}
5165
5166static int open_net_route(void *cpu_env, int fd)
5167{
5168 FILE *fp;
5169 char *line = NULL;
5170 size_t len = 0;
5171 ssize_t read;
5172
5173 fp = fopen("/proc/net/route", "r");
5174 if (fp == NULL) {
5175 return -EACCES;
5176 }
5177
5178
5179
5180 read = getline(&line, &len, fp);
5181 dprintf(fd, "%s", line);
5182
5183
5184
5185 while ((read = getline(&line, &len, fp)) != -1) {
5186 char iface[16];
5187 uint32_t dest, gw, mask;
5188 unsigned int flags, refcnt, use, metric, mtu, window, irtt;
5189 sscanf(line, "%s\t%08x\t%08x\t%04x\t%d\t%d\t%d\t%08x\t%d\t%u\t%u\n",
5190 iface, &dest, &gw, &flags, &refcnt, &use, &metric,
5191 &mask, &mtu, &window, &irtt);
5192 dprintf(fd, "%s\t%08x\t%08x\t%04x\t%d\t%d\t%d\t%08x\t%d\t%u\t%u\n",
5193 iface, tswap32(dest), tswap32(gw), flags, refcnt, use,
5194 metric, tswap32(mask), mtu, window, irtt);
5195 }
5196
5197 free(line);
5198 fclose(fp);
5199
5200 return 0;
5201}
5202#endif
5203
5204static int do_open(void *cpu_env, const char *pathname, int flags, mode_t mode)
5205{
5206 struct fake_open {
5207 const char *filename;
5208 int (*fill)(void *cpu_env, int fd);
5209 int (*cmp)(const char *s1, const char *s2);
5210 };
5211 const struct fake_open *fake_open;
5212 static const struct fake_open fakes[] = {
5213 { "maps", open_self_maps, is_proc_myself },
5214 { "stat", open_self_stat, is_proc_myself },
5215 { "auxv", open_self_auxv, is_proc_myself },
5216#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
5217 { "/proc/net/route", open_net_route, is_proc },
5218#endif
5219 { NULL, NULL, NULL }
5220 };
5221
5222 for (fake_open = fakes; fake_open->filename; fake_open++) {
5223 if (fake_open->cmp(pathname, fake_open->filename)) {
5224 break;
5225 }
5226 }
5227
5228 if (fake_open->filename) {
5229 const char *tmpdir;
5230 char filename[PATH_MAX];
5231 int fd, r;
5232
5233
5234 tmpdir = getenv("TMPDIR");
5235 if (!tmpdir)
5236 tmpdir = "/tmp";
5237 snprintf(filename, sizeof(filename), "%s/qemu-open.XXXXXX", tmpdir);
5238 fd = mkstemp(filename);
5239 if (fd < 0) {
5240 return fd;
5241 }
5242 unlink(filename);
5243
5244 if ((r = fake_open->fill(cpu_env, fd))) {
5245 close(fd);
5246 return r;
5247 }
5248 lseek(fd, 0, SEEK_SET);
5249
5250 return fd;
5251 }
5252
5253 return get_errno(open(path(pathname), flags, mode));
5254}
5255
5256
5257
5258
5259abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
5260 abi_long arg2, abi_long arg3, abi_long arg4,
5261 abi_long arg5, abi_long arg6, abi_long arg7,
5262 abi_long arg8)
5263{
5264 CPUState *cpu = ENV_GET_CPU(cpu_env);
5265 abi_long ret;
5266 struct stat st;
5267 struct statfs stfs;
5268 void *p;
5269
5270#ifdef DEBUG
5271 gemu_log("syscall %d", num);
5272#endif
5273 if(do_strace)
5274 print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
5275
5276 switch(num) {
5277 case TARGET_NR_exit:
5278
5279
5280
5281
5282
5283
5284 if (CPU_NEXT(first_cpu)) {
5285 TaskState *ts;
5286
5287 cpu_list_lock();
5288
5289 QTAILQ_REMOVE(&cpus, cpu, node);
5290 cpu_list_unlock();
5291 ts = ((CPUArchState *)cpu_env)->opaque;
5292 if (ts->child_tidptr) {
5293 put_user_u32(0, ts->child_tidptr);
5294 sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
5295 NULL, NULL, 0);
5296 }
5297 thread_cpu = NULL;
5298 object_unref(OBJECT(ENV_GET_CPU(cpu_env)));
5299 g_free(ts);
5300 pthread_exit(NULL);
5301 }
5302#ifdef TARGET_GPROF
5303 _mcleanup();
5304#endif
5305 gdb_exit(cpu_env, arg1);
5306 _exit(arg1);
5307 ret = 0;
5308 break;
5309 case TARGET_NR_read:
5310 if (arg3 == 0)
5311 ret = 0;
5312 else {
5313 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5314 goto efault;
5315 ret = get_errno(read(arg1, p, arg3));
5316 unlock_user(p, arg2, ret);
5317 }
5318 break;
5319 case TARGET_NR_write:
5320 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5321 goto efault;
5322 ret = get_errno(write(arg1, p, arg3));
5323 unlock_user(p, arg2, 0);
5324 break;
5325 case TARGET_NR_open:
5326 if (!(p = lock_user_string(arg1)))
5327 goto efault;
5328 ret = get_errno(do_open(cpu_env, p,
5329 target_to_host_bitmask(arg2, fcntl_flags_tbl),
5330 arg3));
5331 unlock_user(p, arg1, 0);
5332 break;
5333#if defined(TARGET_NR_openat) && defined(__NR_openat)
5334 case TARGET_NR_openat:
5335 if (!(p = lock_user_string(arg2)))
5336 goto efault;
5337 ret = get_errno(sys_openat(arg1,
5338 path(p),
5339 target_to_host_bitmask(arg3, fcntl_flags_tbl),
5340 arg4));
5341 unlock_user(p, arg2, 0);
5342 break;
5343#endif
5344 case TARGET_NR_close:
5345 ret = get_errno(close(arg1));
5346 break;
5347 case TARGET_NR_brk:
5348 ret = do_brk(arg1);
5349 break;
5350 case TARGET_NR_fork:
5351 ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
5352 break;
5353#ifdef TARGET_NR_waitpid
5354 case TARGET_NR_waitpid:
5355 {
5356 int status;
5357 ret = get_errno(waitpid(arg1, &status, arg3));
5358 if (!is_error(ret) && arg2 && ret
5359 && put_user_s32(host_to_target_waitstatus(status), arg2))
5360 goto efault;
5361 }
5362 break;
5363#endif
5364#ifdef TARGET_NR_waitid
5365 case TARGET_NR_waitid:
5366 {
5367 siginfo_t info;
5368 info.si_pid = 0;
5369 ret = get_errno(waitid(arg1, arg2, &info, arg4));
5370 if (!is_error(ret) && arg3 && info.si_pid != 0) {
5371 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
5372 goto efault;
5373 host_to_target_siginfo(p, &info);
5374 unlock_user(p, arg3, sizeof(target_siginfo_t));
5375 }
5376 }
5377 break;
5378#endif
5379#ifdef TARGET_NR_creat
5380 case TARGET_NR_creat:
5381 if (!(p = lock_user_string(arg1)))
5382 goto efault;
5383 ret = get_errno(creat(p, arg2));
5384 unlock_user(p, arg1, 0);
5385 break;
5386#endif
5387 case TARGET_NR_link:
5388 {
5389 void * p2;
5390 p = lock_user_string(arg1);
5391 p2 = lock_user_string(arg2);
5392 if (!p || !p2)
5393 ret = -TARGET_EFAULT;
5394 else
5395 ret = get_errno(link(p, p2));
5396 unlock_user(p2, arg2, 0);
5397 unlock_user(p, arg1, 0);
5398 }
5399 break;
5400#if defined(TARGET_NR_linkat)
5401 case TARGET_NR_linkat:
5402 {
5403 void * p2 = NULL;
5404 if (!arg2 || !arg4)
5405 goto efault;
5406 p = lock_user_string(arg2);
5407 p2 = lock_user_string(arg4);
5408 if (!p || !p2)
5409 ret = -TARGET_EFAULT;
5410 else
5411 ret = get_errno(linkat(arg1, p, arg3, p2, arg5));
5412 unlock_user(p, arg2, 0);
5413 unlock_user(p2, arg4, 0);
5414 }
5415 break;
5416#endif
5417 case TARGET_NR_unlink:
5418 if (!(p = lock_user_string(arg1)))
5419 goto efault;
5420 ret = get_errno(unlink(p));
5421 unlock_user(p, arg1, 0);
5422 break;
5423#if defined(TARGET_NR_unlinkat)
5424 case TARGET_NR_unlinkat:
5425 if (!(p = lock_user_string(arg2)))
5426 goto efault;
5427 ret = get_errno(unlinkat(arg1, p, arg3));
5428 unlock_user(p, arg2, 0);
5429 break;
5430#endif
5431 case TARGET_NR_execve:
5432 {
5433 char **argp, **envp;
5434 int argc, envc;
5435 abi_ulong gp;
5436 abi_ulong guest_argp;
5437 abi_ulong guest_envp;
5438 abi_ulong addr;
5439 char **q;
5440 int total_size = 0;
5441
5442 argc = 0;
5443 guest_argp = arg2;
5444 for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
5445 if (get_user_ual(addr, gp))
5446 goto efault;
5447 if (!addr)
5448 break;
5449 argc++;
5450 }
5451 envc = 0;
5452 guest_envp = arg3;
5453 for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
5454 if (get_user_ual(addr, gp))
5455 goto efault;
5456 if (!addr)
5457 break;
5458 envc++;
5459 }
5460
5461 argp = alloca((argc + 1) * sizeof(void *));
5462 envp = alloca((envc + 1) * sizeof(void *));
5463
5464 for (gp = guest_argp, q = argp; gp;
5465 gp += sizeof(abi_ulong), q++) {
5466 if (get_user_ual(addr, gp))
5467 goto execve_efault;
5468 if (!addr)
5469 break;
5470 if (!(*q = lock_user_string(addr)))
5471 goto execve_efault;
5472 total_size += strlen(*q) + 1;
5473 }
5474 *q = NULL;
5475
5476 for (gp = guest_envp, q = envp; gp;
5477 gp += sizeof(abi_ulong), q++) {
5478 if (get_user_ual(addr, gp))
5479 goto execve_efault;
5480 if (!addr)
5481 break;
5482 if (!(*q = lock_user_string(addr)))
5483 goto execve_efault;
5484 total_size += strlen(*q) + 1;
5485 }
5486 *q = NULL;
5487
5488
5489
5490 if (total_size > MAX_ARG_PAGES * TARGET_PAGE_SIZE) {
5491 ret = -TARGET_E2BIG;
5492 goto execve_end;
5493 }
5494 if (!(p = lock_user_string(arg1)))
5495 goto execve_efault;
5496 ret = get_errno(execve(p, argp, envp));
5497 unlock_user(p, arg1, 0);
5498
5499 goto execve_end;
5500
5501 execve_efault:
5502 ret = -TARGET_EFAULT;
5503
5504 execve_end:
5505 for (gp = guest_argp, q = argp; *q;
5506 gp += sizeof(abi_ulong), q++) {
5507 if (get_user_ual(addr, gp)
5508 || !addr)
5509 break;
5510 unlock_user(*q, addr, 0);
5511 }
5512 for (gp = guest_envp, q = envp; *q;
5513 gp += sizeof(abi_ulong), q++) {
5514 if (get_user_ual(addr, gp)
5515 || !addr)
5516 break;
5517 unlock_user(*q, addr, 0);
5518 }
5519 }
5520 break;
5521 case TARGET_NR_chdir:
5522 if (!(p = lock_user_string(arg1)))
5523 goto efault;
5524 ret = get_errno(chdir(p));
5525 unlock_user(p, arg1, 0);
5526 break;
5527#ifdef TARGET_NR_time
5528 case TARGET_NR_time:
5529 {
5530 time_t host_time;
5531 ret = get_errno(time(&host_time));
5532 if (!is_error(ret)
5533 && arg1
5534 && put_user_sal(host_time, arg1))
5535 goto efault;
5536 }
5537 break;
5538#endif
5539 case TARGET_NR_mknod:
5540 if (!(p = lock_user_string(arg1)))
5541 goto efault;
5542 ret = get_errno(mknod(p, arg2, arg3));
5543 unlock_user(p, arg1, 0);
5544 break;
5545#if defined(TARGET_NR_mknodat)
5546 case TARGET_NR_mknodat:
5547 if (!(p = lock_user_string(arg2)))
5548 goto efault;
5549 ret = get_errno(mknodat(arg1, p, arg3, arg4));
5550 unlock_user(p, arg2, 0);
5551 break;
5552#endif
5553 case TARGET_NR_chmod:
5554 if (!(p = lock_user_string(arg1)))
5555 goto efault;
5556 ret = get_errno(chmod(p, arg2));
5557 unlock_user(p, arg1, 0);
5558 break;
5559#ifdef TARGET_NR_break
5560 case TARGET_NR_break:
5561 goto unimplemented;
5562#endif
5563#ifdef TARGET_NR_oldstat
5564 case TARGET_NR_oldstat:
5565 goto unimplemented;
5566#endif
5567 case TARGET_NR_lseek:
5568 ret = get_errno(lseek(arg1, arg2, arg3));
5569 break;
5570#if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA)
5571
5572 case TARGET_NR_getxpid:
5573 ((CPUAlphaState *)cpu_env)->ir[IR_A4] = getppid();
5574 ret = get_errno(getpid());
5575 break;
5576#endif
5577#ifdef TARGET_NR_getpid
5578 case TARGET_NR_getpid:
5579 ret = get_errno(getpid());
5580 break;
5581#endif
5582 case TARGET_NR_mount:
5583 {
5584
5585 void *p2, *p3;
5586 p = lock_user_string(arg1);
5587 p2 = lock_user_string(arg2);
5588 p3 = lock_user_string(arg3);
5589 if (!p || !p2 || !p3)
5590 ret = -TARGET_EFAULT;
5591 else {
5592
5593
5594
5595
5596 if ( ! arg5 )
5597 ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, NULL));
5598 else
5599 ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
5600 }
5601 unlock_user(p, arg1, 0);
5602 unlock_user(p2, arg2, 0);
5603 unlock_user(p3, arg3, 0);
5604 break;
5605 }
5606#ifdef TARGET_NR_umount
5607 case TARGET_NR_umount:
5608 if (!(p = lock_user_string(arg1)))
5609 goto efault;
5610 ret = get_errno(umount(p));
5611 unlock_user(p, arg1, 0);
5612 break;
5613#endif
5614#ifdef TARGET_NR_stime
5615 case TARGET_NR_stime:
5616 {
5617 time_t host_time;
5618 if (get_user_sal(host_time, arg1))
5619 goto efault;
5620 ret = get_errno(stime(&host_time));
5621 }
5622 break;
5623#endif
5624 case TARGET_NR_ptrace:
5625 goto unimplemented;
5626#ifdef TARGET_NR_alarm
5627 case TARGET_NR_alarm:
5628 ret = alarm(arg1);
5629 break;
5630#endif
5631#ifdef TARGET_NR_oldfstat
5632 case TARGET_NR_oldfstat:
5633 goto unimplemented;
5634#endif
5635#ifdef TARGET_NR_pause
5636 case TARGET_NR_pause:
5637 ret = get_errno(pause());
5638 break;
5639#endif
5640#ifdef TARGET_NR_utime
5641 case TARGET_NR_utime:
5642 {
5643 struct utimbuf tbuf, *host_tbuf;
5644 struct target_utimbuf *target_tbuf;
5645 if (arg2) {
5646 if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
5647 goto efault;
5648 tbuf.actime = tswapal(target_tbuf->actime);
5649 tbuf.modtime = tswapal(target_tbuf->modtime);
5650 unlock_user_struct(target_tbuf, arg2, 0);
5651 host_tbuf = &tbuf;
5652 } else {
5653 host_tbuf = NULL;
5654 }
5655 if (!(p = lock_user_string(arg1)))
5656 goto efault;
5657 ret = get_errno(utime(p, host_tbuf));
5658 unlock_user(p, arg1, 0);
5659 }
5660 break;
5661#endif
5662 case TARGET_NR_utimes:
5663 {
5664 struct timeval *tvp, tv[2];
5665 if (arg2) {
5666 if (copy_from_user_timeval(&tv[0], arg2)
5667 || copy_from_user_timeval(&tv[1],
5668 arg2 + sizeof(struct target_timeval)))
5669 goto efault;
5670 tvp = tv;
5671 } else {
5672 tvp = NULL;
5673 }
5674 if (!(p = lock_user_string(arg1)))
5675 goto efault;
5676 ret = get_errno(utimes(p, tvp));
5677 unlock_user(p, arg1, 0);
5678 }
5679 break;
5680#if defined(TARGET_NR_futimesat)
5681 case TARGET_NR_futimesat:
5682 {
5683 struct timeval *tvp, tv[2];
5684 if (arg3) {
5685 if (copy_from_user_timeval(&tv[0], arg3)
5686 || copy_from_user_timeval(&tv[1],
5687 arg3 + sizeof(struct target_timeval)))
5688 goto efault;
5689 tvp = tv;
5690 } else {
5691 tvp = NULL;
5692 }
5693 if (!(p = lock_user_string(arg2)))
5694 goto efault;
5695 ret = get_errno(futimesat(arg1, path(p), tvp));
5696 unlock_user(p, arg2, 0);
5697 }
5698 break;
5699#endif
5700#ifdef TARGET_NR_stty
5701 case TARGET_NR_stty:
5702 goto unimplemented;
5703#endif
5704#ifdef TARGET_NR_gtty
5705 case TARGET_NR_gtty:
5706 goto unimplemented;
5707#endif
5708 case TARGET_NR_access:
5709 if (!(p = lock_user_string(arg1)))
5710 goto efault;
5711 ret = get_errno(access(path(p), arg2));
5712 unlock_user(p, arg1, 0);
5713 break;
5714#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
5715 case TARGET_NR_faccessat:
5716 if (!(p = lock_user_string(arg2)))
5717 goto efault;
5718 ret = get_errno(faccessat(arg1, p, arg3, 0));
5719 unlock_user(p, arg2, 0);
5720 break;
5721#endif
5722#ifdef TARGET_NR_nice
5723 case TARGET_NR_nice:
5724 ret = get_errno(nice(arg1));
5725 break;
5726#endif
5727#ifdef TARGET_NR_ftime
5728 case TARGET_NR_ftime:
5729 goto unimplemented;
5730#endif
5731 case TARGET_NR_sync:
5732 sync();
5733 ret = 0;
5734 break;
5735 case TARGET_NR_kill:
5736 ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
5737 break;
5738 case TARGET_NR_rename:
5739 {
5740 void *p2;
5741 p = lock_user_string(arg1);
5742 p2 = lock_user_string(arg2);
5743 if (!p || !p2)
5744 ret = -TARGET_EFAULT;
5745 else
5746 ret = get_errno(rename(p, p2));
5747 unlock_user(p2, arg2, 0);
5748 unlock_user(p, arg1, 0);
5749 }
5750 break;
5751#if defined(TARGET_NR_renameat)
5752 case TARGET_NR_renameat:
5753 {
5754 void *p2;
5755 p = lock_user_string(arg2);
5756 p2 = lock_user_string(arg4);
5757 if (!p || !p2)
5758 ret = -TARGET_EFAULT;
5759 else
5760 ret = get_errno(renameat(arg1, p, arg3, p2));
5761 unlock_user(p2, arg4, 0);
5762 unlock_user(p, arg2, 0);
5763 }
5764 break;
5765#endif
5766 case TARGET_NR_mkdir:
5767 if (!(p = lock_user_string(arg1)))
5768 goto efault;
5769 ret = get_errno(mkdir(p, arg2));
5770 unlock_user(p, arg1, 0);
5771 break;
5772#if defined(TARGET_NR_mkdirat)
5773 case TARGET_NR_mkdirat:
5774 if (!(p = lock_user_string(arg2)))
5775 goto efault;
5776 ret = get_errno(mkdirat(arg1, p, arg3));
5777 unlock_user(p, arg2, 0);
5778 break;
5779#endif
5780 case TARGET_NR_rmdir:
5781 if (!(p = lock_user_string(arg1)))
5782 goto efault;
5783 ret = get_errno(rmdir(p));
5784 unlock_user(p, arg1, 0);
5785 break;
5786 case TARGET_NR_dup:
5787 ret = get_errno(dup(arg1));
5788 break;
5789 case TARGET_NR_pipe:
5790 ret = do_pipe(cpu_env, arg1, 0, 0);
5791 break;
5792#ifdef TARGET_NR_pipe2
5793 case TARGET_NR_pipe2:
5794 ret = do_pipe(cpu_env, arg1,
5795 target_to_host_bitmask(arg2, fcntl_flags_tbl), 1);
5796 break;
5797#endif
5798 case TARGET_NR_times:
5799 {
5800 struct target_tms *tmsp;
5801 struct tms tms;
5802 ret = get_errno(times(&tms));
5803 if (arg1) {
5804 tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
5805 if (!tmsp)
5806 goto efault;
5807 tmsp->tms_utime = tswapal(host_to_target_clock_t(tms.tms_utime));
5808 tmsp->tms_stime = tswapal(host_to_target_clock_t(tms.tms_stime));
5809 tmsp->tms_cutime = tswapal(host_to_target_clock_t(tms.tms_cutime));
5810 tmsp->tms_cstime = tswapal(host_to_target_clock_t(tms.tms_cstime));
5811 }
5812 if (!is_error(ret))
5813 ret = host_to_target_clock_t(ret);
5814 }
5815 break;
5816#ifdef TARGET_NR_prof
5817 case TARGET_NR_prof:
5818 goto unimplemented;
5819#endif
5820#ifdef TARGET_NR_signal
5821 case TARGET_NR_signal:
5822 goto unimplemented;
5823#endif
5824 case TARGET_NR_acct:
5825 if (arg1 == 0) {
5826 ret = get_errno(acct(NULL));
5827 } else {
5828 if (!(p = lock_user_string(arg1)))
5829 goto efault;
5830 ret = get_errno(acct(path(p)));
5831 unlock_user(p, arg1, 0);
5832 }
5833 break;
5834#ifdef TARGET_NR_umount2
5835 case TARGET_NR_umount2:
5836 if (!(p = lock_user_string(arg1)))
5837 goto efault;
5838 ret = get_errno(umount2(p, arg2));
5839 unlock_user(p, arg1, 0);
5840 break;
5841#endif
5842#ifdef TARGET_NR_lock
5843 case TARGET_NR_lock:
5844 goto unimplemented;
5845#endif
5846 case TARGET_NR_ioctl:
5847 ret = do_ioctl(arg1, arg2, arg3);
5848 break;
5849 case TARGET_NR_fcntl:
5850 ret = do_fcntl(arg1, arg2, arg3);
5851 break;
5852#ifdef TARGET_NR_mpx
5853 case TARGET_NR_mpx:
5854 goto unimplemented;
5855#endif
5856 case TARGET_NR_setpgid:
5857 ret = get_errno(setpgid(arg1, arg2));
5858 break;
5859#ifdef TARGET_NR_ulimit
5860 case TARGET_NR_ulimit:
5861 goto unimplemented;
5862#endif
5863#ifdef TARGET_NR_oldolduname
5864 case TARGET_NR_oldolduname:
5865 goto unimplemented;
5866#endif
5867 case TARGET_NR_umask:
5868 ret = get_errno(umask(arg1));
5869 break;
5870 case TARGET_NR_chroot:
5871 if (!(p = lock_user_string(arg1)))
5872 goto efault;
5873 ret = get_errno(chroot(p));
5874 unlock_user(p, arg1, 0);
5875 break;
5876 case TARGET_NR_ustat:
5877 goto unimplemented;
5878 case TARGET_NR_dup2:
5879 ret = get_errno(dup2(arg1, arg2));
5880 break;
5881#if defined(CONFIG_DUP3) && defined(TARGET_NR_dup3)
5882 case TARGET_NR_dup3:
5883 ret = get_errno(dup3(arg1, arg2, arg3));
5884 break;
5885#endif
5886#ifdef TARGET_NR_getppid
5887 case TARGET_NR_getppid:
5888 ret = get_errno(getppid());
5889 break;
5890#endif
5891 case TARGET_NR_getpgrp:
5892 ret = get_errno(getpgrp());
5893 break;
5894 case TARGET_NR_setsid:
5895 ret = get_errno(setsid());
5896 break;
5897#ifdef TARGET_NR_sigaction
5898 case TARGET_NR_sigaction:
5899 {
5900#if defined(TARGET_ALPHA)
5901 struct target_sigaction act, oact, *pact = 0;
5902 struct target_old_sigaction *old_act;
5903 if (arg2) {
5904 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
5905 goto efault;
5906 act._sa_handler = old_act->_sa_handler;
5907 target_siginitset(&act.sa_mask, old_act->sa_mask);
5908 act.sa_flags = old_act->sa_flags;
5909 act.sa_restorer = 0;
5910 unlock_user_struct(old_act, arg2, 0);
5911 pact = &act;
5912 }
5913 ret = get_errno(do_sigaction(arg1, pact, &oact));
5914 if (!is_error(ret) && arg3) {
5915 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
5916 goto efault;
5917 old_act->_sa_handler = oact._sa_handler;
5918 old_act->sa_mask = oact.sa_mask.sig[0];
5919 old_act->sa_flags = oact.sa_flags;
5920 unlock_user_struct(old_act, arg3, 1);
5921 }
5922#elif defined(TARGET_MIPS)
5923 struct target_sigaction act, oact, *pact, *old_act;
5924
5925 if (arg2) {
5926 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
5927 goto efault;
5928 act._sa_handler = old_act->_sa_handler;
5929 target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
5930 act.sa_flags = old_act->sa_flags;
5931 unlock_user_struct(old_act, arg2, 0);
5932 pact = &act;
5933 } else {
5934 pact = NULL;
5935 }
5936
5937 ret = get_errno(do_sigaction(arg1, pact, &oact));
5938
5939 if (!is_error(ret) && arg3) {
5940 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
5941 goto efault;
5942 old_act->_sa_handler = oact._sa_handler;
5943 old_act->sa_flags = oact.sa_flags;
5944 old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
5945 old_act->sa_mask.sig[1] = 0;
5946 old_act->sa_mask.sig[2] = 0;
5947 old_act->sa_mask.sig[3] = 0;
5948 unlock_user_struct(old_act, arg3, 1);
5949 }
5950#else
5951 struct target_old_sigaction *old_act;
5952 struct target_sigaction act, oact, *pact;
5953 if (arg2) {
5954 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
5955 goto efault;
5956 act._sa_handler = old_act->_sa_handler;
5957 target_siginitset(&act.sa_mask, old_act->sa_mask);
5958 act.sa_flags = old_act->sa_flags;
5959 act.sa_restorer = old_act->sa_restorer;
5960 unlock_user_struct(old_act, arg2, 0);
5961 pact = &act;
5962 } else {
5963 pact = NULL;
5964 }
5965 ret = get_errno(do_sigaction(arg1, pact, &oact));
5966 if (!is_error(ret) && arg3) {
5967 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
5968 goto efault;
5969 old_act->_sa_handler = oact._sa_handler;
5970 old_act->sa_mask = oact.sa_mask.sig[0];
5971 old_act->sa_flags = oact.sa_flags;
5972 old_act->sa_restorer = oact.sa_restorer;
5973 unlock_user_struct(old_act, arg3, 1);
5974 }
5975#endif
5976 }
5977 break;
5978#endif
5979 case TARGET_NR_rt_sigaction:
5980 {
5981#if defined(TARGET_ALPHA)
5982 struct target_sigaction act, oact, *pact = 0;
5983 struct target_rt_sigaction *rt_act;
5984
5985 if (arg2) {
5986 if (!lock_user_struct(VERIFY_READ, rt_act, arg2, 1))
5987 goto efault;
5988 act._sa_handler = rt_act->_sa_handler;
5989 act.sa_mask = rt_act->sa_mask;
5990 act.sa_flags = rt_act->sa_flags;
5991 act.sa_restorer = arg5;
5992 unlock_user_struct(rt_act, arg2, 0);
5993 pact = &act;
5994 }
5995 ret = get_errno(do_sigaction(arg1, pact, &oact));
5996 if (!is_error(ret) && arg3) {
5997 if (!lock_user_struct(VERIFY_WRITE, rt_act, arg3, 0))
5998 goto efault;
5999 rt_act->_sa_handler = oact._sa_handler;
6000 rt_act->sa_mask = oact.sa_mask;
6001 rt_act->sa_flags = oact.sa_flags;
6002 unlock_user_struct(rt_act, arg3, 1);
6003 }
6004#else
6005 struct target_sigaction *act;
6006 struct target_sigaction *oact;
6007
6008 if (arg2) {
6009 if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
6010 goto efault;
6011 } else
6012 act = NULL;
6013 if (arg3) {
6014 if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
6015 ret = -TARGET_EFAULT;
6016 goto rt_sigaction_fail;
6017 }
6018 } else
6019 oact = NULL;
6020 ret = get_errno(do_sigaction(arg1, act, oact));
6021 rt_sigaction_fail:
6022 if (act)
6023 unlock_user_struct(act, arg2, 0);
6024 if (oact)
6025 unlock_user_struct(oact, arg3, 1);
6026#endif
6027 }
6028 break;
6029#ifdef TARGET_NR_sgetmask
6030 case TARGET_NR_sgetmask:
6031 {
6032 sigset_t cur_set;
6033 abi_ulong target_set;
6034 sigprocmask(0, NULL, &cur_set);
6035 host_to_target_old_sigset(&target_set, &cur_set);
6036 ret = target_set;
6037 }
6038 break;
6039#endif
6040#ifdef TARGET_NR_ssetmask
6041 case TARGET_NR_ssetmask:
6042 {
6043 sigset_t set, oset, cur_set;
6044 abi_ulong target_set = arg1;
6045 sigprocmask(0, NULL, &cur_set);
6046 target_to_host_old_sigset(&set, &target_set);
6047 sigorset(&set, &set, &cur_set);
6048 sigprocmask(SIG_SETMASK, &set, &oset);
6049 host_to_target_old_sigset(&target_set, &oset);
6050 ret = target_set;
6051 }
6052 break;
6053#endif
6054#ifdef TARGET_NR_sigprocmask
6055 case TARGET_NR_sigprocmask:
6056 {
6057#if defined(TARGET_ALPHA)
6058 sigset_t set, oldset;
6059 abi_ulong mask;
6060 int how;
6061
6062 switch (arg1) {
6063 case TARGET_SIG_BLOCK:
6064 how = SIG_BLOCK;
6065 break;
6066 case TARGET_SIG_UNBLOCK:
6067 how = SIG_UNBLOCK;
6068 break;
6069 case TARGET_SIG_SETMASK:
6070 how = SIG_SETMASK;
6071 break;
6072 default:
6073 ret = -TARGET_EINVAL;
6074 goto fail;
6075 }
6076 mask = arg2;
6077 target_to_host_old_sigset(&set, &mask);
6078
6079 ret = get_errno(sigprocmask(how, &set, &oldset));
6080 if (!is_error(ret)) {
6081 host_to_target_old_sigset(&mask, &oldset);
6082 ret = mask;
6083 ((CPUAlphaState *)cpu_env)->ir[IR_V0] = 0;
6084 }
6085#else
6086 sigset_t set, oldset, *set_ptr;
6087 int how;
6088
6089 if (arg2) {
6090 switch (arg1) {
6091 case TARGET_SIG_BLOCK:
6092 how = SIG_BLOCK;
6093 break;
6094 case TARGET_SIG_UNBLOCK:
6095 how = SIG_UNBLOCK;
6096 break;
6097 case TARGET_SIG_SETMASK:
6098 how = SIG_SETMASK;
6099 break;
6100 default:
6101 ret = -TARGET_EINVAL;
6102 goto fail;
6103 }
6104 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
6105 goto efault;
6106 target_to_host_old_sigset(&set, p);
6107 unlock_user(p, arg2, 0);
6108 set_ptr = &set;
6109 } else {
6110 how = 0;
6111 set_ptr = NULL;
6112 }
6113 ret = get_errno(sigprocmask(how, set_ptr, &oldset));
6114 if (!is_error(ret) && arg3) {
6115 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
6116 goto efault;
6117 host_to_target_old_sigset(p, &oldset);
6118 unlock_user(p, arg3, sizeof(target_sigset_t));
6119 }
6120#endif
6121 }
6122 break;
6123#endif
6124 case TARGET_NR_rt_sigprocmask:
6125 {
6126 int how = arg1;
6127 sigset_t set, oldset, *set_ptr;
6128
6129 if (arg2) {
6130 switch(how) {
6131 case TARGET_SIG_BLOCK:
6132 how = SIG_BLOCK;
6133 break;
6134 case TARGET_SIG_UNBLOCK:
6135 how = SIG_UNBLOCK;
6136 break;
6137 case TARGET_SIG_SETMASK:
6138 how = SIG_SETMASK;
6139 break;
6140 default:
6141 ret = -TARGET_EINVAL;
6142 goto fail;
6143 }
6144 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
6145 goto efault;
6146 target_to_host_sigset(&set, p);
6147 unlock_user(p, arg2, 0);
6148 set_ptr = &set;
6149 } else {
6150 how = 0;
6151 set_ptr = NULL;
6152 }
6153 ret = get_errno(sigprocmask(how, set_ptr, &oldset));
6154 if (!is_error(ret) && arg3) {
6155 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
6156 goto efault;
6157 host_to_target_sigset(p, &oldset);
6158 unlock_user(p, arg3, sizeof(target_sigset_t));
6159 }
6160 }
6161 break;
6162#ifdef TARGET_NR_sigpending
6163 case TARGET_NR_sigpending:
6164 {
6165 sigset_t set;
6166 ret = get_errno(sigpending(&set));
6167 if (!is_error(ret)) {
6168 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
6169 goto efault;
6170 host_to_target_old_sigset(p, &set);
6171 unlock_user(p, arg1, sizeof(target_sigset_t));
6172 }
6173 }
6174 break;
6175#endif
6176 case TARGET_NR_rt_sigpending:
6177 {
6178 sigset_t set;
6179 ret = get_errno(sigpending(&set));
6180 if (!is_error(ret)) {
6181 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
6182 goto efault;
6183 host_to_target_sigset(p, &set);
6184 unlock_user(p, arg1, sizeof(target_sigset_t));
6185 }
6186 }
6187 break;
6188#ifdef TARGET_NR_sigsuspend
6189 case TARGET_NR_sigsuspend:
6190 {
6191 sigset_t set;
6192#if defined(TARGET_ALPHA)
6193 abi_ulong mask = arg1;
6194 target_to_host_old_sigset(&set, &mask);
6195#else
6196 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
6197 goto efault;
6198 target_to_host_old_sigset(&set, p);
6199 unlock_user(p, arg1, 0);
6200#endif
6201 ret = get_errno(sigsuspend(&set));
6202 }
6203 break;
6204#endif
6205 case TARGET_NR_rt_sigsuspend:
6206 {
6207 sigset_t set;
6208 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
6209 goto efault;
6210 target_to_host_sigset(&set, p);
6211 unlock_user(p, arg1, 0);
6212 ret = get_errno(sigsuspend(&set));
6213 }
6214 break;
6215 case TARGET_NR_rt_sigtimedwait:
6216 {
6217 sigset_t set;
6218 struct timespec uts, *puts;
6219 siginfo_t uinfo;
6220
6221 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
6222 goto efault;
6223 target_to_host_sigset(&set, p);
6224 unlock_user(p, arg1, 0);
6225 if (arg3) {
6226 puts = &uts;
6227 target_to_host_timespec(puts, arg3);
6228 } else {
6229 puts = NULL;
6230 }
6231 ret = get_errno(sigtimedwait(&set, &uinfo, puts));
6232 if (!is_error(ret) && arg2) {
6233 if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
6234 goto efault;
6235 host_to_target_siginfo(p, &uinfo);
6236 unlock_user(p, arg2, sizeof(target_siginfo_t));
6237 }
6238 }
6239 break;
6240 case TARGET_NR_rt_sigqueueinfo:
6241 {
6242 siginfo_t uinfo;
6243 if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
6244 goto efault;
6245 target_to_host_siginfo(&uinfo, p);
6246 unlock_user(p, arg1, 0);
6247 ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
6248 }
6249 break;
6250#ifdef TARGET_NR_sigreturn
6251 case TARGET_NR_sigreturn:
6252
6253 ret = do_sigreturn(cpu_env);
6254 break;
6255#endif
6256 case TARGET_NR_rt_sigreturn:
6257
6258 ret = do_rt_sigreturn(cpu_env);
6259 break;
6260 case TARGET_NR_sethostname:
6261 if (!(p = lock_user_string(arg1)))
6262 goto efault;
6263 ret = get_errno(sethostname(p, arg2));
6264 unlock_user(p, arg1, 0);
6265 break;
6266 case TARGET_NR_setrlimit:
6267 {
6268 int resource = target_to_host_resource(arg1);
6269 struct target_rlimit *target_rlim;
6270 struct rlimit rlim;
6271 if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
6272 goto efault;
6273 rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur);
6274 rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max);
6275 unlock_user_struct(target_rlim, arg2, 0);
6276 ret = get_errno(setrlimit(resource, &rlim));
6277 }
6278 break;
6279 case TARGET_NR_getrlimit:
6280 {
6281 int resource = target_to_host_resource(arg1);
6282 struct target_rlimit *target_rlim;
6283 struct rlimit rlim;
6284
6285 ret = get_errno(getrlimit(resource, &rlim));
6286 if (!is_error(ret)) {
6287 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
6288 goto efault;
6289 target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
6290 target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
6291 unlock_user_struct(target_rlim, arg2, 1);
6292 }
6293 }
6294 break;
6295 case TARGET_NR_getrusage:
6296 {
6297 struct rusage rusage;
6298 ret = get_errno(getrusage(arg1, &rusage));
6299 if (!is_error(ret)) {
6300 host_to_target_rusage(arg2, &rusage);
6301 }
6302 }
6303 break;
6304 case TARGET_NR_gettimeofday:
6305 {
6306 struct timeval tv;
6307 ret = get_errno(gettimeofday(&tv, NULL));
6308 if (!is_error(ret)) {
6309 if (copy_to_user_timeval(arg1, &tv))
6310 goto efault;
6311 }
6312 }
6313 break;
6314 case TARGET_NR_settimeofday:
6315 {
6316 struct timeval tv;
6317 if (copy_from_user_timeval(&tv, arg1))
6318 goto efault;
6319 ret = get_errno(settimeofday(&tv, NULL));
6320 }
6321 break;
6322#if defined(TARGET_NR_select)
6323 case TARGET_NR_select:
6324#if defined(TARGET_S390X) || defined(TARGET_ALPHA)
6325 ret = do_select(arg1, arg2, arg3, arg4, arg5);
6326#else
6327 {
6328 struct target_sel_arg_struct *sel;
6329 abi_ulong inp, outp, exp, tvp;
6330 long nsel;
6331
6332 if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
6333 goto efault;
6334 nsel = tswapal(sel->n);
6335 inp = tswapal(sel->inp);
6336 outp = tswapal(sel->outp);
6337 exp = tswapal(sel->exp);
6338 tvp = tswapal(sel->tvp);
6339 unlock_user_struct(sel, arg1, 0);
6340 ret = do_select(nsel, inp, outp, exp, tvp);
6341 }
6342#endif
6343 break;
6344#endif
6345#ifdef TARGET_NR_pselect6
6346 case TARGET_NR_pselect6:
6347 {
6348 abi_long rfd_addr, wfd_addr, efd_addr, n, ts_addr;
6349 fd_set rfds, wfds, efds;
6350 fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
6351 struct timespec ts, *ts_ptr;
6352
6353
6354
6355
6356
6357 sigset_t set;
6358 struct {
6359 sigset_t *set;
6360 size_t size;
6361 } sig, *sig_ptr;
6362
6363 abi_ulong arg_sigset, arg_sigsize, *arg7;
6364 target_sigset_t *target_sigset;
6365
6366 n = arg1;
6367 rfd_addr = arg2;
6368 wfd_addr = arg3;
6369 efd_addr = arg4;
6370 ts_addr = arg5;
6371
6372 ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
6373 if (ret) {
6374 goto fail;
6375 }
6376 ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
6377 if (ret) {
6378 goto fail;
6379 }
6380 ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
6381 if (ret) {
6382 goto fail;
6383 }
6384
6385
6386
6387
6388
6389 if (ts_addr) {
6390 if (target_to_host_timespec(&ts, ts_addr)) {
6391 goto efault;
6392 }
6393 ts_ptr = &ts;
6394 } else {
6395 ts_ptr = NULL;
6396 }
6397
6398
6399 if (arg6) {
6400 sig_ptr = &sig;
6401 sig.size = _NSIG / 8;
6402
6403 arg7 = lock_user(VERIFY_READ, arg6, sizeof(*arg7) * 2, 1);
6404 if (!arg7) {
6405 goto efault;
6406 }
6407 arg_sigset = tswapal(arg7[0]);
6408 arg_sigsize = tswapal(arg7[1]);
6409 unlock_user(arg7, arg6, 0);
6410
6411 if (arg_sigset) {
6412 sig.set = &set;
6413 if (arg_sigsize != sizeof(*target_sigset)) {
6414
6415 ret = -TARGET_EINVAL;
6416 goto fail;
6417 }
6418 target_sigset = lock_user(VERIFY_READ, arg_sigset,
6419 sizeof(*target_sigset), 1);
6420 if (!target_sigset) {
6421 goto efault;
6422 }
6423 target_to_host_sigset(&set, target_sigset);
6424 unlock_user(target_sigset, arg_sigset, 0);
6425 } else {
6426 sig.set = NULL;
6427 }
6428 } else {
6429 sig_ptr = NULL;
6430 }
6431
6432 ret = get_errno(sys_pselect6(n, rfds_ptr, wfds_ptr, efds_ptr,
6433 ts_ptr, sig_ptr));
6434
6435 if (!is_error(ret)) {
6436 if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
6437 goto efault;
6438 if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
6439 goto efault;
6440 if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
6441 goto efault;
6442
6443 if (ts_addr && host_to_target_timespec(ts_addr, &ts))
6444 goto efault;
6445 }
6446 }
6447 break;
6448#endif
6449 case TARGET_NR_symlink:
6450 {
6451 void *p2;
6452 p = lock_user_string(arg1);
6453 p2 = lock_user_string(arg2);
6454 if (!p || !p2)
6455 ret = -TARGET_EFAULT;
6456 else
6457 ret = get_errno(symlink(p, p2));
6458 unlock_user(p2, arg2, 0);
6459 unlock_user(p, arg1, 0);
6460 }
6461 break;
6462#if defined(TARGET_NR_symlinkat)
6463 case TARGET_NR_symlinkat:
6464 {
6465 void *p2;
6466 p = lock_user_string(arg1);
6467 p2 = lock_user_string(arg3);
6468 if (!p || !p2)
6469 ret = -TARGET_EFAULT;
6470 else
6471 ret = get_errno(symlinkat(p, arg2, p2));
6472 unlock_user(p2, arg3, 0);
6473 unlock_user(p, arg1, 0);
6474 }
6475 break;
6476#endif
6477#ifdef TARGET_NR_oldlstat
6478 case TARGET_NR_oldlstat:
6479 goto unimplemented;
6480#endif
6481 case TARGET_NR_readlink:
6482 {
6483 void *p2;
6484 p = lock_user_string(arg1);
6485 p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
6486 if (!p || !p2) {
6487 ret = -TARGET_EFAULT;
6488 } else if (is_proc_myself((const char *)p, "exe")) {
6489 char real[PATH_MAX], *temp;
6490 temp = realpath(exec_path, real);
6491 ret = temp == NULL ? get_errno(-1) : strlen(real) ;
6492 snprintf((char *)p2, arg3, "%s", real);
6493 } else {
6494 ret = get_errno(readlink(path(p), p2, arg3));
6495 }
6496 unlock_user(p2, arg2, ret);
6497 unlock_user(p, arg1, 0);
6498 }
6499 break;
6500#if defined(TARGET_NR_readlinkat)
6501 case TARGET_NR_readlinkat:
6502 {
6503 void *p2;
6504 p = lock_user_string(arg2);
6505 p2 = lock_user(VERIFY_WRITE, arg3, arg4, 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, arg4, "%s", real);
6513 } else {
6514 ret = get_errno(readlinkat(arg1, path(p), p2, arg4));
6515 }
6516 unlock_user(p2, arg3, ret);
6517 unlock_user(p, arg2, 0);
6518 }
6519 break;
6520#endif
6521#ifdef TARGET_NR_uselib
6522 case TARGET_NR_uselib:
6523 goto unimplemented;
6524#endif
6525#ifdef TARGET_NR_swapon
6526 case TARGET_NR_swapon:
6527 if (!(p = lock_user_string(arg1)))
6528 goto efault;
6529 ret = get_errno(swapon(p, arg2));
6530 unlock_user(p, arg1, 0);
6531 break;
6532#endif
6533 case TARGET_NR_reboot:
6534 if (arg3 == LINUX_REBOOT_CMD_RESTART2) {
6535
6536 p = lock_user_string(arg4);
6537 if (!p) {
6538 goto efault;
6539 }
6540 ret = get_errno(reboot(arg1, arg2, arg3, p));
6541 unlock_user(p, arg4, 0);
6542 } else {
6543 ret = get_errno(reboot(arg1, arg2, arg3, NULL));
6544 }
6545 break;
6546#ifdef TARGET_NR_readdir
6547 case TARGET_NR_readdir:
6548 goto unimplemented;
6549#endif
6550#ifdef TARGET_NR_mmap
6551 case TARGET_NR_mmap:
6552#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || \
6553 (defined(TARGET_ARM) && defined(TARGET_ABI32)) || \
6554 defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) \
6555 || defined(TARGET_S390X)
6556 {
6557 abi_ulong *v;
6558 abi_ulong v1, v2, v3, v4, v5, v6;
6559 if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
6560 goto efault;
6561 v1 = tswapal(v[0]);
6562 v2 = tswapal(v[1]);
6563 v3 = tswapal(v[2]);
6564 v4 = tswapal(v[3]);
6565 v5 = tswapal(v[4]);
6566 v6 = tswapal(v[5]);
6567 unlock_user(v, arg1, 0);
6568 ret = get_errno(target_mmap(v1, v2, v3,
6569 target_to_host_bitmask(v4, mmap_flags_tbl),
6570 v5, v6));
6571 }
6572#else
6573 ret = get_errno(target_mmap(arg1, arg2, arg3,
6574 target_to_host_bitmask(arg4, mmap_flags_tbl),
6575 arg5,
6576 arg6));
6577#endif
6578 break;
6579#endif
6580#ifdef TARGET_NR_mmap2
6581 case TARGET_NR_mmap2:
6582#ifndef MMAP_SHIFT
6583#define MMAP_SHIFT 12
6584#endif
6585 ret = get_errno(target_mmap(arg1, arg2, arg3,
6586 target_to_host_bitmask(arg4, mmap_flags_tbl),
6587 arg5,
6588 arg6 << MMAP_SHIFT));
6589 break;
6590#endif
6591 case TARGET_NR_munmap:
6592 ret = get_errno(target_munmap(arg1, arg2));
6593 break;
6594 case TARGET_NR_mprotect:
6595 {
6596 TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
6597
6598 if ((arg3 & PROT_GROWSDOWN)
6599 && arg1 >= ts->info->stack_limit
6600 && arg1 <= ts->info->start_stack) {
6601 arg3 &= ~PROT_GROWSDOWN;
6602 arg2 = arg2 + arg1 - ts->info->stack_limit;
6603 arg1 = ts->info->stack_limit;
6604 }
6605 }
6606 ret = get_errno(target_mprotect(arg1, arg2, arg3));
6607 break;
6608#ifdef TARGET_NR_mremap
6609 case TARGET_NR_mremap:
6610 ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
6611 break;
6612#endif
6613
6614#ifdef TARGET_NR_msync
6615 case TARGET_NR_msync:
6616 ret = get_errno(msync(g2h(arg1), arg2, arg3));
6617 break;
6618#endif
6619#ifdef TARGET_NR_mlock
6620 case TARGET_NR_mlock:
6621 ret = get_errno(mlock(g2h(arg1), arg2));
6622 break;
6623#endif
6624#ifdef TARGET_NR_munlock
6625 case TARGET_NR_munlock:
6626 ret = get_errno(munlock(g2h(arg1), arg2));
6627 break;
6628#endif
6629#ifdef TARGET_NR_mlockall
6630 case TARGET_NR_mlockall:
6631 ret = get_errno(mlockall(arg1));
6632 break;
6633#endif
6634#ifdef TARGET_NR_munlockall
6635 case TARGET_NR_munlockall:
6636 ret = get_errno(munlockall());
6637 break;
6638#endif
6639 case TARGET_NR_truncate:
6640 if (!(p = lock_user_string(arg1)))
6641 goto efault;
6642 ret = get_errno(truncate(p, arg2));
6643 unlock_user(p, arg1, 0);
6644 break;
6645 case TARGET_NR_ftruncate:
6646 ret = get_errno(ftruncate(arg1, arg2));
6647 break;
6648 case TARGET_NR_fchmod:
6649 ret = get_errno(fchmod(arg1, arg2));
6650 break;
6651#if defined(TARGET_NR_fchmodat)
6652 case TARGET_NR_fchmodat:
6653 if (!(p = lock_user_string(arg2)))
6654 goto efault;
6655 ret = get_errno(fchmodat(arg1, p, arg3, 0));
6656 unlock_user(p, arg2, 0);
6657 break;
6658#endif
6659 case TARGET_NR_getpriority:
6660
6661
6662 errno = 0;
6663 ret = getpriority(arg1, arg2);
6664 if (ret == -1 && errno != 0) {
6665 ret = -host_to_target_errno(errno);
6666 break;
6667 }
6668#ifdef TARGET_ALPHA
6669
6670 ((CPUAlphaState *)cpu_env)->ir[IR_V0] = 0;
6671#else
6672
6673 ret = 20 - ret;
6674#endif
6675 break;
6676 case TARGET_NR_setpriority:
6677 ret = get_errno(setpriority(arg1, arg2, arg3));
6678 break;
6679#ifdef TARGET_NR_profil
6680 case TARGET_NR_profil:
6681 goto unimplemented;
6682#endif
6683 case TARGET_NR_statfs:
6684 if (!(p = lock_user_string(arg1)))
6685 goto efault;
6686 ret = get_errno(statfs(path(p), &stfs));
6687 unlock_user(p, arg1, 0);
6688 convert_statfs:
6689 if (!is_error(ret)) {
6690 struct target_statfs *target_stfs;
6691
6692 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
6693 goto efault;
6694 __put_user(stfs.f_type, &target_stfs->f_type);
6695 __put_user(stfs.f_bsize, &target_stfs->f_bsize);
6696 __put_user(stfs.f_blocks, &target_stfs->f_blocks);
6697 __put_user(stfs.f_bfree, &target_stfs->f_bfree);
6698 __put_user(stfs.f_bavail, &target_stfs->f_bavail);
6699 __put_user(stfs.f_files, &target_stfs->f_files);
6700 __put_user(stfs.f_ffree, &target_stfs->f_ffree);
6701 __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
6702 __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
6703 __put_user(stfs.f_namelen, &target_stfs->f_namelen);
6704 __put_user(stfs.f_frsize, &target_stfs->f_frsize);
6705 memset(target_stfs->f_spare, 0, sizeof(target_stfs->f_spare));
6706 unlock_user_struct(target_stfs, arg2, 1);
6707 }
6708 break;
6709 case TARGET_NR_fstatfs:
6710 ret = get_errno(fstatfs(arg1, &stfs));
6711 goto convert_statfs;
6712#ifdef TARGET_NR_statfs64
6713 case TARGET_NR_statfs64:
6714 if (!(p = lock_user_string(arg1)))
6715 goto efault;
6716 ret = get_errno(statfs(path(p), &stfs));
6717 unlock_user(p, arg1, 0);
6718 convert_statfs64:
6719 if (!is_error(ret)) {
6720 struct target_statfs64 *target_stfs;
6721
6722 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
6723 goto efault;
6724 __put_user(stfs.f_type, &target_stfs->f_type);
6725 __put_user(stfs.f_bsize, &target_stfs->f_bsize);
6726 __put_user(stfs.f_blocks, &target_stfs->f_blocks);
6727 __put_user(stfs.f_bfree, &target_stfs->f_bfree);
6728 __put_user(stfs.f_bavail, &target_stfs->f_bavail);
6729 __put_user(stfs.f_files, &target_stfs->f_files);
6730 __put_user(stfs.f_ffree, &target_stfs->f_ffree);
6731 __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
6732 __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
6733 __put_user(stfs.f_namelen, &target_stfs->f_namelen);
6734 __put_user(stfs.f_frsize, &target_stfs->f_frsize);
6735 memset(target_stfs->f_spare, 0, sizeof(target_stfs->f_spare));
6736 unlock_user_struct(target_stfs, arg3, 1);
6737 }
6738 break;
6739 case TARGET_NR_fstatfs64:
6740 ret = get_errno(fstatfs(arg1, &stfs));
6741 goto convert_statfs64;
6742#endif
6743#ifdef TARGET_NR_ioperm
6744 case TARGET_NR_ioperm:
6745 goto unimplemented;
6746#endif
6747#ifdef TARGET_NR_socketcall
6748 case TARGET_NR_socketcall:
6749 ret = do_socketcall(arg1, arg2);
6750 break;
6751#endif
6752#ifdef TARGET_NR_accept
6753 case TARGET_NR_accept:
6754 ret = do_accept4(arg1, arg2, arg3, 0);
6755 break;
6756#endif
6757#ifdef TARGET_NR_accept4
6758 case TARGET_NR_accept4:
6759#ifdef CONFIG_ACCEPT4
6760 ret = do_accept4(arg1, arg2, arg3, arg4);
6761#else
6762 goto unimplemented;
6763#endif
6764 break;
6765#endif
6766#ifdef TARGET_NR_bind
6767 case TARGET_NR_bind:
6768 ret = do_bind(arg1, arg2, arg3);
6769 break;
6770#endif
6771#ifdef TARGET_NR_connect
6772 case TARGET_NR_connect:
6773 ret = do_connect(arg1, arg2, arg3);
6774 break;
6775#endif
6776#ifdef TARGET_NR_getpeername
6777 case TARGET_NR_getpeername:
6778 ret = do_getpeername(arg1, arg2, arg3);
6779 break;
6780#endif
6781#ifdef TARGET_NR_getsockname
6782 case TARGET_NR_getsockname:
6783 ret = do_getsockname(arg1, arg2, arg3);
6784 break;
6785#endif
6786#ifdef TARGET_NR_getsockopt
6787 case TARGET_NR_getsockopt:
6788 ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
6789 break;
6790#endif
6791#ifdef TARGET_NR_listen
6792 case TARGET_NR_listen:
6793 ret = get_errno(listen(arg1, arg2));
6794 break;
6795#endif
6796#ifdef TARGET_NR_recv
6797 case TARGET_NR_recv:
6798 ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
6799 break;
6800#endif
6801#ifdef TARGET_NR_recvfrom
6802 case TARGET_NR_recvfrom:
6803 ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
6804 break;
6805#endif
6806#ifdef TARGET_NR_recvmsg
6807 case TARGET_NR_recvmsg:
6808 ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
6809 break;
6810#endif
6811#ifdef TARGET_NR_send
6812 case TARGET_NR_send:
6813 ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
6814 break;
6815#endif
6816#ifdef TARGET_NR_sendmsg
6817 case TARGET_NR_sendmsg:
6818 ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
6819 break;
6820#endif
6821#ifdef TARGET_NR_sendto
6822 case TARGET_NR_sendto:
6823 ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
6824 break;
6825#endif
6826#ifdef TARGET_NR_shutdown
6827 case TARGET_NR_shutdown:
6828 ret = get_errno(shutdown(arg1, arg2));
6829 break;
6830#endif
6831#ifdef TARGET_NR_socket
6832 case TARGET_NR_socket:
6833 ret = do_socket(arg1, arg2, arg3);
6834 break;
6835#endif
6836#ifdef TARGET_NR_socketpair
6837 case TARGET_NR_socketpair:
6838 ret = do_socketpair(arg1, arg2, arg3, arg4);
6839 break;
6840#endif
6841#ifdef TARGET_NR_setsockopt
6842 case TARGET_NR_setsockopt:
6843 ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
6844 break;
6845#endif
6846
6847 case TARGET_NR_syslog:
6848 if (!(p = lock_user_string(arg2)))
6849 goto efault;
6850 ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
6851 unlock_user(p, arg2, 0);
6852 break;
6853
6854 case TARGET_NR_setitimer:
6855 {
6856 struct itimerval value, ovalue, *pvalue;
6857
6858 if (arg2) {
6859 pvalue = &value;
6860 if (copy_from_user_timeval(&pvalue->it_interval, arg2)
6861 || copy_from_user_timeval(&pvalue->it_value,
6862 arg2 + sizeof(struct target_timeval)))
6863 goto efault;
6864 } else {
6865 pvalue = NULL;
6866 }
6867 ret = get_errno(setitimer(arg1, pvalue, &ovalue));
6868 if (!is_error(ret) && arg3) {
6869 if (copy_to_user_timeval(arg3,
6870 &ovalue.it_interval)
6871 || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
6872 &ovalue.it_value))
6873 goto efault;
6874 }
6875 }
6876 break;
6877 case TARGET_NR_getitimer:
6878 {
6879 struct itimerval value;
6880
6881 ret = get_errno(getitimer(arg1, &value));
6882 if (!is_error(ret) && arg2) {
6883 if (copy_to_user_timeval(arg2,
6884 &value.it_interval)
6885 || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
6886 &value.it_value))
6887 goto efault;
6888 }
6889 }
6890 break;
6891 case TARGET_NR_stat:
6892 if (!(p = lock_user_string(arg1)))
6893 goto efault;
6894 ret = get_errno(stat(path(p), &st));
6895 unlock_user(p, arg1, 0);
6896 goto do_stat;
6897 case TARGET_NR_lstat:
6898 if (!(p = lock_user_string(arg1)))
6899 goto efault;
6900 ret = get_errno(lstat(path(p), &st));
6901 unlock_user(p, arg1, 0);
6902 goto do_stat;
6903 case TARGET_NR_fstat:
6904 {
6905 ret = get_errno(fstat(arg1, &st));
6906 do_stat:
6907 if (!is_error(ret)) {
6908 struct target_stat *target_st;
6909
6910 if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
6911 goto efault;
6912 memset(target_st, 0, sizeof(*target_st));
6913 __put_user(st.st_dev, &target_st->st_dev);
6914 __put_user(st.st_ino, &target_st->st_ino);
6915 __put_user(st.st_mode, &target_st->st_mode);
6916 __put_user(st.st_uid, &target_st->st_uid);
6917 __put_user(st.st_gid, &target_st->st_gid);
6918 __put_user(st.st_nlink, &target_st->st_nlink);
6919 __put_user(st.st_rdev, &target_st->st_rdev);
6920 __put_user(st.st_size, &target_st->st_size);
6921 __put_user(st.st_blksize, &target_st->st_blksize);
6922 __put_user(st.st_blocks, &target_st->st_blocks);
6923 __put_user(st.st_atime, &target_st->target_st_atime);
6924 __put_user(st.st_mtime, &target_st->target_st_mtime);
6925 __put_user(st.st_ctime, &target_st->target_st_ctime);
6926 unlock_user_struct(target_st, arg2, 1);
6927 }
6928 }
6929 break;
6930#ifdef TARGET_NR_olduname
6931 case TARGET_NR_olduname:
6932 goto unimplemented;
6933#endif
6934#ifdef TARGET_NR_iopl
6935 case TARGET_NR_iopl:
6936 goto unimplemented;
6937#endif
6938 case TARGET_NR_vhangup:
6939 ret = get_errno(vhangup());
6940 break;
6941#ifdef TARGET_NR_idle
6942 case TARGET_NR_idle:
6943 goto unimplemented;
6944#endif
6945#ifdef TARGET_NR_syscall
6946 case TARGET_NR_syscall:
6947 ret = do_syscall(cpu_env, arg1 & 0xffff, arg2, arg3, arg4, arg5,
6948 arg6, arg7, arg8, 0);
6949 break;
6950#endif
6951 case TARGET_NR_wait4:
6952 {
6953 int status;
6954 abi_long status_ptr = arg2;
6955 struct rusage rusage, *rusage_ptr;
6956 abi_ulong target_rusage = arg4;
6957 if (target_rusage)
6958 rusage_ptr = &rusage;
6959 else
6960 rusage_ptr = NULL;
6961 ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
6962 if (!is_error(ret)) {
6963 if (status_ptr && ret) {
6964 status = host_to_target_waitstatus(status);
6965 if (put_user_s32(status, status_ptr))
6966 goto efault;
6967 }
6968 if (target_rusage)
6969 host_to_target_rusage(target_rusage, &rusage);
6970 }
6971 }
6972 break;
6973#ifdef TARGET_NR_swapoff
6974 case TARGET_NR_swapoff:
6975 if (!(p = lock_user_string(arg1)))
6976 goto efault;
6977 ret = get_errno(swapoff(p));
6978 unlock_user(p, arg1, 0);
6979 break;
6980#endif
6981 case TARGET_NR_sysinfo:
6982 {
6983 struct target_sysinfo *target_value;
6984 struct sysinfo value;
6985 ret = get_errno(sysinfo(&value));
6986 if (!is_error(ret) && arg1)
6987 {
6988 if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
6989 goto efault;
6990 __put_user(value.uptime, &target_value->uptime);
6991 __put_user(value.loads[0], &target_value->loads[0]);
6992 __put_user(value.loads[1], &target_value->loads[1]);
6993 __put_user(value.loads[2], &target_value->loads[2]);
6994 __put_user(value.totalram, &target_value->totalram);
6995 __put_user(value.freeram, &target_value->freeram);
6996 __put_user(value.sharedram, &target_value->sharedram);
6997 __put_user(value.bufferram, &target_value->bufferram);
6998 __put_user(value.totalswap, &target_value->totalswap);
6999 __put_user(value.freeswap, &target_value->freeswap);
7000 __put_user(value.procs, &target_value->procs);
7001 __put_user(value.totalhigh, &target_value->totalhigh);
7002 __put_user(value.freehigh, &target_value->freehigh);
7003 __put_user(value.mem_unit, &target_value->mem_unit);
7004 unlock_user_struct(target_value, arg1, 1);
7005 }
7006 }
7007 break;
7008#ifdef TARGET_NR_ipc
7009 case TARGET_NR_ipc:
7010 ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
7011 break;
7012#endif
7013#ifdef TARGET_NR_semget
7014 case TARGET_NR_semget:
7015 ret = get_errno(semget(arg1, arg2, arg3));
7016 break;
7017#endif
7018#ifdef TARGET_NR_semop
7019 case TARGET_NR_semop:
7020 ret = do_semop(arg1, arg2, arg3);
7021 break;
7022#endif
7023#ifdef TARGET_NR_semctl
7024 case TARGET_NR_semctl:
7025 ret = do_semctl(arg1, arg2, arg3, (union target_semun)(abi_ulong)arg4);
7026 break;
7027#endif
7028#ifdef TARGET_NR_msgctl
7029 case TARGET_NR_msgctl:
7030 ret = do_msgctl(arg1, arg2, arg3);
7031 break;
7032#endif
7033#ifdef TARGET_NR_msgget
7034 case TARGET_NR_msgget:
7035 ret = get_errno(msgget(arg1, arg2));
7036 break;
7037#endif
7038#ifdef TARGET_NR_msgrcv
7039 case TARGET_NR_msgrcv:
7040 ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
7041 break;
7042#endif
7043#ifdef TARGET_NR_msgsnd
7044 case TARGET_NR_msgsnd:
7045 ret = do_msgsnd(arg1, arg2, arg3, arg4);
7046 break;
7047#endif
7048#ifdef TARGET_NR_shmget
7049 case TARGET_NR_shmget:
7050 ret = get_errno(shmget(arg1, arg2, arg3));
7051 break;
7052#endif
7053#ifdef TARGET_NR_shmctl
7054 case TARGET_NR_shmctl:
7055 ret = do_shmctl(arg1, arg2, arg3);
7056 break;
7057#endif
7058#ifdef TARGET_NR_shmat
7059 case TARGET_NR_shmat:
7060 ret = do_shmat(arg1, arg2, arg3);
7061 break;
7062#endif
7063#ifdef TARGET_NR_shmdt
7064 case TARGET_NR_shmdt:
7065 ret = do_shmdt(arg1);
7066 break;
7067#endif
7068 case TARGET_NR_fsync:
7069 ret = get_errno(fsync(arg1));
7070 break;
7071 case TARGET_NR_clone:
7072
7073
7074
7075
7076
7077
7078#if defined(TARGET_MICROBLAZE)
7079 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg4, arg6, arg5));
7080#elif defined(TARGET_CLONE_BACKWARDS)
7081 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
7082#elif defined(TARGET_CLONE_BACKWARDS2)
7083 ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg5, arg4));
7084#else
7085 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
7086#endif
7087 break;
7088#ifdef __NR_exit_group
7089
7090 case TARGET_NR_exit_group:
7091#ifdef TARGET_GPROF
7092 _mcleanup();
7093#endif
7094 gdb_exit(cpu_env, arg1);
7095 ret = get_errno(exit_group(arg1));
7096 break;
7097#endif
7098 case TARGET_NR_setdomainname:
7099 if (!(p = lock_user_string(arg1)))
7100 goto efault;
7101 ret = get_errno(setdomainname(p, arg2));
7102 unlock_user(p, arg1, 0);
7103 break;
7104 case TARGET_NR_uname:
7105
7106 {
7107 struct new_utsname * buf;
7108
7109 if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
7110 goto efault;
7111 ret = get_errno(sys_uname(buf));
7112 if (!is_error(ret)) {
7113
7114
7115 strcpy (buf->machine, cpu_to_uname_machine(cpu_env));
7116
7117 if (qemu_uname_release && *qemu_uname_release)
7118 strcpy (buf->release, qemu_uname_release);
7119 }
7120 unlock_user_struct(buf, arg1, 1);
7121 }
7122 break;
7123#ifdef TARGET_I386
7124 case TARGET_NR_modify_ldt:
7125 ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
7126 break;
7127#if !defined(TARGET_X86_64)
7128 case TARGET_NR_vm86old:
7129 goto unimplemented;
7130 case TARGET_NR_vm86:
7131 ret = do_vm86(cpu_env, arg1, arg2);
7132 break;
7133#endif
7134#endif
7135 case TARGET_NR_adjtimex:
7136 goto unimplemented;
7137#ifdef TARGET_NR_create_module
7138 case TARGET_NR_create_module:
7139#endif
7140 case TARGET_NR_init_module:
7141 case TARGET_NR_delete_module:
7142#ifdef TARGET_NR_get_kernel_syms
7143 case TARGET_NR_get_kernel_syms:
7144#endif
7145 goto unimplemented;
7146 case TARGET_NR_quotactl:
7147 goto unimplemented;
7148 case TARGET_NR_getpgid:
7149 ret = get_errno(getpgid(arg1));
7150 break;
7151 case TARGET_NR_fchdir:
7152 ret = get_errno(fchdir(arg1));
7153 break;
7154#ifdef TARGET_NR_bdflush
7155 case TARGET_NR_bdflush:
7156 goto unimplemented;
7157#endif
7158#ifdef TARGET_NR_sysfs
7159 case TARGET_NR_sysfs:
7160 goto unimplemented;
7161#endif
7162 case TARGET_NR_personality:
7163 ret = get_errno(personality(arg1));
7164 break;
7165#ifdef TARGET_NR_afs_syscall
7166 case TARGET_NR_afs_syscall:
7167 goto unimplemented;
7168#endif
7169#ifdef TARGET_NR__llseek
7170 case TARGET_NR__llseek:
7171 {
7172 int64_t res;
7173#if !defined(__NR_llseek)
7174 res = lseek(arg1, ((uint64_t)arg2 << 32) | arg3, arg5);
7175 if (res == -1) {
7176 ret = get_errno(res);
7177 } else {
7178 ret = 0;
7179 }
7180#else
7181 ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
7182#endif
7183 if ((ret == 0) && put_user_s64(res, arg4)) {
7184 goto efault;
7185 }
7186 }
7187 break;
7188#endif
7189 case TARGET_NR_getdents:
7190#ifdef __NR_getdents
7191#if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
7192 {
7193 struct target_dirent *target_dirp;
7194 struct linux_dirent *dirp;
7195 abi_long count = arg3;
7196
7197 dirp = malloc(count);
7198 if (!dirp) {
7199 ret = -TARGET_ENOMEM;
7200 goto fail;
7201 }
7202
7203 ret = get_errno(sys_getdents(arg1, dirp, count));
7204 if (!is_error(ret)) {
7205 struct linux_dirent *de;
7206 struct target_dirent *tde;
7207 int len = ret;
7208 int reclen, treclen;
7209 int count1, tnamelen;
7210
7211 count1 = 0;
7212 de = dirp;
7213 if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
7214 goto efault;
7215 tde = target_dirp;
7216 while (len > 0) {
7217 reclen = de->d_reclen;
7218 tnamelen = reclen - offsetof(struct linux_dirent, d_name);
7219 assert(tnamelen >= 0);
7220 treclen = tnamelen + offsetof(struct target_dirent, d_name);
7221 assert(count1 + treclen <= count);
7222 tde->d_reclen = tswap16(treclen);
7223 tde->d_ino = tswapal(de->d_ino);
7224 tde->d_off = tswapal(de->d_off);
7225 memcpy(tde->d_name, de->d_name, tnamelen);
7226 de = (struct linux_dirent *)((char *)de + reclen);
7227 len -= reclen;
7228 tde = (struct target_dirent *)((char *)tde + treclen);
7229 count1 += treclen;
7230 }
7231 ret = count1;
7232 unlock_user(target_dirp, arg2, ret);
7233 }
7234 free(dirp);
7235 }
7236#else
7237 {
7238 struct linux_dirent *dirp;
7239 abi_long count = arg3;
7240
7241 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
7242 goto efault;
7243 ret = get_errno(sys_getdents(arg1, dirp, count));
7244 if (!is_error(ret)) {
7245 struct linux_dirent *de;
7246 int len = ret;
7247 int reclen;
7248 de = dirp;
7249 while (len > 0) {
7250 reclen = de->d_reclen;
7251 if (reclen > len)
7252 break;
7253 de->d_reclen = tswap16(reclen);
7254 tswapls(&de->d_ino);
7255 tswapls(&de->d_off);
7256 de = (struct linux_dirent *)((char *)de + reclen);
7257 len -= reclen;
7258 }
7259 }
7260 unlock_user(dirp, arg2, ret);
7261 }
7262#endif
7263#else
7264
7265 {
7266 struct linux_dirent64 *dirp;
7267 abi_long count = arg3;
7268
7269 dirp = lock_user(VERIFY_WRITE, arg2, count, 0);
7270 if (!dirp) {
7271 goto efault;
7272 }
7273 ret = get_errno(sys_getdents64(arg1, dirp, count));
7274 if (!is_error(ret)) {
7275
7276
7277
7278
7279
7280 struct linux_dirent64 *de;
7281 struct target_dirent *tde;
7282 int len = ret;
7283 int tlen = 0;
7284
7285 de = dirp;
7286 tde = (struct target_dirent *)dirp;
7287 while (len > 0) {
7288 int namelen, treclen;
7289 int reclen = de->d_reclen;
7290 uint64_t ino = de->d_ino;
7291 int64_t off = de->d_off;
7292 uint8_t type = de->d_type;
7293
7294 namelen = strlen(de->d_name);
7295 treclen = offsetof(struct target_dirent, d_name)
7296 + namelen + 2;
7297 treclen = QEMU_ALIGN_UP(treclen, sizeof(abi_long));
7298
7299 memmove(tde->d_name, de->d_name, namelen + 1);
7300 tde->d_ino = tswapal(ino);
7301 tde->d_off = tswapal(off);
7302 tde->d_reclen = tswap16(treclen);
7303
7304
7305
7306 *(((char *)tde) + treclen - 1) = type;
7307
7308 de = (struct linux_dirent64 *)((char *)de + reclen);
7309 tde = (struct target_dirent *)((char *)tde + treclen);
7310 len -= reclen;
7311 tlen += treclen;
7312 }
7313 ret = tlen;
7314 }
7315 unlock_user(dirp, arg2, ret);
7316 }
7317#endif
7318 break;
7319#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
7320 case TARGET_NR_getdents64:
7321 {
7322 struct linux_dirent64 *dirp;
7323 abi_long count = arg3;
7324 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
7325 goto efault;
7326 ret = get_errno(sys_getdents64(arg1, dirp, count));
7327 if (!is_error(ret)) {
7328 struct linux_dirent64 *de;
7329 int len = ret;
7330 int reclen;
7331 de = dirp;
7332 while (len > 0) {
7333 reclen = de->d_reclen;
7334 if (reclen > len)
7335 break;
7336 de->d_reclen = tswap16(reclen);
7337 tswap64s((uint64_t *)&de->d_ino);
7338 tswap64s((uint64_t *)&de->d_off);
7339 de = (struct linux_dirent64 *)((char *)de + reclen);
7340 len -= reclen;
7341 }
7342 }
7343 unlock_user(dirp, arg2, ret);
7344 }
7345 break;
7346#endif
7347#if defined(TARGET_NR__newselect)
7348 case TARGET_NR__newselect:
7349 ret = do_select(arg1, arg2, arg3, arg4, arg5);
7350 break;
7351#endif
7352#if defined(TARGET_NR_poll) || defined(TARGET_NR_ppoll)
7353# ifdef TARGET_NR_poll
7354 case TARGET_NR_poll:
7355# endif
7356# ifdef TARGET_NR_ppoll
7357 case TARGET_NR_ppoll:
7358# endif
7359 {
7360 struct target_pollfd *target_pfd;
7361 unsigned int nfds = arg2;
7362 int timeout = arg3;
7363 struct pollfd *pfd;
7364 unsigned int i;
7365
7366 target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
7367 if (!target_pfd)
7368 goto efault;
7369
7370 pfd = alloca(sizeof(struct pollfd) * nfds);
7371 for(i = 0; i < nfds; i++) {
7372 pfd[i].fd = tswap32(target_pfd[i].fd);
7373 pfd[i].events = tswap16(target_pfd[i].events);
7374 }
7375
7376# ifdef TARGET_NR_ppoll
7377 if (num == TARGET_NR_ppoll) {
7378 struct timespec _timeout_ts, *timeout_ts = &_timeout_ts;
7379 target_sigset_t *target_set;
7380 sigset_t _set, *set = &_set;
7381
7382 if (arg3) {
7383 if (target_to_host_timespec(timeout_ts, arg3)) {
7384 unlock_user(target_pfd, arg1, 0);
7385 goto efault;
7386 }
7387 } else {
7388 timeout_ts = NULL;
7389 }
7390
7391 if (arg4) {
7392 target_set = lock_user(VERIFY_READ, arg4, sizeof(target_sigset_t), 1);
7393 if (!target_set) {
7394 unlock_user(target_pfd, arg1, 0);
7395 goto efault;
7396 }
7397 target_to_host_sigset(set, target_set);
7398 } else {
7399 set = NULL;
7400 }
7401
7402 ret = get_errno(sys_ppoll(pfd, nfds, timeout_ts, set, _NSIG/8));
7403
7404 if (!is_error(ret) && arg3) {
7405 host_to_target_timespec(arg3, timeout_ts);
7406 }
7407 if (arg4) {
7408 unlock_user(target_set, arg4, 0);
7409 }
7410 } else
7411# endif
7412 ret = get_errno(poll(pfd, nfds, timeout));
7413
7414 if (!is_error(ret)) {
7415 for(i = 0; i < nfds; i++) {
7416 target_pfd[i].revents = tswap16(pfd[i].revents);
7417 }
7418 }
7419 unlock_user(target_pfd, arg1, sizeof(struct target_pollfd) * nfds);
7420 }
7421 break;
7422#endif
7423 case TARGET_NR_flock:
7424
7425
7426 ret = get_errno(flock(arg1, arg2));
7427 break;
7428 case TARGET_NR_readv:
7429 {
7430 struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 0);
7431 if (vec != NULL) {
7432 ret = get_errno(readv(arg1, vec, arg3));
7433 unlock_iovec(vec, arg2, arg3, 1);
7434 } else {
7435 ret = -host_to_target_errno(errno);
7436 }
7437 }
7438 break;
7439 case TARGET_NR_writev:
7440 {
7441 struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
7442 if (vec != NULL) {
7443 ret = get_errno(writev(arg1, vec, arg3));
7444 unlock_iovec(vec, arg2, arg3, 0);
7445 } else {
7446 ret = -host_to_target_errno(errno);
7447 }
7448 }
7449 break;
7450 case TARGET_NR_getsid:
7451 ret = get_errno(getsid(arg1));
7452 break;
7453#if defined(TARGET_NR_fdatasync)
7454 case TARGET_NR_fdatasync:
7455 ret = get_errno(fdatasync(arg1));
7456 break;
7457#endif
7458 case TARGET_NR__sysctl:
7459
7460
7461 ret = -TARGET_ENOTDIR;
7462 break;
7463 case TARGET_NR_sched_getaffinity:
7464 {
7465 unsigned int mask_size;
7466 unsigned long *mask;
7467
7468
7469
7470
7471
7472 if (arg2 & (sizeof(abi_ulong) - 1)) {
7473 ret = -TARGET_EINVAL;
7474 break;
7475 }
7476 mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
7477
7478 mask = alloca(mask_size);
7479 ret = get_errno(sys_sched_getaffinity(arg1, mask_size, mask));
7480
7481 if (!is_error(ret)) {
7482 if (copy_to_user(arg3, mask, ret)) {
7483 goto efault;
7484 }
7485 }
7486 }
7487 break;
7488 case TARGET_NR_sched_setaffinity:
7489 {
7490 unsigned int mask_size;
7491 unsigned long *mask;
7492
7493
7494
7495
7496
7497 if (arg2 & (sizeof(abi_ulong) - 1)) {
7498 ret = -TARGET_EINVAL;
7499 break;
7500 }
7501 mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
7502
7503 mask = alloca(mask_size);
7504 if (!lock_user_struct(VERIFY_READ, p, arg3, 1)) {
7505 goto efault;
7506 }
7507 memcpy(mask, p, arg2);
7508 unlock_user_struct(p, arg2, 0);
7509
7510 ret = get_errno(sys_sched_setaffinity(arg1, mask_size, mask));
7511 }
7512 break;
7513 case TARGET_NR_sched_setparam:
7514 {
7515 struct sched_param *target_schp;
7516 struct sched_param schp;
7517
7518 if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
7519 goto efault;
7520 schp.sched_priority = tswap32(target_schp->sched_priority);
7521 unlock_user_struct(target_schp, arg2, 0);
7522 ret = get_errno(sched_setparam(arg1, &schp));
7523 }
7524 break;
7525 case TARGET_NR_sched_getparam:
7526 {
7527 struct sched_param *target_schp;
7528 struct sched_param schp;
7529 ret = get_errno(sched_getparam(arg1, &schp));
7530 if (!is_error(ret)) {
7531 if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
7532 goto efault;
7533 target_schp->sched_priority = tswap32(schp.sched_priority);
7534 unlock_user_struct(target_schp, arg2, 1);
7535 }
7536 }
7537 break;
7538 case TARGET_NR_sched_setscheduler:
7539 {
7540 struct sched_param *target_schp;
7541 struct sched_param schp;
7542 if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
7543 goto efault;
7544 schp.sched_priority = tswap32(target_schp->sched_priority);
7545 unlock_user_struct(target_schp, arg3, 0);
7546 ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
7547 }
7548 break;
7549 case TARGET_NR_sched_getscheduler:
7550 ret = get_errno(sched_getscheduler(arg1));
7551 break;
7552 case TARGET_NR_sched_yield:
7553 ret = get_errno(sched_yield());
7554 break;
7555 case TARGET_NR_sched_get_priority_max:
7556 ret = get_errno(sched_get_priority_max(arg1));
7557 break;
7558 case TARGET_NR_sched_get_priority_min:
7559 ret = get_errno(sched_get_priority_min(arg1));
7560 break;
7561 case TARGET_NR_sched_rr_get_interval:
7562 {
7563 struct timespec ts;
7564 ret = get_errno(sched_rr_get_interval(arg1, &ts));
7565 if (!is_error(ret)) {
7566 host_to_target_timespec(arg2, &ts);
7567 }
7568 }
7569 break;
7570 case TARGET_NR_nanosleep:
7571 {
7572 struct timespec req, rem;
7573 target_to_host_timespec(&req, arg1);
7574 ret = get_errno(nanosleep(&req, &rem));
7575 if (is_error(ret) && arg2) {
7576 host_to_target_timespec(arg2, &rem);
7577 }
7578 }
7579 break;
7580#ifdef TARGET_NR_query_module
7581 case TARGET_NR_query_module:
7582 goto unimplemented;
7583#endif
7584#ifdef TARGET_NR_nfsservctl
7585 case TARGET_NR_nfsservctl:
7586 goto unimplemented;
7587#endif
7588 case TARGET_NR_prctl:
7589 switch (arg1) {
7590 case PR_GET_PDEATHSIG:
7591 {
7592 int deathsig;
7593 ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
7594 if (!is_error(ret) && arg2
7595 && put_user_ual(deathsig, arg2)) {
7596 goto efault;
7597 }
7598 break;
7599 }
7600#ifdef PR_GET_NAME
7601 case PR_GET_NAME:
7602 {
7603 void *name = lock_user(VERIFY_WRITE, arg2, 16, 1);
7604 if (!name) {
7605 goto efault;
7606 }
7607 ret = get_errno(prctl(arg1, (unsigned long)name,
7608 arg3, arg4, arg5));
7609 unlock_user(name, arg2, 16);
7610 break;
7611 }
7612 case PR_SET_NAME:
7613 {
7614 void *name = lock_user(VERIFY_READ, arg2, 16, 1);
7615 if (!name) {
7616 goto efault;
7617 }
7618 ret = get_errno(prctl(arg1, (unsigned long)name,
7619 arg3, arg4, arg5));
7620 unlock_user(name, arg2, 0);
7621 break;
7622 }
7623#endif
7624 default:
7625
7626 ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
7627 break;
7628 }
7629 break;
7630#ifdef TARGET_NR_arch_prctl
7631 case TARGET_NR_arch_prctl:
7632#if defined(TARGET_I386) && !defined(TARGET_ABI32)
7633 ret = do_arch_prctl(cpu_env, arg1, arg2);
7634 break;
7635#else
7636 goto unimplemented;
7637#endif
7638#endif
7639#ifdef TARGET_NR_pread64
7640 case TARGET_NR_pread64:
7641 if (regpairs_aligned(cpu_env)) {
7642 arg4 = arg5;
7643 arg5 = arg6;
7644 }
7645 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
7646 goto efault;
7647 ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
7648 unlock_user(p, arg2, ret);
7649 break;
7650 case TARGET_NR_pwrite64:
7651 if (regpairs_aligned(cpu_env)) {
7652 arg4 = arg5;
7653 arg5 = arg6;
7654 }
7655 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
7656 goto efault;
7657 ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
7658 unlock_user(p, arg2, 0);
7659 break;
7660#endif
7661 case TARGET_NR_getcwd:
7662 if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
7663 goto efault;
7664 ret = get_errno(sys_getcwd1(p, arg2));
7665 unlock_user(p, arg1, ret);
7666 break;
7667 case TARGET_NR_capget:
7668 goto unimplemented;
7669 case TARGET_NR_capset:
7670 goto unimplemented;
7671 case TARGET_NR_sigaltstack:
7672#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
7673 defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA) || \
7674 defined(TARGET_M68K) || defined(TARGET_S390X) || defined(TARGET_OPENRISC)
7675 ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUArchState *)cpu_env));
7676 break;
7677#else
7678 goto unimplemented;
7679#endif
7680
7681#ifdef CONFIG_SENDFILE
7682 case TARGET_NR_sendfile:
7683 {
7684 off_t *offp = NULL;
7685 off_t off;
7686 if (arg3) {
7687 ret = get_user_sal(off, arg3);
7688 if (is_error(ret)) {
7689 break;
7690 }
7691 offp = &off;
7692 }
7693 ret = get_errno(sendfile(arg1, arg2, offp, arg4));
7694 if (!is_error(ret) && arg3) {
7695 abi_long ret2 = put_user_sal(off, arg3);
7696 if (is_error(ret2)) {
7697 ret = ret2;
7698 }
7699 }
7700 break;
7701 }
7702#ifdef TARGET_NR_sendfile64
7703 case TARGET_NR_sendfile64:
7704 {
7705 off_t *offp = NULL;
7706 off_t off;
7707 if (arg3) {
7708 ret = get_user_s64(off, arg3);
7709 if (is_error(ret)) {
7710 break;
7711 }
7712 offp = &off;
7713 }
7714 ret = get_errno(sendfile(arg1, arg2, offp, arg4));
7715 if (!is_error(ret) && arg3) {
7716 abi_long ret2 = put_user_s64(off, arg3);
7717 if (is_error(ret2)) {
7718 ret = ret2;
7719 }
7720 }
7721 break;
7722 }
7723#endif
7724#else
7725 case TARGET_NR_sendfile:
7726#ifdef TARGET_NR_sendfile64
7727 case TARGET_NR_sendfile64:
7728#endif
7729 goto unimplemented;
7730#endif
7731
7732#ifdef TARGET_NR_getpmsg
7733 case TARGET_NR_getpmsg:
7734 goto unimplemented;
7735#endif
7736#ifdef TARGET_NR_putpmsg
7737 case TARGET_NR_putpmsg:
7738 goto unimplemented;
7739#endif
7740#ifdef TARGET_NR_vfork
7741 case TARGET_NR_vfork:
7742 ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
7743 0, 0, 0, 0));
7744 break;
7745#endif
7746#ifdef TARGET_NR_ugetrlimit
7747 case TARGET_NR_ugetrlimit:
7748 {
7749 struct rlimit rlim;
7750 int resource = target_to_host_resource(arg1);
7751 ret = get_errno(getrlimit(resource, &rlim));
7752 if (!is_error(ret)) {
7753 struct target_rlimit *target_rlim;
7754 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
7755 goto efault;
7756 target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
7757 target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
7758 unlock_user_struct(target_rlim, arg2, 1);
7759 }
7760 break;
7761 }
7762#endif
7763#ifdef TARGET_NR_truncate64
7764 case TARGET_NR_truncate64:
7765 if (!(p = lock_user_string(arg1)))
7766 goto efault;
7767 ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
7768 unlock_user(p, arg1, 0);
7769 break;
7770#endif
7771#ifdef TARGET_NR_ftruncate64
7772 case TARGET_NR_ftruncate64:
7773 ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
7774 break;
7775#endif
7776#ifdef TARGET_NR_stat64
7777 case TARGET_NR_stat64:
7778 if (!(p = lock_user_string(arg1)))
7779 goto efault;
7780 ret = get_errno(stat(path(p), &st));
7781 unlock_user(p, arg1, 0);
7782 if (!is_error(ret))
7783 ret = host_to_target_stat64(cpu_env, arg2, &st);
7784 break;
7785#endif
7786#ifdef TARGET_NR_lstat64
7787 case TARGET_NR_lstat64:
7788 if (!(p = lock_user_string(arg1)))
7789 goto efault;
7790 ret = get_errno(lstat(path(p), &st));
7791 unlock_user(p, arg1, 0);
7792 if (!is_error(ret))
7793 ret = host_to_target_stat64(cpu_env, arg2, &st);
7794 break;
7795#endif
7796#ifdef TARGET_NR_fstat64
7797 case TARGET_NR_fstat64:
7798 ret = get_errno(fstat(arg1, &st));
7799 if (!is_error(ret))
7800 ret = host_to_target_stat64(cpu_env, arg2, &st);
7801 break;
7802#endif
7803#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat))
7804#ifdef TARGET_NR_fstatat64
7805 case TARGET_NR_fstatat64:
7806#endif
7807#ifdef TARGET_NR_newfstatat
7808 case TARGET_NR_newfstatat:
7809#endif
7810 if (!(p = lock_user_string(arg2)))
7811 goto efault;
7812 ret = get_errno(fstatat(arg1, path(p), &st, arg4));
7813 if (!is_error(ret))
7814 ret = host_to_target_stat64(cpu_env, arg3, &st);
7815 break;
7816#endif
7817 case TARGET_NR_lchown:
7818 if (!(p = lock_user_string(arg1)))
7819 goto efault;
7820 ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
7821 unlock_user(p, arg1, 0);
7822 break;
7823#ifdef TARGET_NR_getuid
7824 case TARGET_NR_getuid:
7825 ret = get_errno(high2lowuid(getuid()));
7826 break;
7827#endif
7828#ifdef TARGET_NR_getgid
7829 case TARGET_NR_getgid:
7830 ret = get_errno(high2lowgid(getgid()));
7831 break;
7832#endif
7833#ifdef TARGET_NR_geteuid
7834 case TARGET_NR_geteuid:
7835 ret = get_errno(high2lowuid(geteuid()));
7836 break;
7837#endif
7838#ifdef TARGET_NR_getegid
7839 case TARGET_NR_getegid:
7840 ret = get_errno(high2lowgid(getegid()));
7841 break;
7842#endif
7843 case TARGET_NR_setreuid:
7844 ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
7845 break;
7846 case TARGET_NR_setregid:
7847 ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
7848 break;
7849 case TARGET_NR_getgroups:
7850 {
7851 int gidsetsize = arg1;
7852 target_id *target_grouplist;
7853 gid_t *grouplist;
7854 int i;
7855
7856 grouplist = alloca(gidsetsize * sizeof(gid_t));
7857 ret = get_errno(getgroups(gidsetsize, grouplist));
7858 if (gidsetsize == 0)
7859 break;
7860 if (!is_error(ret)) {
7861 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * sizeof(target_id), 0);
7862 if (!target_grouplist)
7863 goto efault;
7864 for(i = 0;i < ret; i++)
7865 target_grouplist[i] = tswapid(high2lowgid(grouplist[i]));
7866 unlock_user(target_grouplist, arg2, gidsetsize * sizeof(target_id));
7867 }
7868 }
7869 break;
7870 case TARGET_NR_setgroups:
7871 {
7872 int gidsetsize = arg1;
7873 target_id *target_grouplist;
7874 gid_t *grouplist = NULL;
7875 int i;
7876 if (gidsetsize) {
7877 grouplist = alloca(gidsetsize * sizeof(gid_t));
7878 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * sizeof(target_id), 1);
7879 if (!target_grouplist) {
7880 ret = -TARGET_EFAULT;
7881 goto fail;
7882 }
7883 for (i = 0; i < gidsetsize; i++) {
7884 grouplist[i] = low2highgid(tswapid(target_grouplist[i]));
7885 }
7886 unlock_user(target_grouplist, arg2, 0);
7887 }
7888 ret = get_errno(setgroups(gidsetsize, grouplist));
7889 }
7890 break;
7891 case TARGET_NR_fchown:
7892 ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
7893 break;
7894#if defined(TARGET_NR_fchownat)
7895 case TARGET_NR_fchownat:
7896 if (!(p = lock_user_string(arg2)))
7897 goto efault;
7898 ret = get_errno(fchownat(arg1, p, low2highuid(arg3),
7899 low2highgid(arg4), arg5));
7900 unlock_user(p, arg2, 0);
7901 break;
7902#endif
7903#ifdef TARGET_NR_setresuid
7904 case TARGET_NR_setresuid:
7905 ret = get_errno(setresuid(low2highuid(arg1),
7906 low2highuid(arg2),
7907 low2highuid(arg3)));
7908 break;
7909#endif
7910#ifdef TARGET_NR_getresuid
7911 case TARGET_NR_getresuid:
7912 {
7913 uid_t ruid, euid, suid;
7914 ret = get_errno(getresuid(&ruid, &euid, &suid));
7915 if (!is_error(ret)) {
7916 if (put_user_u16(high2lowuid(ruid), arg1)
7917 || put_user_u16(high2lowuid(euid), arg2)
7918 || put_user_u16(high2lowuid(suid), arg3))
7919 goto efault;
7920 }
7921 }
7922 break;
7923#endif
7924#ifdef TARGET_NR_getresgid
7925 case TARGET_NR_setresgid:
7926 ret = get_errno(setresgid(low2highgid(arg1),
7927 low2highgid(arg2),
7928 low2highgid(arg3)));
7929 break;
7930#endif
7931#ifdef TARGET_NR_getresgid
7932 case TARGET_NR_getresgid:
7933 {
7934 gid_t rgid, egid, sgid;
7935 ret = get_errno(getresgid(&rgid, &egid, &sgid));
7936 if (!is_error(ret)) {
7937 if (put_user_u16(high2lowgid(rgid), arg1)
7938 || put_user_u16(high2lowgid(egid), arg2)
7939 || put_user_u16(high2lowgid(sgid), arg3))
7940 goto efault;
7941 }
7942 }
7943 break;
7944#endif
7945 case TARGET_NR_chown:
7946 if (!(p = lock_user_string(arg1)))
7947 goto efault;
7948 ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
7949 unlock_user(p, arg1, 0);
7950 break;
7951 case TARGET_NR_setuid:
7952 ret = get_errno(setuid(low2highuid(arg1)));
7953 break;
7954 case TARGET_NR_setgid:
7955 ret = get_errno(setgid(low2highgid(arg1)));
7956 break;
7957 case TARGET_NR_setfsuid:
7958 ret = get_errno(setfsuid(arg1));
7959 break;
7960 case TARGET_NR_setfsgid:
7961 ret = get_errno(setfsgid(arg1));
7962 break;
7963
7964#ifdef TARGET_NR_lchown32
7965 case TARGET_NR_lchown32:
7966 if (!(p = lock_user_string(arg1)))
7967 goto efault;
7968 ret = get_errno(lchown(p, arg2, arg3));
7969 unlock_user(p, arg1, 0);
7970 break;
7971#endif
7972#ifdef TARGET_NR_getuid32
7973 case TARGET_NR_getuid32:
7974 ret = get_errno(getuid());
7975 break;
7976#endif
7977
7978#if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
7979
7980 case TARGET_NR_getxuid:
7981 {
7982 uid_t euid;
7983 euid=geteuid();
7984 ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
7985 }
7986 ret = get_errno(getuid());
7987 break;
7988#endif
7989#if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
7990
7991 case TARGET_NR_getxgid:
7992 {
7993 uid_t egid;
7994 egid=getegid();
7995 ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
7996 }
7997 ret = get_errno(getgid());
7998 break;
7999#endif
8000#if defined(TARGET_NR_osf_getsysinfo) && defined(TARGET_ALPHA)
8001
8002 case TARGET_NR_osf_getsysinfo:
8003 ret = -TARGET_EOPNOTSUPP;
8004 switch (arg1) {
8005 case TARGET_GSI_IEEE_FP_CONTROL:
8006 {
8007 uint64_t swcr, fpcr = cpu_alpha_load_fpcr (cpu_env);
8008
8009
8010 swcr = (fpcr >> 35) & SWCR_STATUS_MASK;
8011 swcr |= (fpcr >> 36) & SWCR_MAP_DMZ;
8012 swcr |= (~fpcr >> 48) & (SWCR_TRAP_ENABLE_INV
8013 | SWCR_TRAP_ENABLE_DZE
8014 | SWCR_TRAP_ENABLE_OVF);
8015 swcr |= (~fpcr >> 57) & (SWCR_TRAP_ENABLE_UNF
8016 | SWCR_TRAP_ENABLE_INE);
8017 swcr |= (fpcr >> 47) & SWCR_MAP_UMZ;
8018 swcr |= (~fpcr >> 41) & SWCR_TRAP_ENABLE_DNO;
8019
8020 if (put_user_u64 (swcr, arg2))
8021 goto efault;
8022 ret = 0;
8023 }
8024 break;
8025
8026
8027
8028
8029
8030
8031
8032
8033
8034
8035 }
8036 break;
8037#endif
8038#if defined(TARGET_NR_osf_setsysinfo) && defined(TARGET_ALPHA)
8039
8040 case TARGET_NR_osf_setsysinfo:
8041 ret = -TARGET_EOPNOTSUPP;
8042 switch (arg1) {
8043 case TARGET_SSI_IEEE_FP_CONTROL:
8044 {
8045 uint64_t swcr, fpcr, orig_fpcr;
8046
8047 if (get_user_u64 (swcr, arg2)) {
8048 goto efault;
8049 }
8050 orig_fpcr = cpu_alpha_load_fpcr(cpu_env);
8051 fpcr = orig_fpcr & FPCR_DYN_MASK;
8052
8053
8054 fpcr |= (swcr & SWCR_STATUS_MASK) << 35;
8055 fpcr |= (swcr & SWCR_MAP_DMZ) << 36;
8056 fpcr |= (~swcr & (SWCR_TRAP_ENABLE_INV
8057 | SWCR_TRAP_ENABLE_DZE
8058 | SWCR_TRAP_ENABLE_OVF)) << 48;
8059 fpcr |= (~swcr & (SWCR_TRAP_ENABLE_UNF
8060 | SWCR_TRAP_ENABLE_INE)) << 57;
8061 fpcr |= (swcr & SWCR_MAP_UMZ ? FPCR_UNDZ | FPCR_UNFD : 0);
8062 fpcr |= (~swcr & SWCR_TRAP_ENABLE_DNO) << 41;
8063
8064 cpu_alpha_store_fpcr(cpu_env, fpcr);
8065 ret = 0;
8066 }
8067 break;
8068
8069 case TARGET_SSI_IEEE_RAISE_EXCEPTION:
8070 {
8071 uint64_t exc, fpcr, orig_fpcr;
8072 int si_code;
8073
8074 if (get_user_u64(exc, arg2)) {
8075 goto efault;
8076 }
8077
8078 orig_fpcr = cpu_alpha_load_fpcr(cpu_env);
8079
8080
8081 fpcr = orig_fpcr | ((exc & SWCR_STATUS_MASK) << 35);
8082
8083 cpu_alpha_store_fpcr(cpu_env, fpcr);
8084 ret = 0;
8085
8086
8087 fpcr &= ~(orig_fpcr & FPCR_STATUS_MASK);
8088
8089
8090
8091 si_code = 0;
8092 if ((fpcr & (FPCR_INE | FPCR_INED)) == FPCR_INE) {
8093 si_code = TARGET_FPE_FLTRES;
8094 }
8095 if ((fpcr & (FPCR_UNF | FPCR_UNFD)) == FPCR_UNF) {
8096 si_code = TARGET_FPE_FLTUND;
8097 }
8098 if ((fpcr & (FPCR_OVF | FPCR_OVFD)) == FPCR_OVF) {
8099 si_code = TARGET_FPE_FLTOVF;
8100 }
8101 if ((fpcr & (FPCR_DZE | FPCR_DZED)) == FPCR_DZE) {
8102 si_code = TARGET_FPE_FLTDIV;
8103 }
8104 if ((fpcr & (FPCR_INV | FPCR_INVD)) == FPCR_INV) {
8105 si_code = TARGET_FPE_FLTINV;
8106 }
8107 if (si_code != 0) {
8108 target_siginfo_t info;
8109 info.si_signo = SIGFPE;
8110 info.si_errno = 0;
8111 info.si_code = si_code;
8112 info._sifields._sigfault._addr
8113 = ((CPUArchState *)cpu_env)->pc;
8114 queue_signal((CPUArchState *)cpu_env, info.si_signo, &info);
8115 }
8116 }
8117 break;
8118
8119
8120
8121
8122
8123
8124
8125 }
8126 break;
8127#endif
8128#ifdef TARGET_NR_osf_sigprocmask
8129
8130 case TARGET_NR_osf_sigprocmask:
8131 {
8132 abi_ulong mask;
8133 int how;
8134 sigset_t set, oldset;
8135
8136 switch(arg1) {
8137 case TARGET_SIG_BLOCK:
8138 how = SIG_BLOCK;
8139 break;
8140 case TARGET_SIG_UNBLOCK:
8141 how = SIG_UNBLOCK;
8142 break;
8143 case TARGET_SIG_SETMASK:
8144 how = SIG_SETMASK;
8145 break;
8146 default:
8147 ret = -TARGET_EINVAL;
8148 goto fail;
8149 }
8150 mask = arg2;
8151 target_to_host_old_sigset(&set, &mask);
8152 sigprocmask(how, &set, &oldset);
8153 host_to_target_old_sigset(&mask, &oldset);
8154 ret = mask;
8155 }
8156 break;
8157#endif
8158
8159#ifdef TARGET_NR_getgid32
8160 case TARGET_NR_getgid32:
8161 ret = get_errno(getgid());
8162 break;
8163#endif
8164#ifdef TARGET_NR_geteuid32
8165 case TARGET_NR_geteuid32:
8166 ret = get_errno(geteuid());
8167 break;
8168#endif
8169#ifdef TARGET_NR_getegid32
8170 case TARGET_NR_getegid32:
8171 ret = get_errno(getegid());
8172 break;
8173#endif
8174#ifdef TARGET_NR_setreuid32
8175 case TARGET_NR_setreuid32:
8176 ret = get_errno(setreuid(arg1, arg2));
8177 break;
8178#endif
8179#ifdef TARGET_NR_setregid32
8180 case TARGET_NR_setregid32:
8181 ret = get_errno(setregid(arg1, arg2));
8182 break;
8183#endif
8184#ifdef TARGET_NR_getgroups32
8185 case TARGET_NR_getgroups32:
8186 {
8187 int gidsetsize = arg1;
8188 uint32_t *target_grouplist;
8189 gid_t *grouplist;
8190 int i;
8191
8192 grouplist = alloca(gidsetsize * sizeof(gid_t));
8193 ret = get_errno(getgroups(gidsetsize, grouplist));
8194 if (gidsetsize == 0)
8195 break;
8196 if (!is_error(ret)) {
8197 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
8198 if (!target_grouplist) {
8199 ret = -TARGET_EFAULT;
8200 goto fail;
8201 }
8202 for(i = 0;i < ret; i++)
8203 target_grouplist[i] = tswap32(grouplist[i]);
8204 unlock_user(target_grouplist, arg2, gidsetsize * 4);
8205 }
8206 }
8207 break;
8208#endif
8209#ifdef TARGET_NR_setgroups32
8210 case TARGET_NR_setgroups32:
8211 {
8212 int gidsetsize = arg1;
8213 uint32_t *target_grouplist;
8214 gid_t *grouplist;
8215 int i;
8216
8217 grouplist = alloca(gidsetsize * sizeof(gid_t));
8218 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
8219 if (!target_grouplist) {
8220 ret = -TARGET_EFAULT;
8221 goto fail;
8222 }
8223 for(i = 0;i < gidsetsize; i++)
8224 grouplist[i] = tswap32(target_grouplist[i]);
8225 unlock_user(target_grouplist, arg2, 0);
8226 ret = get_errno(setgroups(gidsetsize, grouplist));
8227 }
8228 break;
8229#endif
8230#ifdef TARGET_NR_fchown32
8231 case TARGET_NR_fchown32:
8232 ret = get_errno(fchown(arg1, arg2, arg3));
8233 break;
8234#endif
8235#ifdef TARGET_NR_setresuid32
8236 case TARGET_NR_setresuid32:
8237 ret = get_errno(setresuid(arg1, arg2, arg3));
8238 break;
8239#endif
8240#ifdef TARGET_NR_getresuid32
8241 case TARGET_NR_getresuid32:
8242 {
8243 uid_t ruid, euid, suid;
8244 ret = get_errno(getresuid(&ruid, &euid, &suid));
8245 if (!is_error(ret)) {
8246 if (put_user_u32(ruid, arg1)
8247 || put_user_u32(euid, arg2)
8248 || put_user_u32(suid, arg3))
8249 goto efault;
8250 }
8251 }
8252 break;
8253#endif
8254#ifdef TARGET_NR_setresgid32
8255 case TARGET_NR_setresgid32:
8256 ret = get_errno(setresgid(arg1, arg2, arg3));
8257 break;
8258#endif
8259#ifdef TARGET_NR_getresgid32
8260 case TARGET_NR_getresgid32:
8261 {
8262 gid_t rgid, egid, sgid;
8263 ret = get_errno(getresgid(&rgid, &egid, &sgid));
8264 if (!is_error(ret)) {
8265 if (put_user_u32(rgid, arg1)
8266 || put_user_u32(egid, arg2)
8267 || put_user_u32(sgid, arg3))
8268 goto efault;
8269 }
8270 }
8271 break;
8272#endif
8273#ifdef TARGET_NR_chown32
8274 case TARGET_NR_chown32:
8275 if (!(p = lock_user_string(arg1)))
8276 goto efault;
8277 ret = get_errno(chown(p, arg2, arg3));
8278 unlock_user(p, arg1, 0);
8279 break;
8280#endif
8281#ifdef TARGET_NR_setuid32
8282 case TARGET_NR_setuid32:
8283 ret = get_errno(setuid(arg1));
8284 break;
8285#endif
8286#ifdef TARGET_NR_setgid32
8287 case TARGET_NR_setgid32:
8288 ret = get_errno(setgid(arg1));
8289 break;
8290#endif
8291#ifdef TARGET_NR_setfsuid32
8292 case TARGET_NR_setfsuid32:
8293 ret = get_errno(setfsuid(arg1));
8294 break;
8295#endif
8296#ifdef TARGET_NR_setfsgid32
8297 case TARGET_NR_setfsgid32:
8298 ret = get_errno(setfsgid(arg1));
8299 break;
8300#endif
8301
8302 case TARGET_NR_pivot_root:
8303 goto unimplemented;
8304#ifdef TARGET_NR_mincore
8305 case TARGET_NR_mincore:
8306 {
8307 void *a;
8308 ret = -TARGET_EFAULT;
8309 if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
8310 goto efault;
8311 if (!(p = lock_user_string(arg3)))
8312 goto mincore_fail;
8313 ret = get_errno(mincore(a, arg2, p));
8314 unlock_user(p, arg3, ret);
8315 mincore_fail:
8316 unlock_user(a, arg1, 0);
8317 }
8318 break;
8319#endif
8320#ifdef TARGET_NR_arm_fadvise64_64
8321 case TARGET_NR_arm_fadvise64_64:
8322 {
8323
8324
8325
8326
8327 abi_long temp;
8328 temp = arg3;
8329 arg3 = arg4;
8330 arg4 = temp;
8331 }
8332#endif
8333#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64) || defined(TARGET_NR_fadvise64)
8334#ifdef TARGET_NR_fadvise64_64
8335 case TARGET_NR_fadvise64_64:
8336#endif
8337#ifdef TARGET_NR_fadvise64
8338 case TARGET_NR_fadvise64:
8339#endif
8340#ifdef TARGET_S390X
8341 switch (arg4) {
8342 case 4: arg4 = POSIX_FADV_NOREUSE + 1; break;
8343 case 5: arg4 = POSIX_FADV_NOREUSE + 2; break;
8344 case 6: arg4 = POSIX_FADV_DONTNEED; break;
8345 case 7: arg4 = POSIX_FADV_NOREUSE; break;
8346 default: break;
8347 }
8348#endif
8349 ret = -posix_fadvise(arg1, arg2, arg3, arg4);
8350 break;
8351#endif
8352#ifdef TARGET_NR_madvise
8353 case TARGET_NR_madvise:
8354
8355
8356
8357
8358 ret = get_errno(0);
8359 break;
8360#endif
8361#if TARGET_ABI_BITS == 32
8362 case TARGET_NR_fcntl64:
8363 {
8364 int cmd;
8365 struct flock64 fl;
8366 struct target_flock64 *target_fl;
8367#ifdef TARGET_ARM
8368 struct target_eabi_flock64 *target_efl;
8369#endif
8370
8371 cmd = target_to_host_fcntl_cmd(arg2);
8372 if (cmd == -TARGET_EINVAL) {
8373 ret = cmd;
8374 break;
8375 }
8376
8377 switch(arg2) {
8378 case TARGET_F_GETLK64:
8379#ifdef TARGET_ARM
8380 if (((CPUARMState *)cpu_env)->eabi) {
8381 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1))
8382 goto efault;
8383 fl.l_type = tswap16(target_efl->l_type);
8384 fl.l_whence = tswap16(target_efl->l_whence);
8385 fl.l_start = tswap64(target_efl->l_start);
8386 fl.l_len = tswap64(target_efl->l_len);
8387 fl.l_pid = tswap32(target_efl->l_pid);
8388 unlock_user_struct(target_efl, arg3, 0);
8389 } else
8390#endif
8391 {
8392 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1))
8393 goto efault;
8394 fl.l_type = tswap16(target_fl->l_type);
8395 fl.l_whence = tswap16(target_fl->l_whence);
8396 fl.l_start = tswap64(target_fl->l_start);
8397 fl.l_len = tswap64(target_fl->l_len);
8398 fl.l_pid = tswap32(target_fl->l_pid);
8399 unlock_user_struct(target_fl, arg3, 0);
8400 }
8401 ret = get_errno(fcntl(arg1, cmd, &fl));
8402 if (ret == 0) {
8403#ifdef TARGET_ARM
8404 if (((CPUARMState *)cpu_env)->eabi) {
8405 if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0))
8406 goto efault;
8407 target_efl->l_type = tswap16(fl.l_type);
8408 target_efl->l_whence = tswap16(fl.l_whence);
8409 target_efl->l_start = tswap64(fl.l_start);
8410 target_efl->l_len = tswap64(fl.l_len);
8411 target_efl->l_pid = tswap32(fl.l_pid);
8412 unlock_user_struct(target_efl, arg3, 1);
8413 } else
8414#endif
8415 {
8416 if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0))
8417 goto efault;
8418 target_fl->l_type = tswap16(fl.l_type);
8419 target_fl->l_whence = tswap16(fl.l_whence);
8420 target_fl->l_start = tswap64(fl.l_start);
8421 target_fl->l_len = tswap64(fl.l_len);
8422 target_fl->l_pid = tswap32(fl.l_pid);
8423 unlock_user_struct(target_fl, arg3, 1);
8424 }
8425 }
8426 break;
8427
8428 case TARGET_F_SETLK64:
8429 case TARGET_F_SETLKW64:
8430#ifdef TARGET_ARM
8431 if (((CPUARMState *)cpu_env)->eabi) {
8432 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1))
8433 goto efault;
8434 fl.l_type = tswap16(target_efl->l_type);
8435 fl.l_whence = tswap16(target_efl->l_whence);
8436 fl.l_start = tswap64(target_efl->l_start);
8437 fl.l_len = tswap64(target_efl->l_len);
8438 fl.l_pid = tswap32(target_efl->l_pid);
8439 unlock_user_struct(target_efl, arg3, 0);
8440 } else
8441#endif
8442 {
8443 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1))
8444 goto efault;
8445 fl.l_type = tswap16(target_fl->l_type);
8446 fl.l_whence = tswap16(target_fl->l_whence);
8447 fl.l_start = tswap64(target_fl->l_start);
8448 fl.l_len = tswap64(target_fl->l_len);
8449 fl.l_pid = tswap32(target_fl->l_pid);
8450 unlock_user_struct(target_fl, arg3, 0);
8451 }
8452 ret = get_errno(fcntl(arg1, cmd, &fl));
8453 break;
8454 default:
8455 ret = do_fcntl(arg1, arg2, arg3);
8456 break;
8457 }
8458 break;
8459 }
8460#endif
8461#ifdef TARGET_NR_cacheflush
8462 case TARGET_NR_cacheflush:
8463
8464 ret = 0;
8465 break;
8466#endif
8467#ifdef TARGET_NR_security
8468 case TARGET_NR_security:
8469 goto unimplemented;
8470#endif
8471#ifdef TARGET_NR_getpagesize
8472 case TARGET_NR_getpagesize:
8473 ret = TARGET_PAGE_SIZE;
8474 break;
8475#endif
8476 case TARGET_NR_gettid:
8477 ret = get_errno(gettid());
8478 break;
8479#ifdef TARGET_NR_readahead
8480 case TARGET_NR_readahead:
8481#if TARGET_ABI_BITS == 32
8482 if (regpairs_aligned(cpu_env)) {
8483 arg2 = arg3;
8484 arg3 = arg4;
8485 arg4 = arg5;
8486 }
8487 ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
8488#else
8489 ret = get_errno(readahead(arg1, arg2, arg3));
8490#endif
8491 break;
8492#endif
8493#ifdef CONFIG_ATTR
8494#ifdef TARGET_NR_setxattr
8495 case TARGET_NR_listxattr:
8496 case TARGET_NR_llistxattr:
8497 {
8498 void *p, *b = 0;
8499 if (arg2) {
8500 b = lock_user(VERIFY_WRITE, arg2, arg3, 0);
8501 if (!b) {
8502 ret = -TARGET_EFAULT;
8503 break;
8504 }
8505 }
8506 p = lock_user_string(arg1);
8507 if (p) {
8508 if (num == TARGET_NR_listxattr) {
8509 ret = get_errno(listxattr(p, b, arg3));
8510 } else {
8511 ret = get_errno(llistxattr(p, b, arg3));
8512 }
8513 } else {
8514 ret = -TARGET_EFAULT;
8515 }
8516 unlock_user(p, arg1, 0);
8517 unlock_user(b, arg2, arg3);
8518 break;
8519 }
8520 case TARGET_NR_flistxattr:
8521 {
8522 void *b = 0;
8523 if (arg2) {
8524 b = lock_user(VERIFY_WRITE, arg2, arg3, 0);
8525 if (!b) {
8526 ret = -TARGET_EFAULT;
8527 break;
8528 }
8529 }
8530 ret = get_errno(flistxattr(arg1, b, arg3));
8531 unlock_user(b, arg2, arg3);
8532 break;
8533 }
8534 case TARGET_NR_setxattr:
8535 case TARGET_NR_lsetxattr:
8536 {
8537 void *p, *n, *v = 0;
8538 if (arg3) {
8539 v = lock_user(VERIFY_READ, arg3, arg4, 1);
8540 if (!v) {
8541 ret = -TARGET_EFAULT;
8542 break;
8543 }
8544 }
8545 p = lock_user_string(arg1);
8546 n = lock_user_string(arg2);
8547 if (p && n) {
8548 if (num == TARGET_NR_setxattr) {
8549 ret = get_errno(setxattr(p, n, v, arg4, arg5));
8550 } else {
8551 ret = get_errno(lsetxattr(p, n, v, arg4, arg5));
8552 }
8553 } else {
8554 ret = -TARGET_EFAULT;
8555 }
8556 unlock_user(p, arg1, 0);
8557 unlock_user(n, arg2, 0);
8558 unlock_user(v, arg3, 0);
8559 }
8560 break;
8561 case TARGET_NR_fsetxattr:
8562 {
8563 void *n, *v = 0;
8564 if (arg3) {
8565 v = lock_user(VERIFY_READ, arg3, arg4, 1);
8566 if (!v) {
8567 ret = -TARGET_EFAULT;
8568 break;
8569 }
8570 }
8571 n = lock_user_string(arg2);
8572 if (n) {
8573 ret = get_errno(fsetxattr(arg1, n, v, arg4, arg5));
8574 } else {
8575 ret = -TARGET_EFAULT;
8576 }
8577 unlock_user(n, arg2, 0);
8578 unlock_user(v, arg3, 0);
8579 }
8580 break;
8581 case TARGET_NR_getxattr:
8582 case TARGET_NR_lgetxattr:
8583 {
8584 void *p, *n, *v = 0;
8585 if (arg3) {
8586 v = lock_user(VERIFY_WRITE, arg3, arg4, 0);
8587 if (!v) {
8588 ret = -TARGET_EFAULT;
8589 break;
8590 }
8591 }
8592 p = lock_user_string(arg1);
8593 n = lock_user_string(arg2);
8594 if (p && n) {
8595 if (num == TARGET_NR_getxattr) {
8596 ret = get_errno(getxattr(p, n, v, arg4));
8597 } else {
8598 ret = get_errno(lgetxattr(p, n, v, arg4));
8599 }
8600 } else {
8601 ret = -TARGET_EFAULT;
8602 }
8603 unlock_user(p, arg1, 0);
8604 unlock_user(n, arg2, 0);
8605 unlock_user(v, arg3, arg4);
8606 }
8607 break;
8608 case TARGET_NR_fgetxattr:
8609 {
8610 void *n, *v = 0;
8611 if (arg3) {
8612 v = lock_user(VERIFY_WRITE, arg3, arg4, 0);
8613 if (!v) {
8614 ret = -TARGET_EFAULT;
8615 break;
8616 }
8617 }
8618 n = lock_user_string(arg2);
8619 if (n) {
8620 ret = get_errno(fgetxattr(arg1, n, v, arg4));
8621 } else {
8622 ret = -TARGET_EFAULT;
8623 }
8624 unlock_user(n, arg2, 0);
8625 unlock_user(v, arg3, arg4);
8626 }
8627 break;
8628 case TARGET_NR_removexattr:
8629 case TARGET_NR_lremovexattr:
8630 {
8631 void *p, *n;
8632 p = lock_user_string(arg1);
8633 n = lock_user_string(arg2);
8634 if (p && n) {
8635 if (num == TARGET_NR_removexattr) {
8636 ret = get_errno(removexattr(p, n));
8637 } else {
8638 ret = get_errno(lremovexattr(p, n));
8639 }
8640 } else {
8641 ret = -TARGET_EFAULT;
8642 }
8643 unlock_user(p, arg1, 0);
8644 unlock_user(n, arg2, 0);
8645 }
8646 break;
8647 case TARGET_NR_fremovexattr:
8648 {
8649 void *n;
8650 n = lock_user_string(arg2);
8651 if (n) {
8652 ret = get_errno(fremovexattr(arg1, n));
8653 } else {
8654 ret = -TARGET_EFAULT;
8655 }
8656 unlock_user(n, arg2, 0);
8657 }
8658 break;
8659#endif
8660#endif
8661#ifdef TARGET_NR_set_thread_area
8662 case TARGET_NR_set_thread_area:
8663#if defined(TARGET_MIPS)
8664 ((CPUMIPSState *) cpu_env)->tls_value = arg1;
8665 ret = 0;
8666 break;
8667#elif defined(TARGET_CRIS)
8668 if (arg1 & 0xff)
8669 ret = -TARGET_EINVAL;
8670 else {
8671 ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
8672 ret = 0;
8673 }
8674 break;
8675#elif defined(TARGET_I386) && defined(TARGET_ABI32)
8676 ret = do_set_thread_area(cpu_env, arg1);
8677 break;
8678#elif defined(TARGET_M68K)
8679 {
8680 TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
8681 ts->tp_value = arg1;
8682 ret = 0;
8683 break;
8684 }
8685#else
8686 goto unimplemented_nowarn;
8687#endif
8688#endif
8689#ifdef TARGET_NR_get_thread_area
8690 case TARGET_NR_get_thread_area:
8691#if defined(TARGET_I386) && defined(TARGET_ABI32)
8692 ret = do_get_thread_area(cpu_env, arg1);
8693 break;
8694#elif defined(TARGET_M68K)
8695 {
8696 TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
8697 ret = ts->tp_value;
8698 break;
8699 }
8700#else
8701 goto unimplemented_nowarn;
8702#endif
8703#endif
8704#ifdef TARGET_NR_getdomainname
8705 case TARGET_NR_getdomainname:
8706 goto unimplemented_nowarn;
8707#endif
8708
8709#ifdef TARGET_NR_clock_gettime
8710 case TARGET_NR_clock_gettime:
8711 {
8712 struct timespec ts;
8713 ret = get_errno(clock_gettime(arg1, &ts));
8714 if (!is_error(ret)) {
8715 host_to_target_timespec(arg2, &ts);
8716 }
8717 break;
8718 }
8719#endif
8720#ifdef TARGET_NR_clock_getres
8721 case TARGET_NR_clock_getres:
8722 {
8723 struct timespec ts;
8724 ret = get_errno(clock_getres(arg1, &ts));
8725 if (!is_error(ret)) {
8726 host_to_target_timespec(arg2, &ts);
8727 }
8728 break;
8729 }
8730#endif
8731#ifdef TARGET_NR_clock_nanosleep
8732 case TARGET_NR_clock_nanosleep:
8733 {
8734 struct timespec ts;
8735 target_to_host_timespec(&ts, arg3);
8736 ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
8737 if (arg4)
8738 host_to_target_timespec(arg4, &ts);
8739 break;
8740 }
8741#endif
8742
8743#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
8744 case TARGET_NR_set_tid_address:
8745 ret = get_errno(set_tid_address((int *)g2h(arg1)));
8746 break;
8747#endif
8748
8749#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
8750 case TARGET_NR_tkill:
8751 ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
8752 break;
8753#endif
8754
8755#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
8756 case TARGET_NR_tgkill:
8757 ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
8758 target_to_host_signal(arg3)));
8759 break;
8760#endif
8761
8762#ifdef TARGET_NR_set_robust_list
8763 case TARGET_NR_set_robust_list:
8764 case TARGET_NR_get_robust_list:
8765
8766
8767
8768
8769
8770
8771
8772
8773
8774
8775
8776
8777 goto unimplemented_nowarn;
8778#endif
8779
8780#if defined(TARGET_NR_utimensat)
8781 case TARGET_NR_utimensat:
8782 {
8783 struct timespec *tsp, ts[2];
8784 if (!arg3) {
8785 tsp = NULL;
8786 } else {
8787 target_to_host_timespec(ts, arg3);
8788 target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
8789 tsp = ts;
8790 }
8791 if (!arg2)
8792 ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4));
8793 else {
8794 if (!(p = lock_user_string(arg2))) {
8795 ret = -TARGET_EFAULT;
8796 goto fail;
8797 }
8798 ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4));
8799 unlock_user(p, arg2, 0);
8800 }
8801 }
8802 break;
8803#endif
8804 case TARGET_NR_futex:
8805 ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
8806 break;
8807#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
8808 case TARGET_NR_inotify_init:
8809 ret = get_errno(sys_inotify_init());
8810 break;
8811#endif
8812#ifdef CONFIG_INOTIFY1
8813#if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
8814 case TARGET_NR_inotify_init1:
8815 ret = get_errno(sys_inotify_init1(arg1));
8816 break;
8817#endif
8818#endif
8819#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
8820 case TARGET_NR_inotify_add_watch:
8821 p = lock_user_string(arg2);
8822 ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
8823 unlock_user(p, arg2, 0);
8824 break;
8825#endif
8826#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
8827 case TARGET_NR_inotify_rm_watch:
8828 ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
8829 break;
8830#endif
8831
8832#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
8833 case TARGET_NR_mq_open:
8834 {
8835 struct mq_attr posix_mq_attr;
8836
8837 p = lock_user_string(arg1 - 1);
8838 if (arg4 != 0)
8839 copy_from_user_mq_attr (&posix_mq_attr, arg4);
8840 ret = get_errno(mq_open(p, arg2, arg3, &posix_mq_attr));
8841 unlock_user (p, arg1, 0);
8842 }
8843 break;
8844
8845 case TARGET_NR_mq_unlink:
8846 p = lock_user_string(arg1 - 1);
8847 ret = get_errno(mq_unlink(p));
8848 unlock_user (p, arg1, 0);
8849 break;
8850
8851 case TARGET_NR_mq_timedsend:
8852 {
8853 struct timespec ts;
8854
8855 p = lock_user (VERIFY_READ, arg2, arg3, 1);
8856 if (arg5 != 0) {
8857 target_to_host_timespec(&ts, arg5);
8858 ret = get_errno(mq_timedsend(arg1, p, arg3, arg4, &ts));
8859 host_to_target_timespec(arg5, &ts);
8860 }
8861 else
8862 ret = get_errno(mq_send(arg1, p, arg3, arg4));
8863 unlock_user (p, arg2, arg3);
8864 }
8865 break;
8866
8867 case TARGET_NR_mq_timedreceive:
8868 {
8869 struct timespec ts;
8870 unsigned int prio;
8871
8872 p = lock_user (VERIFY_READ, arg2, arg3, 1);
8873 if (arg5 != 0) {
8874 target_to_host_timespec(&ts, arg5);
8875 ret = get_errno(mq_timedreceive(arg1, p, arg3, &prio, &ts));
8876 host_to_target_timespec(arg5, &ts);
8877 }
8878 else
8879 ret = get_errno(mq_receive(arg1, p, arg3, &prio));
8880 unlock_user (p, arg2, arg3);
8881 if (arg4 != 0)
8882 put_user_u32(prio, arg4);
8883 }
8884 break;
8885
8886
8887
8888
8889
8890 case TARGET_NR_mq_getsetattr:
8891 {
8892 struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
8893 ret = 0;
8894 if (arg3 != 0) {
8895 ret = mq_getattr(arg1, &posix_mq_attr_out);
8896 copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
8897 }
8898 if (arg2 != 0) {
8899 copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
8900 ret |= mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_attr_out);
8901 }
8902
8903 }
8904 break;
8905#endif
8906
8907#ifdef CONFIG_SPLICE
8908#ifdef TARGET_NR_tee
8909 case TARGET_NR_tee:
8910 {
8911 ret = get_errno(tee(arg1,arg2,arg3,arg4));
8912 }
8913 break;
8914#endif
8915#ifdef TARGET_NR_splice
8916 case TARGET_NR_splice:
8917 {
8918 loff_t loff_in, loff_out;
8919 loff_t *ploff_in = NULL, *ploff_out = NULL;
8920 if(arg2) {
8921 get_user_u64(loff_in, arg2);
8922 ploff_in = &loff_in;
8923 }
8924 if(arg4) {
8925 get_user_u64(loff_out, arg2);
8926 ploff_out = &loff_out;
8927 }
8928 ret = get_errno(splice(arg1, ploff_in, arg3, ploff_out, arg5, arg6));
8929 }
8930 break;
8931#endif
8932#ifdef TARGET_NR_vmsplice
8933 case TARGET_NR_vmsplice:
8934 {
8935 struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
8936 if (vec != NULL) {
8937 ret = get_errno(vmsplice(arg1, vec, arg3, arg4));
8938 unlock_iovec(vec, arg2, arg3, 0);
8939 } else {
8940 ret = -host_to_target_errno(errno);
8941 }
8942 }
8943 break;
8944#endif
8945#endif
8946#ifdef CONFIG_EVENTFD
8947#if defined(TARGET_NR_eventfd)
8948 case TARGET_NR_eventfd:
8949 ret = get_errno(eventfd(arg1, 0));
8950 break;
8951#endif
8952#if defined(TARGET_NR_eventfd2)
8953 case TARGET_NR_eventfd2:
8954 {
8955 int host_flags = arg2 & (~(TARGET_O_NONBLOCK | TARGET_O_CLOEXEC));
8956 if (arg2 & TARGET_O_NONBLOCK) {
8957 host_flags |= O_NONBLOCK;
8958 }
8959 if (arg2 & TARGET_O_CLOEXEC) {
8960 host_flags |= O_CLOEXEC;
8961 }
8962 ret = get_errno(eventfd(arg1, host_flags));
8963 break;
8964 }
8965#endif
8966#endif
8967#if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate)
8968 case TARGET_NR_fallocate:
8969#if TARGET_ABI_BITS == 32
8970 ret = get_errno(fallocate(arg1, arg2, target_offset64(arg3, arg4),
8971 target_offset64(arg5, arg6)));
8972#else
8973 ret = get_errno(fallocate(arg1, arg2, arg3, arg4));
8974#endif
8975 break;
8976#endif
8977#if defined(CONFIG_SYNC_FILE_RANGE)
8978#if defined(TARGET_NR_sync_file_range)
8979 case TARGET_NR_sync_file_range:
8980#if TARGET_ABI_BITS == 32
8981#if defined(TARGET_MIPS)
8982 ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
8983 target_offset64(arg5, arg6), arg7));
8984#else
8985 ret = get_errno(sync_file_range(arg1, target_offset64(arg2, arg3),
8986 target_offset64(arg4, arg5), arg6));
8987#endif
8988#else
8989 ret = get_errno(sync_file_range(arg1, arg2, arg3, arg4));
8990#endif
8991 break;
8992#endif
8993#if defined(TARGET_NR_sync_file_range2)
8994 case TARGET_NR_sync_file_range2:
8995
8996#if TARGET_ABI_BITS == 32
8997 ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
8998 target_offset64(arg5, arg6), arg2));
8999#else
9000 ret = get_errno(sync_file_range(arg1, arg3, arg4, arg2));
9001#endif
9002 break;
9003#endif
9004#endif
9005#if defined(CONFIG_EPOLL)
9006#if defined(TARGET_NR_epoll_create)
9007 case TARGET_NR_epoll_create:
9008 ret = get_errno(epoll_create(arg1));
9009 break;
9010#endif
9011#if defined(TARGET_NR_epoll_create1) && defined(CONFIG_EPOLL_CREATE1)
9012 case TARGET_NR_epoll_create1:
9013 ret = get_errno(epoll_create1(arg1));
9014 break;
9015#endif
9016#if defined(TARGET_NR_epoll_ctl)
9017 case TARGET_NR_epoll_ctl:
9018 {
9019 struct epoll_event ep;
9020 struct epoll_event *epp = 0;
9021 if (arg4) {
9022 struct target_epoll_event *target_ep;
9023 if (!lock_user_struct(VERIFY_READ, target_ep, arg4, 1)) {
9024 goto efault;
9025 }
9026 ep.events = tswap32(target_ep->events);
9027
9028
9029
9030
9031 ep.data.u64 = tswap64(target_ep->data.u64);
9032 unlock_user_struct(target_ep, arg4, 0);
9033 epp = &ep;
9034 }
9035 ret = get_errno(epoll_ctl(arg1, arg2, arg3, epp));
9036 break;
9037 }
9038#endif
9039
9040#if defined(TARGET_NR_epoll_pwait) && defined(CONFIG_EPOLL_PWAIT)
9041#define IMPLEMENT_EPOLL_PWAIT
9042#endif
9043#if defined(TARGET_NR_epoll_wait) || defined(IMPLEMENT_EPOLL_PWAIT)
9044#if defined(TARGET_NR_epoll_wait)
9045 case TARGET_NR_epoll_wait:
9046#endif
9047#if defined(IMPLEMENT_EPOLL_PWAIT)
9048 case TARGET_NR_epoll_pwait:
9049#endif
9050 {
9051 struct target_epoll_event *target_ep;
9052 struct epoll_event *ep;
9053 int epfd = arg1;
9054 int maxevents = arg3;
9055 int timeout = arg4;
9056
9057 target_ep = lock_user(VERIFY_WRITE, arg2,
9058 maxevents * sizeof(struct target_epoll_event), 1);
9059 if (!target_ep) {
9060 goto efault;
9061 }
9062
9063 ep = alloca(maxevents * sizeof(struct epoll_event));
9064
9065 switch (num) {
9066#if defined(IMPLEMENT_EPOLL_PWAIT)
9067 case TARGET_NR_epoll_pwait:
9068 {
9069 target_sigset_t *target_set;
9070 sigset_t _set, *set = &_set;
9071
9072 if (arg5) {
9073 target_set = lock_user(VERIFY_READ, arg5,
9074 sizeof(target_sigset_t), 1);
9075 if (!target_set) {
9076 unlock_user(target_ep, arg2, 0);
9077 goto efault;
9078 }
9079 target_to_host_sigset(set, target_set);
9080 unlock_user(target_set, arg5, 0);
9081 } else {
9082 set = NULL;
9083 }
9084
9085 ret = get_errno(epoll_pwait(epfd, ep, maxevents, timeout, set));
9086 break;
9087 }
9088#endif
9089#if defined(TARGET_NR_epoll_wait)
9090 case TARGET_NR_epoll_wait:
9091 ret = get_errno(epoll_wait(epfd, ep, maxevents, timeout));
9092 break;
9093#endif
9094 default:
9095 ret = -TARGET_ENOSYS;
9096 }
9097 if (!is_error(ret)) {
9098 int i;
9099 for (i = 0; i < ret; i++) {
9100 target_ep[i].events = tswap32(ep[i].events);
9101 target_ep[i].data.u64 = tswap64(ep[i].data.u64);
9102 }
9103 }
9104 unlock_user(target_ep, arg2, ret * sizeof(struct target_epoll_event));
9105 break;
9106 }
9107#endif
9108#endif
9109#ifdef TARGET_NR_prlimit64
9110 case TARGET_NR_prlimit64:
9111 {
9112
9113 struct target_rlimit64 *target_rnew, *target_rold;
9114 struct host_rlimit64 rnew, rold, *rnewp = 0;
9115 if (arg3) {
9116 if (!lock_user_struct(VERIFY_READ, target_rnew, arg3, 1)) {
9117 goto efault;
9118 }
9119 rnew.rlim_cur = tswap64(target_rnew->rlim_cur);
9120 rnew.rlim_max = tswap64(target_rnew->rlim_max);
9121 unlock_user_struct(target_rnew, arg3, 0);
9122 rnewp = &rnew;
9123 }
9124
9125 ret = get_errno(sys_prlimit64(arg1, arg2, rnewp, arg4 ? &rold : 0));
9126 if (!is_error(ret) && arg4) {
9127 if (!lock_user_struct(VERIFY_WRITE, target_rold, arg4, 1)) {
9128 goto efault;
9129 }
9130 target_rold->rlim_cur = tswap64(rold.rlim_cur);
9131 target_rold->rlim_max = tswap64(rold.rlim_max);
9132 unlock_user_struct(target_rold, arg4, 1);
9133 }
9134 break;
9135 }
9136#endif
9137#ifdef TARGET_NR_gethostname
9138 case TARGET_NR_gethostname:
9139 {
9140 char *name = lock_user(VERIFY_WRITE, arg1, arg2, 0);
9141 if (name) {
9142 ret = get_errno(gethostname(name, arg2));
9143 unlock_user(name, arg1, arg2);
9144 } else {
9145 ret = -TARGET_EFAULT;
9146 }
9147 break;
9148 }
9149#endif
9150#ifdef TARGET_NR_atomic_cmpxchg_32
9151 case TARGET_NR_atomic_cmpxchg_32:
9152 {
9153
9154 abi_ulong mem_value;
9155 if (get_user_u32(mem_value, arg6)) {
9156 target_siginfo_t info;
9157 info.si_signo = SIGSEGV;
9158 info.si_errno = 0;
9159 info.si_code = TARGET_SEGV_MAPERR;
9160 info._sifields._sigfault._addr = arg6;
9161 queue_signal((CPUArchState *)cpu_env, info.si_signo, &info);
9162 ret = 0xdeadbeef;
9163
9164 }
9165 if (mem_value == arg2)
9166 put_user_u32(arg1, arg6);
9167 ret = mem_value;
9168 break;
9169 }
9170#endif
9171#ifdef TARGET_NR_atomic_barrier
9172 case TARGET_NR_atomic_barrier:
9173 {
9174
9175 break;
9176 }
9177#endif
9178 default:
9179 unimplemented:
9180 gemu_log("qemu: Unsupported syscall: %d\n", num);
9181#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
9182 unimplemented_nowarn:
9183#endif
9184 ret = -TARGET_ENOSYS;
9185 break;
9186 }
9187fail:
9188#ifdef DEBUG
9189 gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
9190#endif
9191 if(do_strace)
9192 print_syscall_ret(num, ret);
9193 return ret;
9194efault:
9195 ret = -TARGET_EFAULT;
9196 goto fail;
9197}
9198