4 * Copyright (c) 2003 Fabrice Bellard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
32 #include <sys/types.h>
38 #include <sys/mount.h>
39 #include <sys/prctl.h>
40 #include <sys/resource.h>
45 #include <sys/socket.h>
48 #include <sys/times.h>
51 #include <sys/statfs.h>
53 #include <sys/sysinfo.h>
54 //#include <sys/user.h>
55 #include <netinet/ip.h>
56 #include <netinet/tcp.h>
57 #include <qemu-common.h>
62 #define termios host_termios
63 #define winsize host_winsize
64 #define termio host_termio
65 #define sgttyb host_sgttyb /* same as target */
66 #define tchars host_tchars /* same as target */
67 #define ltchars host_ltchars /* same as target */
69 #include <linux/termios.h>
70 #include <linux/unistd.h>
71 #include <linux/utsname.h>
72 #include <linux/cdrom.h>
73 #include <linux/hdreg.h>
74 #include <linux/soundcard.h>
76 #include <linux/mtio.h>
77 #include "linux_loop.h"
80 #include "qemu-common.h"
83 #include <linux/futex.h>
84 #define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
85 CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
87 /* XXX: Hardcode the above values. */
88 #define CLONE_NPTL_FLAGS2 0
93 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \
94 || defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS)
95 /* 16 bit uid wrappers emulation */
99 //#include <linux/msdos_fs.h>
100 #define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct linux_dirent [2])
101 #define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct linux_dirent [2])
112 #define _syscall0(type,name) \
113 static type name (void) \
115 return syscall(__NR_##name); \
118 #define _syscall1(type,name,type1,arg1) \
119 static type name (type1 arg1) \
121 return syscall(__NR_##name, arg1); \
124 #define _syscall2(type,name,type1,arg1,type2,arg2) \
125 static type name (type1 arg1,type2 arg2) \
127 return syscall(__NR_##name, arg1, arg2); \
130 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
131 static type name (type1 arg1,type2 arg2,type3 arg3) \
133 return syscall(__NR_##name, arg1, arg2, arg3); \
136 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
137 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4) \
139 return syscall(__NR_##name, arg1, arg2, arg3, arg4); \
142 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
144 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
146 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5); \
150 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
151 type5,arg5,type6,arg6) \
152 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \
155 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6); \
159 #define __NR_sys_uname __NR_uname
160 #define __NR_sys_faccessat __NR_faccessat
161 #define __NR_sys_fchmodat __NR_fchmodat
162 #define __NR_sys_fchownat __NR_fchownat
163 #define __NR_sys_fstatat64 __NR_fstatat64
164 #define __NR_sys_futimesat __NR_futimesat
165 #define __NR_sys_getcwd1 __NR_getcwd
166 #define __NR_sys_getdents __NR_getdents
167 #define __NR_sys_getdents64 __NR_getdents64
168 #define __NR_sys_getpriority __NR_getpriority
169 #define __NR_sys_linkat __NR_linkat
170 #define __NR_sys_mkdirat __NR_mkdirat
171 #define __NR_sys_mknodat __NR_mknodat
172 #define __NR_sys_newfstatat __NR_newfstatat
173 #define __NR_sys_openat __NR_openat
174 #define __NR_sys_readlinkat __NR_readlinkat
175 #define __NR_sys_renameat __NR_renameat
176 #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
177 #define __NR_sys_symlinkat __NR_symlinkat
178 #define __NR_sys_syslog __NR_syslog
179 #define __NR_sys_tgkill __NR_tgkill
180 #define __NR_sys_tkill __NR_tkill
181 #define __NR_sys_unlinkat __NR_unlinkat
182 #define __NR_sys_utimensat __NR_utimensat
183 #define __NR_sys_futex __NR_futex
184 #define __NR_sys_inotify_init __NR_inotify_init
185 #define __NR_sys_inotify_add_watch __NR_inotify_add_watch
186 #define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
188 #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
189 #define __NR__llseek __NR_lseek
193 _syscall0(int, gettid
)
195 /* This is a replacement for the host gettid() and must return a host
197 static int gettid(void) {
201 _syscall1(int,sys_uname
,struct new_utsname
*,buf
)
202 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
203 _syscall4(int,sys_faccessat
,int,dirfd
,const char *,pathname
,int,mode
,int,flags
)
205 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
206 _syscall4(int,sys_fchmodat
,int,dirfd
,const char *,pathname
,
207 mode_t
,mode
,int,flags
)
209 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) && defined(USE_UID16)
210 _syscall5(int,sys_fchownat
,int,dirfd
,const char *,pathname
,
211 uid_t
,owner
,gid_t
,group
,int,flags
)
213 #if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
214 defined(__NR_fstatat64)
215 _syscall4(int,sys_fstatat64
,int,dirfd
,const char *,pathname
,
216 struct stat
*,buf
,int,flags
)
218 #if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
219 _syscall3(int,sys_futimesat
,int,dirfd
,const char *,pathname
,
220 const struct timeval
*,times
)
222 _syscall2(int,sys_getcwd1
,char *,buf
,size_t,size
)
223 #if TARGET_ABI_BITS == 32
224 _syscall3(int, sys_getdents
, uint
, fd
, struct linux_dirent
*, dirp
, uint
, count
);
226 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
227 _syscall3(int, sys_getdents64
, uint
, fd
, struct linux_dirent64
*, dirp
, uint
, count
);
229 _syscall2(int, sys_getpriority
, int, which
, int, who
);
230 #if !defined (__x86_64__)
231 _syscall5(int, _llseek
, uint
, fd
, ulong
, hi
, ulong
, lo
,
232 loff_t
*, res
, uint
, wh
);
234 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
235 _syscall5(int,sys_linkat
,int,olddirfd
,const char *,oldpath
,
236 int,newdirfd
,const char *,newpath
,int,flags
)
238 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
239 _syscall3(int,sys_mkdirat
,int,dirfd
,const char *,pathname
,mode_t
,mode
)
241 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
242 _syscall4(int,sys_mknodat
,int,dirfd
,const char *,pathname
,
243 mode_t
,mode
,dev_t
,dev
)
245 #if (defined(TARGET_NR_newfstatat) || defined(TARGET_NR_fstatat64) ) && \
246 defined(__NR_newfstatat)
247 _syscall4(int,sys_newfstatat
,int,dirfd
,const char *,pathname
,
248 struct stat
*,buf
,int,flags
)
250 #if defined(TARGET_NR_openat) && defined(__NR_openat)
251 _syscall4(int,sys_openat
,int,dirfd
,const char *,pathname
,int,flags
,mode_t
,mode
)
253 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
254 _syscall4(int,sys_readlinkat
,int,dirfd
,const char *,pathname
,
255 char *,buf
,size_t,bufsize
)
257 #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
258 _syscall4(int,sys_renameat
,int,olddirfd
,const char *,oldpath
,
259 int,newdirfd
,const char *,newpath
)
261 _syscall3(int,sys_rt_sigqueueinfo
,int,pid
,int,sig
,siginfo_t
*,uinfo
)
262 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
263 _syscall3(int,sys_symlinkat
,const char *,oldpath
,
264 int,newdirfd
,const char *,newpath
)
266 _syscall3(int,sys_syslog
,int,type
,char*,bufp
,int,len
)
267 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
268 _syscall3(int,sys_tgkill
,int,tgid
,int,pid
,int,sig
)
270 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
271 _syscall2(int,sys_tkill
,int,tid
,int,sig
)
273 #ifdef __NR_exit_group
274 _syscall1(int,exit_group
,int,error_code
)
276 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
277 _syscall1(int,set_tid_address
,int *,tidptr
)
279 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
280 _syscall3(int,sys_unlinkat
,int,dirfd
,const char *,pathname
,int,flags
)
282 #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
283 _syscall4(int,sys_utimensat
,int,dirfd
,const char *,pathname
,
284 const struct timespec
*,tsp
,int,flags
)
286 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
287 _syscall0(int,sys_inotify_init
)
289 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
290 _syscall3(int,sys_inotify_add_watch
,int,fd
,const char *,pathname
,uint32_t,mask
)
292 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
293 _syscall2(int,sys_inotify_rm_watch
,int,fd
,uint32_t,wd
)
295 #if defined(USE_NPTL)
296 #if defined(TARGET_NR_futex) && defined(__NR_futex)
297 _syscall6(int,sys_futex
,int *,uaddr
,int,op
,int,val
,
298 const struct timespec
*,timeout
,int *,uaddr2
,int,val3
)
302 extern int personality(int);
303 extern int flock(int, int);
304 extern int setfsuid(int);
305 extern int setfsgid(int);
306 extern int setgroups(int, gid_t
*);
308 #define ERRNO_TABLE_SIZE 1200
310 /* target_to_host_errno_table[] is initialized from
311 * host_to_target_errno_table[] in syscall_init(). */
312 static uint16_t target_to_host_errno_table
[ERRNO_TABLE_SIZE
] = {
316 * This list is the union of errno values overridden in asm-<arch>/errno.h
317 * minus the errnos that are not actually generic to all archs.
319 static uint16_t host_to_target_errno_table
[ERRNO_TABLE_SIZE
] = {
320 [EIDRM
] = TARGET_EIDRM
,
321 [ECHRNG
] = TARGET_ECHRNG
,
322 [EL2NSYNC
] = TARGET_EL2NSYNC
,
323 [EL3HLT
] = TARGET_EL3HLT
,
324 [EL3RST
] = TARGET_EL3RST
,
325 [ELNRNG
] = TARGET_ELNRNG
,
326 [EUNATCH
] = TARGET_EUNATCH
,
327 [ENOCSI
] = TARGET_ENOCSI
,
328 [EL2HLT
] = TARGET_EL2HLT
,
329 [EDEADLK
] = TARGET_EDEADLK
,
330 [ENOLCK
] = TARGET_ENOLCK
,
331 [EBADE
] = TARGET_EBADE
,
332 [EBADR
] = TARGET_EBADR
,
333 [EXFULL
] = TARGET_EXFULL
,
334 [ENOANO
] = TARGET_ENOANO
,
335 [EBADRQC
] = TARGET_EBADRQC
,
336 [EBADSLT
] = TARGET_EBADSLT
,
337 [EBFONT
] = TARGET_EBFONT
,
338 [ENOSTR
] = TARGET_ENOSTR
,
339 [ENODATA
] = TARGET_ENODATA
,
340 [ETIME
] = TARGET_ETIME
,
341 [ENOSR
] = TARGET_ENOSR
,
342 [ENONET
] = TARGET_ENONET
,
343 [ENOPKG
] = TARGET_ENOPKG
,
344 [EREMOTE
] = TARGET_EREMOTE
,
345 [ENOLINK
] = TARGET_ENOLINK
,
346 [EADV
] = TARGET_EADV
,
347 [ESRMNT
] = TARGET_ESRMNT
,
348 [ECOMM
] = TARGET_ECOMM
,
349 [EPROTO
] = TARGET_EPROTO
,
350 [EDOTDOT
] = TARGET_EDOTDOT
,
351 [EMULTIHOP
] = TARGET_EMULTIHOP
,
352 [EBADMSG
] = TARGET_EBADMSG
,
353 [ENAMETOOLONG
] = TARGET_ENAMETOOLONG
,
354 [EOVERFLOW
] = TARGET_EOVERFLOW
,
355 [ENOTUNIQ
] = TARGET_ENOTUNIQ
,
356 [EBADFD
] = TARGET_EBADFD
,
357 [EREMCHG
] = TARGET_EREMCHG
,
358 [ELIBACC
] = TARGET_ELIBACC
,
359 [ELIBBAD
] = TARGET_ELIBBAD
,
360 [ELIBSCN
] = TARGET_ELIBSCN
,
361 [ELIBMAX
] = TARGET_ELIBMAX
,
362 [ELIBEXEC
] = TARGET_ELIBEXEC
,
363 [EILSEQ
] = TARGET_EILSEQ
,
364 [ENOSYS
] = TARGET_ENOSYS
,
365 [ELOOP
] = TARGET_ELOOP
,
366 [ERESTART
] = TARGET_ERESTART
,
367 [ESTRPIPE
] = TARGET_ESTRPIPE
,
368 [ENOTEMPTY
] = TARGET_ENOTEMPTY
,
369 [EUSERS
] = TARGET_EUSERS
,
370 [ENOTSOCK
] = TARGET_ENOTSOCK
,
371 [EDESTADDRREQ
] = TARGET_EDESTADDRREQ
,
372 [EMSGSIZE
] = TARGET_EMSGSIZE
,
373 [EPROTOTYPE
] = TARGET_EPROTOTYPE
,
374 [ENOPROTOOPT
] = TARGET_ENOPROTOOPT
,
375 [EPROTONOSUPPORT
] = TARGET_EPROTONOSUPPORT
,
376 [ESOCKTNOSUPPORT
] = TARGET_ESOCKTNOSUPPORT
,
377 [EOPNOTSUPP
] = TARGET_EOPNOTSUPP
,
378 [EPFNOSUPPORT
] = TARGET_EPFNOSUPPORT
,
379 [EAFNOSUPPORT
] = TARGET_EAFNOSUPPORT
,
380 [EADDRINUSE
] = TARGET_EADDRINUSE
,
381 [EADDRNOTAVAIL
] = TARGET_EADDRNOTAVAIL
,
382 [ENETDOWN
] = TARGET_ENETDOWN
,
383 [ENETUNREACH
] = TARGET_ENETUNREACH
,
384 [ENETRESET
] = TARGET_ENETRESET
,
385 [ECONNABORTED
] = TARGET_ECONNABORTED
,
386 [ECONNRESET
] = TARGET_ECONNRESET
,
387 [ENOBUFS
] = TARGET_ENOBUFS
,
388 [EISCONN
] = TARGET_EISCONN
,
389 [ENOTCONN
] = TARGET_ENOTCONN
,
390 [EUCLEAN
] = TARGET_EUCLEAN
,
391 [ENOTNAM
] = TARGET_ENOTNAM
,
392 [ENAVAIL
] = TARGET_ENAVAIL
,
393 [EISNAM
] = TARGET_EISNAM
,
394 [EREMOTEIO
] = TARGET_EREMOTEIO
,
395 [ESHUTDOWN
] = TARGET_ESHUTDOWN
,
396 [ETOOMANYREFS
] = TARGET_ETOOMANYREFS
,
397 [ETIMEDOUT
] = TARGET_ETIMEDOUT
,
398 [ECONNREFUSED
] = TARGET_ECONNREFUSED
,
399 [EHOSTDOWN
] = TARGET_EHOSTDOWN
,
400 [EHOSTUNREACH
] = TARGET_EHOSTUNREACH
,
401 [EALREADY
] = TARGET_EALREADY
,
402 [EINPROGRESS
] = TARGET_EINPROGRESS
,
403 [ESTALE
] = TARGET_ESTALE
,
404 [ECANCELED
] = TARGET_ECANCELED
,
405 [ENOMEDIUM
] = TARGET_ENOMEDIUM
,
406 [EMEDIUMTYPE
] = TARGET_EMEDIUMTYPE
,
408 [ENOKEY
] = TARGET_ENOKEY
,
411 [EKEYEXPIRED
] = TARGET_EKEYEXPIRED
,
414 [EKEYREVOKED
] = TARGET_EKEYREVOKED
,
417 [EKEYREJECTED
] = TARGET_EKEYREJECTED
,
420 [EOWNERDEAD
] = TARGET_EOWNERDEAD
,
422 #ifdef ENOTRECOVERABLE
423 [ENOTRECOVERABLE
] = TARGET_ENOTRECOVERABLE
,
427 static inline int host_to_target_errno(int err
)
429 if(host_to_target_errno_table
[err
])
430 return host_to_target_errno_table
[err
];
434 static inline int target_to_host_errno(int err
)
436 if (target_to_host_errno_table
[err
])
437 return target_to_host_errno_table
[err
];
441 static inline abi_long
get_errno(abi_long ret
)
444 return -host_to_target_errno(errno
);
449 static inline int is_error(abi_long ret
)
451 return (abi_ulong
)ret
>= (abi_ulong
)(-4096);
454 char *target_strerror(int err
)
456 return strerror(target_to_host_errno(err
));
459 static abi_ulong target_brk
;
460 static abi_ulong target_original_brk
;
462 void target_set_brk(abi_ulong new_brk
)
464 target_original_brk
= target_brk
= HOST_PAGE_ALIGN(new_brk
);
467 /* do_brk() must return target values and target errnos. */
468 abi_long
do_brk(abi_ulong new_brk
)
471 abi_long mapped_addr
;
476 if (new_brk
< target_original_brk
)
479 brk_page
= HOST_PAGE_ALIGN(target_brk
);
481 /* If the new brk is less than this, set it and we're done... */
482 if (new_brk
< brk_page
) {
483 target_brk
= new_brk
;
487 /* We need to allocate more memory after the brk... */
488 new_alloc_size
= HOST_PAGE_ALIGN(new_brk
- brk_page
+ 1);
489 mapped_addr
= get_errno(target_mmap(brk_page
, new_alloc_size
,
490 PROT_READ
|PROT_WRITE
,
491 MAP_ANON
|MAP_FIXED
|MAP_PRIVATE
, 0, 0));
493 if (!is_error(mapped_addr
))
494 target_brk
= new_brk
;
499 static inline abi_long
copy_from_user_fdset(fd_set
*fds
,
500 abi_ulong target_fds_addr
,
504 abi_ulong b
, *target_fds
;
506 nw
= (n
+ TARGET_ABI_BITS
- 1) / TARGET_ABI_BITS
;
507 if (!(target_fds
= lock_user(VERIFY_READ
,
509 sizeof(abi_ulong
) * nw
,
511 return -TARGET_EFAULT
;
515 for (i
= 0; i
< nw
; i
++) {
516 /* grab the abi_ulong */
517 __get_user(b
, &target_fds
[i
]);
518 for (j
= 0; j
< TARGET_ABI_BITS
; j
++) {
519 /* check the bit inside the abi_ulong */
526 unlock_user(target_fds
, target_fds_addr
, 0);
531 static inline abi_long
copy_to_user_fdset(abi_ulong target_fds_addr
,
537 abi_ulong
*target_fds
;
539 nw
= (n
+ TARGET_ABI_BITS
- 1) / TARGET_ABI_BITS
;
540 if (!(target_fds
= lock_user(VERIFY_WRITE
,
542 sizeof(abi_ulong
) * nw
,
544 return -TARGET_EFAULT
;
547 for (i
= 0; i
< nw
; i
++) {
549 for (j
= 0; j
< TARGET_ABI_BITS
; j
++) {
550 v
|= ((FD_ISSET(k
, fds
) != 0) << j
);
553 __put_user(v
, &target_fds
[i
]);
556 unlock_user(target_fds
, target_fds_addr
, sizeof(abi_ulong
) * nw
);
561 #if defined(__alpha__)
567 static inline abi_long
host_to_target_clock_t(long ticks
)
569 #if HOST_HZ == TARGET_HZ
572 return ((int64_t)ticks
* TARGET_HZ
) / HOST_HZ
;
576 static inline abi_long
host_to_target_rusage(abi_ulong target_addr
,
577 const struct rusage
*rusage
)
579 struct target_rusage
*target_rusage
;
581 if (!lock_user_struct(VERIFY_WRITE
, target_rusage
, target_addr
, 0))
582 return -TARGET_EFAULT
;
583 target_rusage
->ru_utime
.tv_sec
= tswapl(rusage
->ru_utime
.tv_sec
);
584 target_rusage
->ru_utime
.tv_usec
= tswapl(rusage
->ru_utime
.tv_usec
);
585 target_rusage
->ru_stime
.tv_sec
= tswapl(rusage
->ru_stime
.tv_sec
);
586 target_rusage
->ru_stime
.tv_usec
= tswapl(rusage
->ru_stime
.tv_usec
);
587 target_rusage
->ru_maxrss
= tswapl(rusage
->ru_maxrss
);
588 target_rusage
->ru_ixrss
= tswapl(rusage
->ru_ixrss
);
589 target_rusage
->ru_idrss
= tswapl(rusage
->ru_idrss
);
590 target_rusage
->ru_isrss
= tswapl(rusage
->ru_isrss
);
591 target_rusage
->ru_minflt
= tswapl(rusage
->ru_minflt
);
592 target_rusage
->ru_majflt
= tswapl(rusage
->ru_majflt
);
593 target_rusage
->ru_nswap
= tswapl(rusage
->ru_nswap
);
594 target_rusage
->ru_inblock
= tswapl(rusage
->ru_inblock
);
595 target_rusage
->ru_oublock
= tswapl(rusage
->ru_oublock
);
596 target_rusage
->ru_msgsnd
= tswapl(rusage
->ru_msgsnd
);
597 target_rusage
->ru_msgrcv
= tswapl(rusage
->ru_msgrcv
);
598 target_rusage
->ru_nsignals
= tswapl(rusage
->ru_nsignals
);
599 target_rusage
->ru_nvcsw
= tswapl(rusage
->ru_nvcsw
);
600 target_rusage
->ru_nivcsw
= tswapl(rusage
->ru_nivcsw
);
601 unlock_user_struct(target_rusage
, target_addr
, 1);
606 static inline abi_long
copy_from_user_timeval(struct timeval
*tv
,
607 abi_ulong target_tv_addr
)
609 struct target_timeval
*target_tv
;
611 if (!lock_user_struct(VERIFY_READ
, target_tv
, target_tv_addr
, 1))
612 return -TARGET_EFAULT
;
614 __get_user(tv
->tv_sec
, &target_tv
->tv_sec
);
615 __get_user(tv
->tv_usec
, &target_tv
->tv_usec
);
617 unlock_user_struct(target_tv
, target_tv_addr
, 0);
622 static inline abi_long
copy_to_user_timeval(abi_ulong target_tv_addr
,
623 const struct timeval
*tv
)
625 struct target_timeval
*target_tv
;
627 if (!lock_user_struct(VERIFY_WRITE
, target_tv
, target_tv_addr
, 0))
628 return -TARGET_EFAULT
;
630 __put_user(tv
->tv_sec
, &target_tv
->tv_sec
);
631 __put_user(tv
->tv_usec
, &target_tv
->tv_usec
);
633 unlock_user_struct(target_tv
, target_tv_addr
, 1);
639 /* do_select() must return target values and target errnos. */
640 static abi_long
do_select(int n
,
641 abi_ulong rfd_addr
, abi_ulong wfd_addr
,
642 abi_ulong efd_addr
, abi_ulong target_tv_addr
)
644 fd_set rfds
, wfds
, efds
;
645 fd_set
*rfds_ptr
, *wfds_ptr
, *efds_ptr
;
646 struct timeval tv
, *tv_ptr
;
650 if (copy_from_user_fdset(&rfds
, rfd_addr
, n
))
651 return -TARGET_EFAULT
;
657 if (copy_from_user_fdset(&wfds
, wfd_addr
, n
))
658 return -TARGET_EFAULT
;
664 if (copy_from_user_fdset(&efds
, efd_addr
, n
))
665 return -TARGET_EFAULT
;
671 if (target_tv_addr
) {
672 if (copy_from_user_timeval(&tv
, target_tv_addr
))
673 return -TARGET_EFAULT
;
679 ret
= get_errno(select(n
, rfds_ptr
, wfds_ptr
, efds_ptr
, tv_ptr
));
681 if (!is_error(ret
)) {
682 if (rfd_addr
&& copy_to_user_fdset(rfd_addr
, &rfds
, n
))
683 return -TARGET_EFAULT
;
684 if (wfd_addr
&& copy_to_user_fdset(wfd_addr
, &wfds
, n
))
685 return -TARGET_EFAULT
;
686 if (efd_addr
&& copy_to_user_fdset(efd_addr
, &efds
, n
))
687 return -TARGET_EFAULT
;
689 if (target_tv_addr
&& copy_to_user_timeval(target_tv_addr
, &tv
))
690 return -TARGET_EFAULT
;
696 static inline abi_long
target_to_host_sockaddr(struct sockaddr
*addr
,
697 abi_ulong target_addr
,
700 struct target_sockaddr
*target_saddr
;
702 target_saddr
= lock_user(VERIFY_READ
, target_addr
, len
, 1);
704 return -TARGET_EFAULT
;
705 memcpy(addr
, target_saddr
, len
);
706 addr
->sa_family
= tswap16(target_saddr
->sa_family
);
707 unlock_user(target_saddr
, target_addr
, 0);
712 static inline abi_long
host_to_target_sockaddr(abi_ulong target_addr
,
713 struct sockaddr
*addr
,
716 struct target_sockaddr
*target_saddr
;
718 target_saddr
= lock_user(VERIFY_WRITE
, target_addr
, len
, 0);
720 return -TARGET_EFAULT
;
721 memcpy(target_saddr
, addr
, len
);
722 target_saddr
->sa_family
= tswap16(addr
->sa_family
);
723 unlock_user(target_saddr
, target_addr
, len
);
728 /* ??? Should this also swap msgh->name? */
729 static inline abi_long
target_to_host_cmsg(struct msghdr
*msgh
,
730 struct target_msghdr
*target_msgh
)
732 struct cmsghdr
*cmsg
= CMSG_FIRSTHDR(msgh
);
733 abi_long msg_controllen
;
734 abi_ulong target_cmsg_addr
;
735 struct target_cmsghdr
*target_cmsg
;
738 msg_controllen
= tswapl(target_msgh
->msg_controllen
);
739 if (msg_controllen
< sizeof (struct target_cmsghdr
))
741 target_cmsg_addr
= tswapl(target_msgh
->msg_control
);
742 target_cmsg
= lock_user(VERIFY_READ
, target_cmsg_addr
, msg_controllen
, 1);
744 return -TARGET_EFAULT
;
746 while (cmsg
&& target_cmsg
) {
747 void *data
= CMSG_DATA(cmsg
);
748 void *target_data
= TARGET_CMSG_DATA(target_cmsg
);
750 int len
= tswapl(target_cmsg
->cmsg_len
)
751 - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr
));
753 space
+= CMSG_SPACE(len
);
754 if (space
> msgh
->msg_controllen
) {
755 space
-= CMSG_SPACE(len
);
756 gemu_log("Host cmsg overflow\n");
760 cmsg
->cmsg_level
= tswap32(target_cmsg
->cmsg_level
);
761 cmsg
->cmsg_type
= tswap32(target_cmsg
->cmsg_type
);
762 cmsg
->cmsg_len
= CMSG_LEN(len
);
764 if (cmsg
->cmsg_level
!= TARGET_SOL_SOCKET
|| cmsg
->cmsg_type
!= SCM_RIGHTS
) {
765 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg
->cmsg_level
, cmsg
->cmsg_type
);
766 memcpy(data
, target_data
, len
);
768 int *fd
= (int *)data
;
769 int *target_fd
= (int *)target_data
;
770 int i
, numfds
= len
/ sizeof(int);
772 for (i
= 0; i
< numfds
; i
++)
773 fd
[i
] = tswap32(target_fd
[i
]);
776 cmsg
= CMSG_NXTHDR(msgh
, cmsg
);
777 target_cmsg
= TARGET_CMSG_NXTHDR(target_msgh
, target_cmsg
);
779 unlock_user(target_cmsg
, target_cmsg_addr
, 0);
781 msgh
->msg_controllen
= space
;
785 /* ??? Should this also swap msgh->name? */
786 static inline abi_long
host_to_target_cmsg(struct target_msghdr
*target_msgh
,
789 struct cmsghdr
*cmsg
= CMSG_FIRSTHDR(msgh
);
790 abi_long msg_controllen
;
791 abi_ulong target_cmsg_addr
;
792 struct target_cmsghdr
*target_cmsg
;
795 msg_controllen
= tswapl(target_msgh
->msg_controllen
);
796 if (msg_controllen
< sizeof (struct target_cmsghdr
))
798 target_cmsg_addr
= tswapl(target_msgh
->msg_control
);
799 target_cmsg
= lock_user(VERIFY_WRITE
, target_cmsg_addr
, msg_controllen
, 0);
801 return -TARGET_EFAULT
;
803 while (cmsg
&& target_cmsg
) {
804 void *data
= CMSG_DATA(cmsg
);
805 void *target_data
= TARGET_CMSG_DATA(target_cmsg
);
807 int len
= cmsg
->cmsg_len
- CMSG_ALIGN(sizeof (struct cmsghdr
));
809 space
+= TARGET_CMSG_SPACE(len
);
810 if (space
> msg_controllen
) {
811 space
-= TARGET_CMSG_SPACE(len
);
812 gemu_log("Target cmsg overflow\n");
816 target_cmsg
->cmsg_level
= tswap32(cmsg
->cmsg_level
);
817 target_cmsg
->cmsg_type
= tswap32(cmsg
->cmsg_type
);
818 target_cmsg
->cmsg_len
= tswapl(TARGET_CMSG_LEN(len
));
820 if (cmsg
->cmsg_level
!= TARGET_SOL_SOCKET
|| cmsg
->cmsg_type
!= SCM_RIGHTS
) {
821 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg
->cmsg_level
, cmsg
->cmsg_type
);
822 memcpy(target_data
, data
, len
);
824 int *fd
= (int *)data
;
825 int *target_fd
= (int *)target_data
;
826 int i
, numfds
= len
/ sizeof(int);
828 for (i
= 0; i
< numfds
; i
++)
829 target_fd
[i
] = tswap32(fd
[i
]);
832 cmsg
= CMSG_NXTHDR(msgh
, cmsg
);
833 target_cmsg
= TARGET_CMSG_NXTHDR(target_msgh
, target_cmsg
);
835 unlock_user(target_cmsg
, target_cmsg_addr
, space
);
837 target_msgh
->msg_controllen
= tswapl(space
);
841 /* do_setsockopt() Must return target values and target errnos. */
842 static abi_long
do_setsockopt(int sockfd
, int level
, int optname
,
843 abi_ulong optval_addr
, socklen_t optlen
)
850 /* TCP options all take an 'int' value. */
851 if (optlen
< sizeof(uint32_t))
852 return -TARGET_EINVAL
;
854 if (get_user_u32(val
, optval_addr
))
855 return -TARGET_EFAULT
;
856 ret
= get_errno(setsockopt(sockfd
, level
, optname
, &val
, sizeof(val
)));
863 case IP_ROUTER_ALERT
:
867 case IP_MTU_DISCOVER
:
873 case IP_MULTICAST_TTL
:
874 case IP_MULTICAST_LOOP
:
876 if (optlen
>= sizeof(uint32_t)) {
877 if (get_user_u32(val
, optval_addr
))
878 return -TARGET_EFAULT
;
879 } else if (optlen
>= 1) {
880 if (get_user_u8(val
, optval_addr
))
881 return -TARGET_EFAULT
;
883 ret
= get_errno(setsockopt(sockfd
, level
, optname
, &val
, sizeof(val
)));
889 case TARGET_SOL_SOCKET
:
891 /* Options with 'int' argument. */
892 case TARGET_SO_DEBUG
:
895 case TARGET_SO_REUSEADDR
:
896 optname
= SO_REUSEADDR
;
901 case TARGET_SO_ERROR
:
904 case TARGET_SO_DONTROUTE
:
905 optname
= SO_DONTROUTE
;
907 case TARGET_SO_BROADCAST
:
908 optname
= SO_BROADCAST
;
910 case TARGET_SO_SNDBUF
:
913 case TARGET_SO_RCVBUF
:
916 case TARGET_SO_KEEPALIVE
:
917 optname
= SO_KEEPALIVE
;
919 case TARGET_SO_OOBINLINE
:
920 optname
= SO_OOBINLINE
;
922 case TARGET_SO_NO_CHECK
:
923 optname
= SO_NO_CHECK
;
925 case TARGET_SO_PRIORITY
:
926 optname
= SO_PRIORITY
;
929 case TARGET_SO_BSDCOMPAT
:
930 optname
= SO_BSDCOMPAT
;
933 case TARGET_SO_PASSCRED
:
934 optname
= SO_PASSCRED
;
936 case TARGET_SO_TIMESTAMP
:
937 optname
= SO_TIMESTAMP
;
939 case TARGET_SO_RCVLOWAT
:
940 optname
= SO_RCVLOWAT
;
942 case TARGET_SO_RCVTIMEO
:
943 optname
= SO_RCVTIMEO
;
945 case TARGET_SO_SNDTIMEO
:
946 optname
= SO_SNDTIMEO
;
952 if (optlen
< sizeof(uint32_t))
953 return -TARGET_EINVAL
;
955 if (get_user_u32(val
, optval_addr
))
956 return -TARGET_EFAULT
;
957 ret
= get_errno(setsockopt(sockfd
, SOL_SOCKET
, optname
, &val
, sizeof(val
)));
961 gemu_log("Unsupported setsockopt level=%d optname=%d \n", level
, optname
);
962 ret
= -TARGET_ENOPROTOOPT
;
967 /* do_getsockopt() Must return target values and target errnos. */
968 static abi_long
do_getsockopt(int sockfd
, int level
, int optname
,
969 abi_ulong optval_addr
, abi_ulong optlen
)
976 case TARGET_SOL_SOCKET
:
979 case TARGET_SO_LINGER
:
980 case TARGET_SO_RCVTIMEO
:
981 case TARGET_SO_SNDTIMEO
:
982 case TARGET_SO_PEERCRED
:
983 case TARGET_SO_PEERNAME
:
984 /* These don't just return a single integer */
991 /* TCP options all take an 'int' value. */
993 if (get_user_u32(len
, optlen
))
994 return -TARGET_EFAULT
;
996 return -TARGET_EINVAL
;
998 ret
= get_errno(getsockopt(sockfd
, level
, optname
, &val
, &lv
));
1005 if (put_user_u32(val
, optval_addr
))
1006 return -TARGET_EFAULT
;
1008 if (put_user_u8(val
, optval_addr
))
1009 return -TARGET_EFAULT
;
1011 if (put_user_u32(len
, optlen
))
1012 return -TARGET_EFAULT
;
1019 case IP_ROUTER_ALERT
:
1023 case IP_MTU_DISCOVER
:
1029 case IP_MULTICAST_TTL
:
1030 case IP_MULTICAST_LOOP
:
1031 if (get_user_u32(len
, optlen
))
1032 return -TARGET_EFAULT
;
1034 return -TARGET_EINVAL
;
1036 ret
= get_errno(getsockopt(sockfd
, level
, optname
, &val
, &lv
));
1039 if (len
< sizeof(int) && len
> 0 && val
>= 0 && val
< 255) {
1041 if (put_user_u32(len
, optlen
)
1042 || put_user_u8(val
, optval_addr
))
1043 return -TARGET_EFAULT
;
1045 if (len
> sizeof(int))
1047 if (put_user_u32(len
, optlen
)
1048 || put_user_u32(val
, optval_addr
))
1049 return -TARGET_EFAULT
;
1053 ret
= -TARGET_ENOPROTOOPT
;
1059 gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1061 ret
= -TARGET_EOPNOTSUPP
;
1068 * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1069 * other lock functions have a return code of 0 for failure.
1071 static abi_long
lock_iovec(int type
, struct iovec
*vec
, abi_ulong target_addr
,
1072 int count
, int copy
)
1074 struct target_iovec
*target_vec
;
1078 target_vec
= lock_user(VERIFY_READ
, target_addr
, count
* sizeof(struct target_iovec
), 1);
1080 return -TARGET_EFAULT
;
1081 for(i
= 0;i
< count
; i
++) {
1082 base
= tswapl(target_vec
[i
].iov_base
);
1083 vec
[i
].iov_len
= tswapl(target_vec
[i
].iov_len
);
1084 if (vec
[i
].iov_len
!= 0) {
1085 vec
[i
].iov_base
= lock_user(type
, base
, vec
[i
].iov_len
, copy
);
1086 /* Don't check lock_user return value. We must call writev even
1087 if a element has invalid base address. */
1089 /* zero length pointer is ignored */
1090 vec
[i
].iov_base
= NULL
;
1093 unlock_user (target_vec
, target_addr
, 0);
1097 static abi_long
unlock_iovec(struct iovec
*vec
, abi_ulong target_addr
,
1098 int count
, int copy
)
1100 struct target_iovec
*target_vec
;
1104 target_vec
= lock_user(VERIFY_READ
, target_addr
, count
* sizeof(struct target_iovec
), 1);
1106 return -TARGET_EFAULT
;
1107 for(i
= 0;i
< count
; i
++) {
1108 if (target_vec
[i
].iov_base
) {
1109 base
= tswapl(target_vec
[i
].iov_base
);
1110 unlock_user(vec
[i
].iov_base
, base
, copy
? vec
[i
].iov_len
: 0);
1113 unlock_user (target_vec
, target_addr
, 0);
1118 /* do_socket() Must return target values and target errnos. */
1119 static abi_long
do_socket(int domain
, int type
, int protocol
)
1121 #if defined(TARGET_MIPS)
1123 case TARGET_SOCK_DGRAM
:
1126 case TARGET_SOCK_STREAM
:
1129 case TARGET_SOCK_RAW
:
1132 case TARGET_SOCK_RDM
:
1135 case TARGET_SOCK_SEQPACKET
:
1136 type
= SOCK_SEQPACKET
;
1138 case TARGET_SOCK_PACKET
:
1143 if (domain
== PF_NETLINK
)
1144 return -EAFNOSUPPORT
; /* do not NETLINK socket connections possible */
1145 return get_errno(socket(domain
, type
, protocol
));
1148 /* MAX_SOCK_ADDR from linux/net/socket.c */
1149 #define MAX_SOCK_ADDR 128
1151 /* do_bind() Must return target values and target errnos. */
1152 static abi_long
do_bind(int sockfd
, abi_ulong target_addr
,
1157 if (addrlen
< 0 || addrlen
> MAX_SOCK_ADDR
)
1158 return -TARGET_EINVAL
;
1160 addr
= alloca(addrlen
);
1162 target_to_host_sockaddr(addr
, target_addr
, addrlen
);
1163 return get_errno(bind(sockfd
, addr
, addrlen
));
1166 /* do_connect() Must return target values and target errnos. */
1167 static abi_long
do_connect(int sockfd
, abi_ulong target_addr
,
1172 if (addrlen
< 0 || addrlen
> MAX_SOCK_ADDR
)
1173 return -TARGET_EINVAL
;
1175 addr
= alloca(addrlen
);
1177 target_to_host_sockaddr(addr
, target_addr
, addrlen
);
1178 return get_errno(connect(sockfd
, addr
, addrlen
));
1181 /* do_sendrecvmsg() Must return target values and target errnos. */
1182 static abi_long
do_sendrecvmsg(int fd
, abi_ulong target_msg
,
1183 int flags
, int send
)
1186 struct target_msghdr
*msgp
;
1190 abi_ulong target_vec
;
1193 if (!lock_user_struct(send
? VERIFY_READ
: VERIFY_WRITE
,
1197 return -TARGET_EFAULT
;
1198 if (msgp
->msg_name
) {
1199 msg
.msg_namelen
= tswap32(msgp
->msg_namelen
);
1200 msg
.msg_name
= alloca(msg
.msg_namelen
);
1201 target_to_host_sockaddr(msg
.msg_name
, tswapl(msgp
->msg_name
),
1204 msg
.msg_name
= NULL
;
1205 msg
.msg_namelen
= 0;
1207 msg
.msg_controllen
= 2 * tswapl(msgp
->msg_controllen
);
1208 msg
.msg_control
= alloca(msg
.msg_controllen
);
1209 msg
.msg_flags
= tswap32(msgp
->msg_flags
);
1211 count
= tswapl(msgp
->msg_iovlen
);
1212 vec
= alloca(count
* sizeof(struct iovec
));
1213 target_vec
= tswapl(msgp
->msg_iov
);
1214 lock_iovec(send
? VERIFY_READ
: VERIFY_WRITE
, vec
, target_vec
, count
, send
);
1215 msg
.msg_iovlen
= count
;
1219 ret
= target_to_host_cmsg(&msg
, msgp
);
1221 ret
= get_errno(sendmsg(fd
, &msg
, flags
));
1223 ret
= get_errno(recvmsg(fd
, &msg
, flags
));
1224 if (!is_error(ret
)) {
1226 ret
= host_to_target_cmsg(msgp
, &msg
);
1231 unlock_iovec(vec
, target_vec
, count
, !send
);
1232 unlock_user_struct(msgp
, target_msg
, send
? 0 : 1);
1236 /* do_accept() Must return target values and target errnos. */
1237 static abi_long
do_accept(int fd
, abi_ulong target_addr
,
1238 abi_ulong target_addrlen_addr
)
1244 if (get_user_u32(addrlen
, target_addrlen_addr
))
1245 return -TARGET_EFAULT
;
1247 if (addrlen
< 0 || addrlen
> MAX_SOCK_ADDR
)
1248 return -TARGET_EINVAL
;
1250 addr
= alloca(addrlen
);
1252 ret
= get_errno(accept(fd
, addr
, &addrlen
));
1253 if (!is_error(ret
)) {
1254 host_to_target_sockaddr(target_addr
, addr
, addrlen
);
1255 if (put_user_u32(addrlen
, target_addrlen_addr
))
1256 ret
= -TARGET_EFAULT
;
1261 /* do_getpeername() Must return target values and target errnos. */
1262 static abi_long
do_getpeername(int fd
, abi_ulong target_addr
,
1263 abi_ulong target_addrlen_addr
)
1269 if (get_user_u32(addrlen
, target_addrlen_addr
))
1270 return -TARGET_EFAULT
;
1272 if (addrlen
< 0 || addrlen
> MAX_SOCK_ADDR
)
1273 return -TARGET_EINVAL
;
1275 addr
= alloca(addrlen
);
1277 ret
= get_errno(getpeername(fd
, addr
, &addrlen
));
1278 if (!is_error(ret
)) {
1279 host_to_target_sockaddr(target_addr
, addr
, addrlen
);
1280 if (put_user_u32(addrlen
, target_addrlen_addr
))
1281 ret
= -TARGET_EFAULT
;
1286 /* do_getsockname() Must return target values and target errnos. */
1287 static abi_long
do_getsockname(int fd
, abi_ulong target_addr
,
1288 abi_ulong target_addrlen_addr
)
1294 if (target_addr
== 0)
1295 return get_errno(accept(fd
, NULL
, NULL
));
1297 if (get_user_u32(addrlen
, target_addrlen_addr
))
1298 return -TARGET_EFAULT
;
1300 if (addrlen
< 0 || addrlen
> MAX_SOCK_ADDR
)
1301 return -TARGET_EINVAL
;
1303 addr
= alloca(addrlen
);
1305 ret
= get_errno(getsockname(fd
, addr
, &addrlen
));
1306 if (!is_error(ret
)) {
1307 host_to_target_sockaddr(target_addr
, addr
, addrlen
);
1308 if (put_user_u32(addrlen
, target_addrlen_addr
))
1309 ret
= -TARGET_EFAULT
;
1314 /* do_socketpair() Must return target values and target errnos. */
1315 static abi_long
do_socketpair(int domain
, int type
, int protocol
,
1316 abi_ulong target_tab_addr
)
1321 ret
= get_errno(socketpair(domain
, type
, protocol
, tab
));
1322 if (!is_error(ret
)) {
1323 if (put_user_s32(tab
[0], target_tab_addr
)
1324 || put_user_s32(tab
[1], target_tab_addr
+ sizeof(tab
[0])))
1325 ret
= -TARGET_EFAULT
;
1330 /* do_sendto() Must return target values and target errnos. */
1331 static abi_long
do_sendto(int fd
, abi_ulong msg
, size_t len
, int flags
,
1332 abi_ulong target_addr
, socklen_t addrlen
)
1338 if (addrlen
< 0 || addrlen
> MAX_SOCK_ADDR
)
1339 return -TARGET_EINVAL
;
1341 host_msg
= lock_user(VERIFY_READ
, msg
, len
, 1);
1343 return -TARGET_EFAULT
;
1345 addr
= alloca(addrlen
);
1346 target_to_host_sockaddr(addr
, target_addr
, addrlen
);
1347 ret
= get_errno(sendto(fd
, host_msg
, len
, flags
, addr
, addrlen
));
1349 ret
= get_errno(send(fd
, host_msg
, len
, flags
));
1351 unlock_user(host_msg
, msg
, 0);
1355 /* do_recvfrom() Must return target values and target errnos. */
1356 static abi_long
do_recvfrom(int fd
, abi_ulong msg
, size_t len
, int flags
,
1357 abi_ulong target_addr
,
1358 abi_ulong target_addrlen
)
1365 host_msg
= lock_user(VERIFY_WRITE
, msg
, len
, 0);
1367 return -TARGET_EFAULT
;
1369 if (get_user_u32(addrlen
, target_addrlen
)) {
1370 ret
= -TARGET_EFAULT
;
1373 if (addrlen
< 0 || addrlen
> MAX_SOCK_ADDR
) {
1374 ret
= -TARGET_EINVAL
;
1377 addr
= alloca(addrlen
);
1378 ret
= get_errno(recvfrom(fd
, host_msg
, len
, flags
, addr
, &addrlen
));
1380 addr
= NULL
; /* To keep compiler quiet. */
1381 ret
= get_errno(recv(fd
, host_msg
, len
, flags
));
1383 if (!is_error(ret
)) {
1385 host_to_target_sockaddr(target_addr
, addr
, addrlen
);
1386 if (put_user_u32(addrlen
, target_addrlen
)) {
1387 ret
= -TARGET_EFAULT
;
1391 unlock_user(host_msg
, msg
, len
);
1394 unlock_user(host_msg
, msg
, 0);
1399 #ifdef TARGET_NR_socketcall
1400 /* do_socketcall() Must return target values and target errnos. */
1401 static abi_long
do_socketcall(int num
, abi_ulong vptr
)
1404 const int n
= sizeof(abi_ulong
);
1409 int domain
, type
, protocol
;
1411 if (get_user_s32(domain
, vptr
)
1412 || get_user_s32(type
, vptr
+ n
)
1413 || get_user_s32(protocol
, vptr
+ 2 * n
))
1414 return -TARGET_EFAULT
;
1416 ret
= do_socket(domain
, type
, protocol
);
1422 abi_ulong target_addr
;
1425 if (get_user_s32(sockfd
, vptr
)
1426 || get_user_ual(target_addr
, vptr
+ n
)
1427 || get_user_u32(addrlen
, vptr
+ 2 * n
))
1428 return -TARGET_EFAULT
;
1430 ret
= do_bind(sockfd
, target_addr
, addrlen
);
1433 case SOCKOP_connect
:
1436 abi_ulong target_addr
;
1439 if (get_user_s32(sockfd
, vptr
)
1440 || get_user_ual(target_addr
, vptr
+ n
)
1441 || get_user_u32(addrlen
, vptr
+ 2 * n
))
1442 return -TARGET_EFAULT
;
1444 ret
= do_connect(sockfd
, target_addr
, addrlen
);
1449 int sockfd
, backlog
;
1451 if (get_user_s32(sockfd
, vptr
)
1452 || get_user_s32(backlog
, vptr
+ n
))
1453 return -TARGET_EFAULT
;
1455 ret
= get_errno(listen(sockfd
, backlog
));
1461 abi_ulong target_addr
, target_addrlen
;
1463 if (get_user_s32(sockfd
, vptr
)
1464 || get_user_ual(target_addr
, vptr
+ n
)
1465 || get_user_u32(target_addrlen
, vptr
+ 2 * n
))
1466 return -TARGET_EFAULT
;
1468 ret
= do_accept(sockfd
, target_addr
, target_addrlen
);
1471 case SOCKOP_getsockname
:
1474 abi_ulong target_addr
, target_addrlen
;
1476 if (get_user_s32(sockfd
, vptr
)
1477 || get_user_ual(target_addr
, vptr
+ n
)
1478 || get_user_u32(target_addrlen
, vptr
+ 2 * n
))
1479 return -TARGET_EFAULT
;
1481 ret
= do_getsockname(sockfd
, target_addr
, target_addrlen
);
1484 case SOCKOP_getpeername
:
1487 abi_ulong target_addr
, target_addrlen
;
1489 if (get_user_s32(sockfd
, vptr
)
1490 || get_user_ual(target_addr
, vptr
+ n
)
1491 || get_user_u32(target_addrlen
, vptr
+ 2 * n
))
1492 return -TARGET_EFAULT
;
1494 ret
= do_getpeername(sockfd
, target_addr
, target_addrlen
);
1497 case SOCKOP_socketpair
:
1499 int domain
, type
, protocol
;
1502 if (get_user_s32(domain
, vptr
)
1503 || get_user_s32(type
, vptr
+ n
)
1504 || get_user_s32(protocol
, vptr
+ 2 * n
)
1505 || get_user_ual(tab
, vptr
+ 3 * n
))
1506 return -TARGET_EFAULT
;
1508 ret
= do_socketpair(domain
, type
, protocol
, tab
);
1518 if (get_user_s32(sockfd
, vptr
)
1519 || get_user_ual(msg
, vptr
+ n
)
1520 || get_user_ual(len
, vptr
+ 2 * n
)
1521 || get_user_s32(flags
, vptr
+ 3 * n
))
1522 return -TARGET_EFAULT
;
1524 ret
= do_sendto(sockfd
, msg
, len
, flags
, 0, 0);
1534 if (get_user_s32(sockfd
, vptr
)
1535 || get_user_ual(msg
, vptr
+ n
)
1536 || get_user_ual(len
, vptr
+ 2 * n
)
1537 || get_user_s32(flags
, vptr
+ 3 * n
))
1538 return -TARGET_EFAULT
;
1540 ret
= do_recvfrom(sockfd
, msg
, len
, flags
, 0, 0);
1552 if (get_user_s32(sockfd
, vptr
)
1553 || get_user_ual(msg
, vptr
+ n
)
1554 || get_user_ual(len
, vptr
+ 2 * n
)
1555 || get_user_s32(flags
, vptr
+ 3 * n
)
1556 || get_user_ual(addr
, vptr
+ 4 * n
)
1557 || get_user_u32(addrlen
, vptr
+ 5 * n
))
1558 return -TARGET_EFAULT
;
1560 ret
= do_sendto(sockfd
, msg
, len
, flags
, addr
, addrlen
);
1563 case SOCKOP_recvfrom
:
1572 if (get_user_s32(sockfd
, vptr
)
1573 || get_user_ual(msg
, vptr
+ n
)
1574 || get_user_ual(len
, vptr
+ 2 * n
)
1575 || get_user_s32(flags
, vptr
+ 3 * n
)
1576 || get_user_ual(addr
, vptr
+ 4 * n
)
1577 || get_user_u32(addrlen
, vptr
+ 5 * n
))
1578 return -TARGET_EFAULT
;
1580 ret
= do_recvfrom(sockfd
, msg
, len
, flags
, addr
, addrlen
);
1583 case SOCKOP_shutdown
:
1587 if (get_user_s32(sockfd
, vptr
)
1588 || get_user_s32(how
, vptr
+ n
))
1589 return -TARGET_EFAULT
;
1591 ret
= get_errno(shutdown(sockfd
, how
));
1594 case SOCKOP_sendmsg
:
1595 case SOCKOP_recvmsg
:
1598 abi_ulong target_msg
;
1601 if (get_user_s32(fd
, vptr
)
1602 || get_user_ual(target_msg
, vptr
+ n
)
1603 || get_user_s32(flags
, vptr
+ 2 * n
))
1604 return -TARGET_EFAULT
;
1606 ret
= do_sendrecvmsg(fd
, target_msg
, flags
,
1607 (num
== SOCKOP_sendmsg
));
1610 case SOCKOP_setsockopt
:
1618 if (get_user_s32(sockfd
, vptr
)
1619 || get_user_s32(level
, vptr
+ n
)
1620 || get_user_s32(optname
, vptr
+ 2 * n
)
1621 || get_user_ual(optval
, vptr
+ 3 * n
)
1622 || get_user_u32(optlen
, vptr
+ 4 * n
))
1623 return -TARGET_EFAULT
;
1625 ret
= do_setsockopt(sockfd
, level
, optname
, optval
, optlen
);
1628 case SOCKOP_getsockopt
:
1636 if (get_user_s32(sockfd
, vptr
)
1637 || get_user_s32(level
, vptr
+ n
)
1638 || get_user_s32(optname
, vptr
+ 2 * n
)
1639 || get_user_ual(optval
, vptr
+ 3 * n
)
1640 || get_user_u32(optlen
, vptr
+ 4 * n
))
1641 return -TARGET_EFAULT
;
1643 ret
= do_getsockopt(sockfd
, level
, optname
, optval
, optlen
);
1647 gemu_log("Unsupported socketcall: %d\n", num
);
1648 ret
= -TARGET_ENOSYS
;
1655 #ifdef TARGET_NR_ipc
1656 #define N_SHM_REGIONS 32
1658 static struct shm_region
{
1661 } shm_regions
[N_SHM_REGIONS
];
1664 struct target_ipc_perm
1671 unsigned short int mode
;
1672 unsigned short int __pad1
;
1673 unsigned short int __seq
;
1674 unsigned short int __pad2
;
1675 abi_ulong __unused1
;
1676 abi_ulong __unused2
;
1679 struct target_semid_ds
1681 struct target_ipc_perm sem_perm
;
1682 abi_ulong sem_otime
;
1683 abi_ulong __unused1
;
1684 abi_ulong sem_ctime
;
1685 abi_ulong __unused2
;
1686 abi_ulong sem_nsems
;
1687 abi_ulong __unused3
;
1688 abi_ulong __unused4
;
1691 static inline abi_long
target_to_host_ipc_perm(struct ipc_perm
*host_ip
,
1692 abi_ulong target_addr
)
1694 struct target_ipc_perm
*target_ip
;
1695 struct target_semid_ds
*target_sd
;
1697 if (!lock_user_struct(VERIFY_READ
, target_sd
, target_addr
, 1))
1698 return -TARGET_EFAULT
;
1699 target_ip
=&(target_sd
->sem_perm
);
1700 host_ip
->__key
= tswapl(target_ip
->__key
);
1701 host_ip
->uid
= tswapl(target_ip
->uid
);
1702 host_ip
->gid
= tswapl(target_ip
->gid
);
1703 host_ip
->cuid
= tswapl(target_ip
->cuid
);
1704 host_ip
->cgid
= tswapl(target_ip
->cgid
);
1705 host_ip
->mode
= tswapl(target_ip
->mode
);
1706 unlock_user_struct(target_sd
, target_addr
, 0);
1710 static inline abi_long
host_to_target_ipc_perm(abi_ulong target_addr
,
1711 struct ipc_perm
*host_ip
)
1713 struct target_ipc_perm
*target_ip
;
1714 struct target_semid_ds
*target_sd
;
1716 if (!lock_user_struct(VERIFY_WRITE
, target_sd
, target_addr
, 0))
1717 return -TARGET_EFAULT
;
1718 target_ip
= &(target_sd
->sem_perm
);
1719 target_ip
->__key
= tswapl(host_ip
->__key
);
1720 target_ip
->uid
= tswapl(host_ip
->uid
);
1721 target_ip
->gid
= tswapl(host_ip
->gid
);
1722 target_ip
->cuid
= tswapl(host_ip
->cuid
);
1723 target_ip
->cgid
= tswapl(host_ip
->cgid
);
1724 target_ip
->mode
= tswapl(host_ip
->mode
);
1725 unlock_user_struct(target_sd
, target_addr
, 1);
1729 static inline abi_long
target_to_host_semid_ds(struct semid_ds
*host_sd
,
1730 abi_ulong target_addr
)
1732 struct target_semid_ds
*target_sd
;
1734 if (!lock_user_struct(VERIFY_READ
, target_sd
, target_addr
, 1))
1735 return -TARGET_EFAULT
;
1736 target_to_host_ipc_perm(&(host_sd
->sem_perm
),target_addr
);
1737 host_sd
->sem_nsems
= tswapl(target_sd
->sem_nsems
);
1738 host_sd
->sem_otime
= tswapl(target_sd
->sem_otime
);
1739 host_sd
->sem_ctime
= tswapl(target_sd
->sem_ctime
);
1740 unlock_user_struct(target_sd
, target_addr
, 0);
1744 static inline abi_long
host_to_target_semid_ds(abi_ulong target_addr
,
1745 struct semid_ds
*host_sd
)
1747 struct target_semid_ds
*target_sd
;
1749 if (!lock_user_struct(VERIFY_WRITE
, target_sd
, target_addr
, 0))
1750 return -TARGET_EFAULT
;
1751 host_to_target_ipc_perm(target_addr
,&(host_sd
->sem_perm
));
1752 target_sd
->sem_nsems
= tswapl(host_sd
->sem_nsems
);
1753 target_sd
->sem_otime
= tswapl(host_sd
->sem_otime
);
1754 target_sd
->sem_ctime
= tswapl(host_sd
->sem_ctime
);
1755 unlock_user_struct(target_sd
, target_addr
, 1);
1761 struct semid_ds
*buf
;
1762 unsigned short *array
;
1765 union target_semun
{
1768 unsigned short int *array
;
1771 static inline abi_long
target_to_host_semun(int cmd
,
1772 union semun
*host_su
,
1773 abi_ulong target_addr
,
1774 struct semid_ds
*ds
)
1776 union target_semun
*target_su
;
1781 if (!lock_user_struct(VERIFY_READ
, target_su
, target_addr
, 1))
1782 return -TARGET_EFAULT
;
1783 target_to_host_semid_ds(ds
,target_su
->buf
);
1785 unlock_user_struct(target_su
, target_addr
, 0);
1789 if (!lock_user_struct(VERIFY_READ
, target_su
, target_addr
, 1))
1790 return -TARGET_EFAULT
;
1791 host_su
->val
= tswapl(target_su
->val
);
1792 unlock_user_struct(target_su
, target_addr
, 0);
1796 if (!lock_user_struct(VERIFY_READ
, target_su
, target_addr
, 1))
1797 return -TARGET_EFAULT
;
1798 *host_su
->array
= tswap16(*target_su
->array
);
1799 unlock_user_struct(target_su
, target_addr
, 0);
1802 gemu_log("semun operation not fully supported: %d\n", (int)cmd
);
1807 static inline abi_long
host_to_target_semun(int cmd
,
1808 abi_ulong target_addr
,
1809 union semun
*host_su
,
1810 struct semid_ds
*ds
)
1812 union target_semun
*target_su
;
1817 if (lock_user_struct(VERIFY_WRITE
, target_su
, target_addr
, 0))
1818 return -TARGET_EFAULT
;
1819 host_to_target_semid_ds(target_su
->buf
,ds
);
1820 unlock_user_struct(target_su
, target_addr
, 1);
1824 if (lock_user_struct(VERIFY_WRITE
, target_su
, target_addr
, 0))
1825 return -TARGET_EFAULT
;
1826 target_su
->val
= tswapl(host_su
->val
);
1827 unlock_user_struct(target_su
, target_addr
, 1);
1831 if (lock_user_struct(VERIFY_WRITE
, target_su
, target_addr
, 0))
1832 return -TARGET_EFAULT
;
1833 *target_su
->array
= tswap16(*host_su
->array
);
1834 unlock_user_struct(target_su
, target_addr
, 1);
1837 gemu_log("semun operation not fully supported: %d\n", (int)cmd
);
1842 static inline abi_long
do_semctl(int first
, int second
, int third
,
1846 struct semid_ds dsarg
;
1847 int cmd
= third
&0xff;
1852 target_to_host_semun(cmd
,&arg
,ptr
,&dsarg
);
1853 ret
= get_errno(semctl(first
, second
, cmd
, arg
));
1854 host_to_target_semun(cmd
,ptr
,&arg
,&dsarg
);
1857 target_to_host_semun(cmd
,&arg
,ptr
,&dsarg
);
1858 ret
= get_errno(semctl(first
, second
, cmd
, arg
));
1859 host_to_target_semun(cmd
,ptr
,&arg
,&dsarg
);
1862 target_to_host_semun(cmd
,&arg
,ptr
,&dsarg
);
1863 ret
= get_errno(semctl(first
, second
, cmd
, arg
));
1864 host_to_target_semun(cmd
,ptr
,&arg
,&dsarg
);
1867 target_to_host_semun(cmd
,&arg
,ptr
,&dsarg
);
1868 ret
= get_errno(semctl(first
, second
, cmd
, arg
));
1869 host_to_target_semun(cmd
,ptr
,&arg
,&dsarg
);
1872 target_to_host_semun(cmd
,&arg
,ptr
,&dsarg
);
1873 ret
= get_errno(semctl(first
, second
, cmd
, arg
));
1874 host_to_target_semun(cmd
,ptr
,&arg
,&dsarg
);
1877 target_to_host_semun(cmd
,&arg
,ptr
,&dsarg
);
1878 ret
= get_errno(semctl(first
, second
, cmd
, arg
));
1879 host_to_target_semun(cmd
,ptr
,&arg
,&dsarg
);
1882 ret
= get_errno(semctl(first
, second
, cmd
, arg
));
1888 struct target_msqid_ds
1890 struct target_ipc_perm msg_perm
;
1891 abi_ulong msg_stime
;
1892 #if TARGET_ABI_BITS == 32
1893 abi_ulong __unused1
;
1895 abi_ulong msg_rtime
;
1896 #if TARGET_ABI_BITS == 32
1897 abi_ulong __unused2
;
1899 abi_ulong msg_ctime
;
1900 #if TARGET_ABI_BITS == 32
1901 abi_ulong __unused3
;
1903 abi_ulong __msg_cbytes
;
1905 abi_ulong msg_qbytes
;
1906 abi_ulong msg_lspid
;
1907 abi_ulong msg_lrpid
;
1908 abi_ulong __unused4
;
1909 abi_ulong __unused5
;
1912 static inline abi_long
target_to_host_msqid_ds(struct msqid_ds
*host_md
,
1913 abi_ulong target_addr
)
1915 struct target_msqid_ds
*target_md
;
1917 if (!lock_user_struct(VERIFY_READ
, target_md
, target_addr
, 1))
1918 return -TARGET_EFAULT
;
1919 if (target_to_host_ipc_perm(&(host_md
->msg_perm
),target_addr
))
1920 return -TARGET_EFAULT
;
1921 host_md
->msg_stime
= tswapl(target_md
->msg_stime
);
1922 host_md
->msg_rtime
= tswapl(target_md
->msg_rtime
);
1923 host_md
->msg_ctime
= tswapl(target_md
->msg_ctime
);
1924 host_md
->__msg_cbytes
= tswapl(target_md
->__msg_cbytes
);
1925 host_md
->msg_qnum
= tswapl(target_md
->msg_qnum
);
1926 host_md
->msg_qbytes
= tswapl(target_md
->msg_qbytes
);
1927 host_md
->msg_lspid
= tswapl(target_md
->msg_lspid
);
1928 host_md
->msg_lrpid
= tswapl(target_md
->msg_lrpid
);
1929 unlock_user_struct(target_md
, target_addr
, 0);
1933 static inline abi_long
host_to_target_msqid_ds(abi_ulong target_addr
,
1934 struct msqid_ds
*host_md
)
1936 struct target_msqid_ds
*target_md
;
1938 if (!lock_user_struct(VERIFY_WRITE
, target_md
, target_addr
, 0))
1939 return -TARGET_EFAULT
;
1940 if (host_to_target_ipc_perm(target_addr
,&(host_md
->msg_perm
)))
1941 return -TARGET_EFAULT
;
1942 target_md
->msg_stime
= tswapl(host_md
->msg_stime
);
1943 target_md
->msg_rtime
= tswapl(host_md
->msg_rtime
);
1944 target_md
->msg_ctime
= tswapl(host_md
->msg_ctime
);
1945 target_md
->__msg_cbytes
= tswapl(host_md
->__msg_cbytes
);
1946 target_md
->msg_qnum
= tswapl(host_md
->msg_qnum
);
1947 target_md
->msg_qbytes
= tswapl(host_md
->msg_qbytes
);
1948 target_md
->msg_lspid
= tswapl(host_md
->msg_lspid
);
1949 target_md
->msg_lrpid
= tswapl(host_md
->msg_lrpid
);
1950 unlock_user_struct(target_md
, target_addr
, 1);
1954 struct target_msginfo
{
1962 unsigned short int msgseg
;
1965 static inline abi_long
host_to_target_msginfo(abi_ulong target_addr
,
1966 struct msginfo
*host_msginfo
)
1968 struct target_msginfo
*target_msginfo
;
1969 if (!lock_user_struct(VERIFY_WRITE
, target_msginfo
, target_addr
, 0))
1970 return -TARGET_EFAULT
;
1971 __put_user(host_msginfo
->msgpool
, &target_msginfo
->msgpool
);
1972 __put_user(host_msginfo
->msgmap
, &target_msginfo
->msgmap
);
1973 __put_user(host_msginfo
->msgmax
, &target_msginfo
->msgmax
);
1974 __put_user(host_msginfo
->msgmnb
, &target_msginfo
->msgmnb
);
1975 __put_user(host_msginfo
->msgmni
, &target_msginfo
->msgmni
);
1976 __put_user(host_msginfo
->msgssz
, &target_msginfo
->msgssz
);
1977 __put_user(host_msginfo
->msgtql
, &target_msginfo
->msgtql
);
1978 __put_user(host_msginfo
->msgseg
, &target_msginfo
->msgseg
);
1979 unlock_user_struct(target_msginfo
, target_addr
, 1);
1983 static inline abi_long
do_msgctl(int msgid
, int cmd
, abi_long ptr
)
1985 struct msqid_ds dsarg
;
1986 struct msginfo msginfo
;
1987 abi_long ret
= -TARGET_EINVAL
;
1995 if (target_to_host_msqid_ds(&dsarg
,ptr
))
1996 return -TARGET_EFAULT
;
1997 ret
= get_errno(msgctl(msgid
, cmd
, &dsarg
));
1998 if (host_to_target_msqid_ds(ptr
,&dsarg
))
1999 return -TARGET_EFAULT
;
2002 ret
= get_errno(msgctl(msgid
, cmd
, NULL
));
2006 ret
= get_errno(msgctl(msgid
, cmd
, (struct msqid_ds
*)&msginfo
));
2007 if (host_to_target_msginfo(ptr
, &msginfo
))
2008 return -TARGET_EFAULT
;
2015 struct target_msgbuf
{
2020 static inline abi_long
do_msgsnd(int msqid
, abi_long msgp
,
2021 unsigned int msgsz
, int msgflg
)
2023 struct target_msgbuf
*target_mb
;
2024 struct msgbuf
*host_mb
;
2027 if (!lock_user_struct(VERIFY_READ
, target_mb
, msgp
, 0))
2028 return -TARGET_EFAULT
;
2029 host_mb
= malloc(msgsz
+sizeof(long));
2030 host_mb
->mtype
= (abi_long
) tswapl(target_mb
->mtype
);
2031 memcpy(host_mb
->mtext
, target_mb
->mtext
, msgsz
);
2032 ret
= get_errno(msgsnd(msqid
, host_mb
, msgsz
, msgflg
));
2034 unlock_user_struct(target_mb
, msgp
, 0);
2039 static inline abi_long
do_msgrcv(int msqid
, abi_long msgp
,
2040 unsigned int msgsz
, abi_long msgtyp
,
2043 struct target_msgbuf
*target_mb
;
2045 struct msgbuf
*host_mb
;
2048 if (!lock_user_struct(VERIFY_WRITE
, target_mb
, msgp
, 0))
2049 return -TARGET_EFAULT
;
2051 host_mb
= malloc(msgsz
+sizeof(long));
2052 ret
= get_errno(msgrcv(msqid
, host_mb
, msgsz
, tswapl(msgtyp
), msgflg
));
2055 abi_ulong target_mtext_addr
= msgp
+ sizeof(abi_ulong
);
2056 target_mtext
= lock_user(VERIFY_WRITE
, target_mtext_addr
, ret
, 0);
2057 if (!target_mtext
) {
2058 ret
= -TARGET_EFAULT
;
2061 memcpy(target_mb
->mtext
, host_mb
->mtext
, ret
);
2062 unlock_user(target_mtext
, target_mtext_addr
, ret
);
2065 target_mb
->mtype
= tswapl(host_mb
->mtype
);
2070 unlock_user_struct(target_mb
, msgp
, 1);
2074 #ifdef TARGET_NR_ipc
2075 /* ??? This only works with linear mappings. */
2076 /* do_ipc() must return target values and target errnos. */
2077 static abi_long
do_ipc(unsigned int call
, int first
,
2078 int second
, int third
,
2079 abi_long ptr
, abi_long fifth
)
2083 struct shmid_ds shm_info
;
2086 version
= call
>> 16;
2091 ret
= get_errno(semop(first
,(struct sembuf
*)g2h(ptr
), second
));
2095 ret
= get_errno(semget(first
, second
, third
));
2099 ret
= do_semctl(first
, second
, third
, ptr
);
2102 case IPCOP_semtimedop
:
2103 gemu_log("Unsupported ipc call: %d (version %d)\n", call
, version
);
2104 ret
= -TARGET_ENOSYS
;
2108 ret
= get_errno(msgget(first
, second
));
2112 ret
= do_msgsnd(first
, ptr
, second
, third
);
2116 ret
= do_msgctl(first
, second
, ptr
);
2123 struct target_ipc_kludge
{
2128 if (!lock_user_struct(VERIFY_READ
, tmp
, ptr
, 1)) {
2129 ret
= -TARGET_EFAULT
;
2133 ret
= do_msgrcv(first
, tmp
->msgp
, second
, tmp
->msgtyp
, third
);
2135 unlock_user_struct(tmp
, ptr
, 0);
2139 ret
= do_msgrcv(first
, ptr
, second
, fifth
, third
);
2147 /* SHM_* flags are the same on all linux platforms */
2148 host_addr
= shmat(first
, (void *)g2h(ptr
), second
);
2149 if (host_addr
== (void *)-1) {
2150 ret
= get_errno((long)host_addr
);
2153 raddr
= h2g((unsigned long)host_addr
);
2154 /* find out the length of the shared memory segment */
2156 ret
= get_errno(shmctl(first
, IPC_STAT
, &shm_info
));
2157 if (is_error(ret
)) {
2158 /* can't get length, bail out */
2162 page_set_flags(raddr
, raddr
+ shm_info
.shm_segsz
,
2163 PAGE_VALID
| PAGE_READ
|
2164 ((second
& SHM_RDONLY
)? 0: PAGE_WRITE
));
2165 for (i
= 0; i
< N_SHM_REGIONS
; ++i
) {
2166 if (shm_regions
[i
].start
== 0) {
2167 shm_regions
[i
].start
= raddr
;
2168 shm_regions
[i
].size
= shm_info
.shm_segsz
;
2172 if (put_user_ual(raddr
, third
))
2173 return -TARGET_EFAULT
;
2178 for (i
= 0; i
< N_SHM_REGIONS
; ++i
) {
2179 if (shm_regions
[i
].start
== ptr
) {
2180 shm_regions
[i
].start
= 0;
2181 page_set_flags(ptr
, shm_regions
[i
].size
, 0);
2185 ret
= get_errno(shmdt((void *)g2h(ptr
)));
2189 /* IPC_* flag values are the same on all linux platforms */
2190 ret
= get_errno(shmget(first
, second
, third
));
2193 /* IPC_* and SHM_* command values are the same on all linux platforms */
2199 ret
= get_errno(shmctl(first
, second
, NULL
));
2207 gemu_log("Unsupported ipc call: %d (version %d)\n", call
, version
);
2208 ret
= -TARGET_ENOSYS
;
2215 /* kernel structure types definitions */
2218 #define STRUCT(name, list...) STRUCT_ ## name,
2219 #define STRUCT_SPECIAL(name) STRUCT_ ## name,
2221 #include "syscall_types.h"
2224 #undef STRUCT_SPECIAL
2226 #define STRUCT(name, list...) static const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };
2227 #define STRUCT_SPECIAL(name)
2228 #include "syscall_types.h"
2230 #undef STRUCT_SPECIAL
2232 typedef struct IOCTLEntry
{
2233 unsigned int target_cmd
;
2234 unsigned int host_cmd
;
2237 const argtype arg_type
[5];
2240 #define IOC_R 0x0001
2241 #define IOC_W 0x0002
2242 #define IOC_RW (IOC_R | IOC_W)
2244 #define MAX_STRUCT_SIZE 4096
2246 static IOCTLEntry ioctl_entries
[] = {
2247 #define IOCTL(cmd, access, types...) \
2248 { TARGET_ ## cmd, cmd, #cmd, access, { types } },
2253 /* ??? Implement proper locking for ioctls. */
2254 /* do_ioctl() Must return target values and target errnos. */
2255 static abi_long
do_ioctl(int fd
, abi_long cmd
, abi_long arg
)
2257 const IOCTLEntry
*ie
;
2258 const argtype
*arg_type
;
2260 uint8_t buf_temp
[MAX_STRUCT_SIZE
];
2266 if (ie
->target_cmd
== 0) {
2267 gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd
);
2268 return -TARGET_ENOSYS
;
2270 if (ie
->target_cmd
== cmd
)
2274 arg_type
= ie
->arg_type
;
2276 gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd
, ie
->name
);
2278 switch(arg_type
[0]) {
2281 ret
= get_errno(ioctl(fd
, ie
->host_cmd
));
2286 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, arg
));
2290 target_size
= thunk_type_size(arg_type
, 0);
2291 switch(ie
->access
) {
2293 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, buf_temp
));
2294 if (!is_error(ret
)) {
2295 argptr
= lock_user(VERIFY_WRITE
, arg
, target_size
, 0);
2297 return -TARGET_EFAULT
;
2298 thunk_convert(argptr
, buf_temp
, arg_type
, THUNK_TARGET
);
2299 unlock_user(argptr
, arg
, target_size
);
2303 argptr
= lock_user(VERIFY_READ
, arg
, target_size
, 1);
2305 return -TARGET_EFAULT
;
2306 thunk_convert(buf_temp
, argptr
, arg_type
, THUNK_HOST
);
2307 unlock_user(argptr
, arg
, 0);
2308 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, buf_temp
));
2312 argptr
= lock_user(VERIFY_READ
, arg
, target_size
, 1);
2314 return -TARGET_EFAULT
;
2315 thunk_convert(buf_temp
, argptr
, arg_type
, THUNK_HOST
);
2316 unlock_user(argptr
, arg
, 0);
2317 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, buf_temp
));
2318 if (!is_error(ret
)) {
2319 argptr
= lock_user(VERIFY_WRITE
, arg
, target_size
, 0);
2321 return -TARGET_EFAULT
;
2322 thunk_convert(argptr
, buf_temp
, arg_type
, THUNK_TARGET
);
2323 unlock_user(argptr
, arg
, target_size
);
2329 gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
2330 (long)cmd
, arg_type
[0]);
2331 ret
= -TARGET_ENOSYS
;
2337 static const bitmask_transtbl iflag_tbl
[] = {
2338 { TARGET_IGNBRK
, TARGET_IGNBRK
, IGNBRK
, IGNBRK
},
2339 { TARGET_BRKINT
, TARGET_BRKINT
, BRKINT
, BRKINT
},
2340 { TARGET_IGNPAR
, TARGET_IGNPAR
, IGNPAR
, IGNPAR
},
2341 { TARGET_PARMRK
, TARGET_PARMRK
, PARMRK
, PARMRK
},
2342 { TARGET_INPCK
, TARGET_INPCK
, INPCK
, INPCK
},
2343 { TARGET_ISTRIP
, TARGET_ISTRIP
, ISTRIP
, ISTRIP
},
2344 { TARGET_INLCR
, TARGET_INLCR
, INLCR
, INLCR
},
2345 { TARGET_IGNCR
, TARGET_IGNCR
, IGNCR
, IGNCR
},
2346 { TARGET_ICRNL
, TARGET_ICRNL
, ICRNL
, ICRNL
},
2347 { TARGET_IUCLC
, TARGET_IUCLC
, IUCLC
, IUCLC
},
2348 { TARGET_IXON
, TARGET_IXON
, IXON
, IXON
},
2349 { TARGET_IXANY
, TARGET_IXANY
, IXANY
, IXANY
},
2350 { TARGET_IXOFF
, TARGET_IXOFF
, IXOFF
, IXOFF
},
2351 { TARGET_IMAXBEL
, TARGET_IMAXBEL
, IMAXBEL
, IMAXBEL
},
2355 static const bitmask_transtbl oflag_tbl
[] = {
2356 { TARGET_OPOST
, TARGET_OPOST
, OPOST
, OPOST
},
2357 { TARGET_OLCUC
, TARGET_OLCUC
, OLCUC
, OLCUC
},
2358 { TARGET_ONLCR
, TARGET_ONLCR
, ONLCR
, ONLCR
},
2359 { TARGET_OCRNL
, TARGET_OCRNL
, OCRNL
, OCRNL
},
2360 { TARGET_ONOCR
, TARGET_ONOCR
, ONOCR
, ONOCR
},
2361 { TARGET_ONLRET
, TARGET_ONLRET
, ONLRET
, ONLRET
},
2362 { TARGET_OFILL
, TARGET_OFILL
, OFILL
, OFILL
},
2363 { TARGET_OFDEL
, TARGET_OFDEL
, OFDEL
, OFDEL
},
2364 { TARGET_NLDLY
, TARGET_NL0
, NLDLY
, NL0
},
2365 { TARGET_NLDLY
, TARGET_NL1
, NLDLY
, NL1
},
2366 { TARGET_CRDLY
, TARGET_CR0
, CRDLY
, CR0
},
2367 { TARGET_CRDLY
, TARGET_CR1
, CRDLY
, CR1
},
2368 { TARGET_CRDLY
, TARGET_CR2
, CRDLY
, CR2
},
2369 { TARGET_CRDLY
, TARGET_CR3
, CRDLY
, CR3
},
2370 { TARGET_TABDLY
, TARGET_TAB0
, TABDLY
, TAB0
},
2371 { TARGET_TABDLY
, TARGET_TAB1
, TABDLY
, TAB1
},
2372 { TARGET_TABDLY
, TARGET_TAB2
, TABDLY
, TAB2
},
2373 { TARGET_TABDLY
, TARGET_TAB3
, TABDLY
, TAB3
},
2374 { TARGET_BSDLY
, TARGET_BS0
, BSDLY
, BS0
},
2375 { TARGET_BSDLY
, TARGET_BS1
, BSDLY
, BS1
},
2376 { TARGET_VTDLY
, TARGET_VT0
, VTDLY
, VT0
},
2377 { TARGET_VTDLY
, TARGET_VT1
, VTDLY
, VT1
},
2378 { TARGET_FFDLY
, TARGET_FF0
, FFDLY
, FF0
},
2379 { TARGET_FFDLY
, TARGET_FF1
, FFDLY
, FF1
},
2383 static const bitmask_transtbl cflag_tbl
[] = {
2384 { TARGET_CBAUD
, TARGET_B0
, CBAUD
, B0
},
2385 { TARGET_CBAUD
, TARGET_B50
, CBAUD
, B50
},
2386 { TARGET_CBAUD
, TARGET_B75
, CBAUD
, B75
},
2387 { TARGET_CBAUD
, TARGET_B110
, CBAUD
, B110
},
2388 { TARGET_CBAUD
, TARGET_B134
, CBAUD
, B134
},
2389 { TARGET_CBAUD
, TARGET_B150
, CBAUD
, B150
},
2390 { TARGET_CBAUD
, TARGET_B200
, CBAUD
, B200
},
2391 { TARGET_CBAUD
, TARGET_B300
, CBAUD
, B300
},
2392 { TARGET_CBAUD
, TARGET_B600
, CBAUD
, B600
},
2393 { TARGET_CBAUD
, TARGET_B1200
, CBAUD
, B1200
},
2394 { TARGET_CBAUD
, TARGET_B1800
, CBAUD
, B1800
},
2395 { TARGET_CBAUD
, TARGET_B2400
, CBAUD
, B2400
},
2396 { TARGET_CBAUD
, TARGET_B4800
, CBAUD
, B4800
},
2397 { TARGET_CBAUD
, TARGET_B9600
, CBAUD
, B9600
},
2398 { TARGET_CBAUD
, TARGET_B19200
, CBAUD
, B19200
},
2399 { TARGET_CBAUD
, TARGET_B38400
, CBAUD
, B38400
},
2400 { TARGET_CBAUD
, TARGET_B57600
, CBAUD
, B57600
},
2401 { TARGET_CBAUD
, TARGET_B115200
, CBAUD
, B115200
},
2402 { TARGET_CBAUD
, TARGET_B230400
, CBAUD
, B230400
},
2403 { TARGET_CBAUD
, TARGET_B460800
, CBAUD
, B460800
},
2404 { TARGET_CSIZE
, TARGET_CS5
, CSIZE
, CS5
},
2405 { TARGET_CSIZE
, TARGET_CS6
, CSIZE
, CS6
},
2406 { TARGET_CSIZE
, TARGET_CS7
, CSIZE
, CS7
},
2407 { TARGET_CSIZE
, TARGET_CS8
, CSIZE
, CS8
},
2408 { TARGET_CSTOPB
, TARGET_CSTOPB
, CSTOPB
, CSTOPB
},
2409 { TARGET_CREAD
, TARGET_CREAD
, CREAD
, CREAD
},
2410 { TARGET_PARENB
, TARGET_PARENB
, PARENB
, PARENB
},
2411 { TARGET_PARODD
, TARGET_PARODD
, PARODD
, PARODD
},
2412 { TARGET_HUPCL
, TARGET_HUPCL
, HUPCL
, HUPCL
},
2413 { TARGET_CLOCAL
, TARGET_CLOCAL
, CLOCAL
, CLOCAL
},
2414 { TARGET_CRTSCTS
, TARGET_CRTSCTS
, CRTSCTS
, CRTSCTS
},
2418 static const bitmask_transtbl lflag_tbl
[] = {
2419 { TARGET_ISIG
, TARGET_ISIG
, ISIG
, ISIG
},
2420 { TARGET_ICANON
, TARGET_ICANON
, ICANON
, ICANON
},
2421 { TARGET_XCASE
, TARGET_XCASE
, XCASE
, XCASE
},
2422 { TARGET_ECHO
, TARGET_ECHO
, ECHO
, ECHO
},
2423 { TARGET_ECHOE
, TARGET_ECHOE
, ECHOE
, ECHOE
},
2424 { TARGET_ECHOK
, TARGET_ECHOK
, ECHOK
, ECHOK
},
2425 { TARGET_ECHONL
, TARGET_ECHONL
, ECHONL
, ECHONL
},
2426 { TARGET_NOFLSH
, TARGET_NOFLSH
, NOFLSH
, NOFLSH
},
2427 { TARGET_TOSTOP
, TARGET_TOSTOP
, TOSTOP
, TOSTOP
},
2428 { TARGET_ECHOCTL
, TARGET_ECHOCTL
, ECHOCTL
, ECHOCTL
},
2429 { TARGET_ECHOPRT
, TARGET_ECHOPRT
, ECHOPRT
, ECHOPRT
},
2430 { TARGET_ECHOKE
, TARGET_ECHOKE
, ECHOKE
, ECHOKE
},
2431 { TARGET_FLUSHO
, TARGET_FLUSHO
, FLUSHO
, FLUSHO
},
2432 { TARGET_PENDIN
, TARGET_PENDIN
, PENDIN
, PENDIN
},
2433 { TARGET_IEXTEN
, TARGET_IEXTEN
, IEXTEN
, IEXTEN
},
2437 static void target_to_host_termios (void *dst
, const void *src
)
2439 struct host_termios
*host
= dst
;
2440 const struct target_termios
*target
= src
;
2443 target_to_host_bitmask(tswap32(target
->c_iflag
), iflag_tbl
);
2445 target_to_host_bitmask(tswap32(target
->c_oflag
), oflag_tbl
);
2447 target_to_host_bitmask(tswap32(target
->c_cflag
), cflag_tbl
);
2449 target_to_host_bitmask(tswap32(target
->c_lflag
), lflag_tbl
);
2450 host
->c_line
= target
->c_line
;
2452 host
->c_cc
[VINTR
] = target
->c_cc
[TARGET_VINTR
];
2453 host
->c_cc
[VQUIT
] = target
->c_cc
[TARGET_VQUIT
];
2454 host
->c_cc
[VERASE
] = target
->c_cc
[TARGET_VERASE
];
2455 host
->c_cc
[VKILL
] = target
->c_cc
[TARGET_VKILL
];
2456 host
->c_cc
[VEOF
] = target
->c_cc
[TARGET_VEOF
];
2457 host
->c_cc
[VTIME
] = target
->c_cc
[TARGET_VTIME
];
2458 host
->c_cc
[VMIN
] = target
->c_cc
[TARGET_VMIN
];
2459 host
->c_cc
[VSWTC
] = target
->c_cc
[TARGET_VSWTC
];
2460 host
->c_cc
[VSTART
] = target
->c_cc
[TARGET_VSTART
];
2461 host
->c_cc
[VSTOP
] = target
->c_cc
[TARGET_VSTOP
];
2462 host
->c_cc
[VSUSP
] = target
->c_cc
[TARGET_VSUSP
];
2463 host
->c_cc
[VEOL
] = target
->c_cc
[TARGET_VEOL
];
2464 host
->c_cc
[VREPRINT
] = target
->c_cc
[TARGET_VREPRINT
];
2465 host
->c_cc
[VDISCARD
] = target
->c_cc
[TARGET_VDISCARD
];
2466 host
->c_cc
[VWERASE
] = target
->c_cc
[TARGET_VWERASE
];
2467 host
->c_cc
[VLNEXT
] = target
->c_cc
[TARGET_VLNEXT
];
2468 host
->c_cc
[VEOL2
] = target
->c_cc
[TARGET_VEOL2
];
2471 static void host_to_target_termios (void *dst
, const void *src
)
2473 struct target_termios
*target
= dst
;
2474 const struct host_termios
*host
= src
;
2477 tswap32(host_to_target_bitmask(host
->c_iflag
, iflag_tbl
));
2479 tswap32(host_to_target_bitmask(host
->c_oflag
, oflag_tbl
));
2481 tswap32(host_to_target_bitmask(host
->c_cflag
, cflag_tbl
));
2483 tswap32(host_to_target_bitmask(host
->c_lflag
, lflag_tbl
));
2484 target
->c_line
= host
->c_line
;
2486 target
->c_cc
[TARGET_VINTR
] = host
->c_cc
[VINTR
];
2487 target
->c_cc
[TARGET_VQUIT
] = host
->c_cc
[VQUIT
];
2488 target
->c_cc
[TARGET_VERASE
] = host
->c_cc
[VERASE
];
2489 target
->c_cc
[TARGET_VKILL
] = host
->c_cc
[VKILL
];
2490 target
->c_cc
[TARGET_VEOF
] = host
->c_cc
[VEOF
];
2491 target
->c_cc
[TARGET_VTIME
] = host
->c_cc
[VTIME
];
2492 target
->c_cc
[TARGET_VMIN
] = host
->c_cc
[VMIN
];
2493 target
->c_cc
[TARGET_VSWTC
] = host
->c_cc
[VSWTC
];
2494 target
->c_cc
[TARGET_VSTART
] = host
->c_cc
[VSTART
];
2495 target
->c_cc
[TARGET_VSTOP
] = host
->c_cc
[VSTOP
];
2496 target
->c_cc
[TARGET_VSUSP
] = host
->c_cc
[VSUSP
];
2497 target
->c_cc
[TARGET_VEOL
] = host
->c_cc
[VEOL
];
2498 target
->c_cc
[TARGET_VREPRINT
] = host
->c_cc
[VREPRINT
];
2499 target
->c_cc
[TARGET_VDISCARD
] = host
->c_cc
[VDISCARD
];
2500 target
->c_cc
[TARGET_VWERASE
] = host
->c_cc
[VWERASE
];
2501 target
->c_cc
[TARGET_VLNEXT
] = host
->c_cc
[VLNEXT
];
2502 target
->c_cc
[TARGET_VEOL2
] = host
->c_cc
[VEOL2
];
2505 static const StructEntry struct_termios_def
= {
2506 .convert
= { host_to_target_termios
, target_to_host_termios
},
2507 .size
= { sizeof(struct target_termios
), sizeof(struct host_termios
) },
2508 .align
= { __alignof__(struct target_termios
), __alignof__(struct host_termios
) },
2511 static bitmask_transtbl mmap_flags_tbl
[] = {
2512 { TARGET_MAP_SHARED
, TARGET_MAP_SHARED
, MAP_SHARED
, MAP_SHARED
},
2513 { TARGET_MAP_PRIVATE
, TARGET_MAP_PRIVATE
, MAP_PRIVATE
, MAP_PRIVATE
},
2514 { TARGET_MAP_FIXED
, TARGET_MAP_FIXED
, MAP_FIXED
, MAP_FIXED
},
2515 { TARGET_MAP_ANONYMOUS
, TARGET_MAP_ANONYMOUS
, MAP_ANONYMOUS
, MAP_ANONYMOUS
},
2516 { TARGET_MAP_GROWSDOWN
, TARGET_MAP_GROWSDOWN
, MAP_GROWSDOWN
, MAP_GROWSDOWN
},
2517 { TARGET_MAP_DENYWRITE
, TARGET_MAP_DENYWRITE
, MAP_DENYWRITE
, MAP_DENYWRITE
},
2518 { TARGET_MAP_EXECUTABLE
, TARGET_MAP_EXECUTABLE
, MAP_EXECUTABLE
, MAP_EXECUTABLE
},
2519 { TARGET_MAP_LOCKED
, TARGET_MAP_LOCKED
, MAP_LOCKED
, MAP_LOCKED
},
2523 static bitmask_transtbl fcntl_flags_tbl
[] = {
2524 { TARGET_O_ACCMODE
, TARGET_O_WRONLY
, O_ACCMODE
, O_WRONLY
, },
2525 { TARGET_O_ACCMODE
, TARGET_O_RDWR
, O_ACCMODE
, O_RDWR
, },
2526 { TARGET_O_CREAT
, TARGET_O_CREAT
, O_CREAT
, O_CREAT
, },
2527 { TARGET_O_EXCL
, TARGET_O_EXCL
, O_EXCL
, O_EXCL
, },
2528 { TARGET_O_NOCTTY
, TARGET_O_NOCTTY
, O_NOCTTY
, O_NOCTTY
, },
2529 { TARGET_O_TRUNC
, TARGET_O_TRUNC
, O_TRUNC
, O_TRUNC
, },
2530 { TARGET_O_APPEND
, TARGET_O_APPEND
, O_APPEND
, O_APPEND
, },
2531 { TARGET_O_NONBLOCK
, TARGET_O_NONBLOCK
, O_NONBLOCK
, O_NONBLOCK
, },
2532 { TARGET_O_SYNC
, TARGET_O_SYNC
, O_SYNC
, O_SYNC
, },
2533 { TARGET_FASYNC
, TARGET_FASYNC
, FASYNC
, FASYNC
, },
2534 { TARGET_O_DIRECTORY
, TARGET_O_DIRECTORY
, O_DIRECTORY
, O_DIRECTORY
, },
2535 { TARGET_O_NOFOLLOW
, TARGET_O_NOFOLLOW
, O_NOFOLLOW
, O_NOFOLLOW
, },
2536 { TARGET_O_LARGEFILE
, TARGET_O_LARGEFILE
, O_LARGEFILE
, O_LARGEFILE
, },
2537 #if defined(O_DIRECT)
2538 { TARGET_O_DIRECT
, TARGET_O_DIRECT
, O_DIRECT
, O_DIRECT
, },
2543 #if defined(TARGET_I386)
2545 /* NOTE: there is really one LDT for all the threads */
2546 static uint8_t *ldt_table
;
2548 static abi_long
read_ldt(abi_ulong ptr
, unsigned long bytecount
)
2555 size
= TARGET_LDT_ENTRIES
* TARGET_LDT_ENTRY_SIZE
;
2556 if (size
> bytecount
)
2558 p
= lock_user(VERIFY_WRITE
, ptr
, size
, 0);
2560 return -TARGET_EFAULT
;
2561 /* ??? Should this by byteswapped? */
2562 memcpy(p
, ldt_table
, size
);
2563 unlock_user(p
, ptr
, size
);
2567 /* XXX: add locking support */
2568 static abi_long
write_ldt(CPUX86State
*env
,
2569 abi_ulong ptr
, unsigned long bytecount
, int oldmode
)
2571 struct target_modify_ldt_ldt_s ldt_info
;
2572 struct target_modify_ldt_ldt_s
*target_ldt_info
;
2573 int seg_32bit
, contents
, read_exec_only
, limit_in_pages
;
2574 int seg_not_present
, useable
, lm
;
2575 uint32_t *lp
, entry_1
, entry_2
;
2577 if (bytecount
!= sizeof(ldt_info
))
2578 return -TARGET_EINVAL
;
2579 if (!lock_user_struct(VERIFY_READ
, target_ldt_info
, ptr
, 1))
2580 return -TARGET_EFAULT
;
2581 ldt_info
.entry_number
= tswap32(target_ldt_info
->entry_number
);
2582 ldt_info
.base_addr
= tswapl(target_ldt_info
->base_addr
);
2583 ldt_info
.limit
= tswap32(target_ldt_info
->limit
);
2584 ldt_info
.flags
= tswap32(target_ldt_info
->flags
);
2585 unlock_user_struct(target_ldt_info
, ptr
, 0);
2587 if (ldt_info
.entry_number
>= TARGET_LDT_ENTRIES
)
2588 return -TARGET_EINVAL
;
2589 seg_32bit
= ldt_info
.flags
& 1;
2590 contents
= (ldt_info
.flags
>> 1) & 3;
2591 read_exec_only
= (ldt_info
.flags
>> 3) & 1;
2592 limit_in_pages
= (ldt_info
.flags
>> 4) & 1;
2593 seg_not_present
= (ldt_info
.flags
>> 5) & 1;
2594 useable
= (ldt_info
.flags
>> 6) & 1;
2598 lm
= (ldt_info
.flags
>> 7) & 1;
2600 if (contents
== 3) {
2602 return -TARGET_EINVAL
;
2603 if (seg_not_present
== 0)
2604 return -TARGET_EINVAL
;
2606 /* allocate the LDT */
2608 env
->ldt
.base
= target_mmap(0,
2609 TARGET_LDT_ENTRIES
* TARGET_LDT_ENTRY_SIZE
,
2610 PROT_READ
|PROT_WRITE
,
2611 MAP_ANONYMOUS
|MAP_PRIVATE
, -1, 0);
2612 if (env
->ldt
.base
== -1)
2613 return -TARGET_ENOMEM
;
2614 memset(g2h(env
->ldt
.base
), 0,
2615 TARGET_LDT_ENTRIES
* TARGET_LDT_ENTRY_SIZE
);
2616 env
->ldt
.limit
= 0xffff;
2617 ldt_table
= g2h(env
->ldt
.base
);
2620 /* NOTE: same code as Linux kernel */
2621 /* Allow LDTs to be cleared by the user. */
2622 if (ldt_info
.base_addr
== 0 && ldt_info
.limit
== 0) {
2625 read_exec_only
== 1 &&
2627 limit_in_pages
== 0 &&
2628 seg_not_present
== 1 &&
2636 entry_1
= ((ldt_info
.base_addr
& 0x0000ffff) << 16) |
2637 (ldt_info
.limit
& 0x0ffff);
2638 entry_2
= (ldt_info
.base_addr
& 0xff000000) |
2639 ((ldt_info
.base_addr
& 0x00ff0000) >> 16) |
2640 (ldt_info
.limit
& 0xf0000) |
2641 ((read_exec_only
^ 1) << 9) |
2643 ((seg_not_present
^ 1) << 15) |
2645 (limit_in_pages
<< 23) |
2649 entry_2
|= (useable
<< 20);
2651 /* Install the new entry ... */
2653 lp
= (uint32_t *)(ldt_table
+ (ldt_info
.entry_number
<< 3));
2654 lp
[0] = tswap32(entry_1
);
2655 lp
[1] = tswap32(entry_2
);
2659 /* specific and weird i386 syscalls */
2660 static abi_long
do_modify_ldt(CPUX86State
*env
, int func
, abi_ulong ptr
,
2661 unsigned long bytecount
)
2667 ret
= read_ldt(ptr
, bytecount
);
2670 ret
= write_ldt(env
, ptr
, bytecount
, 1);
2673 ret
= write_ldt(env
, ptr
, bytecount
, 0);
2676 ret
= -TARGET_ENOSYS
;
2682 #if defined(TARGET_I386) && defined(TARGET_ABI32)
2683 static abi_long
do_set_thread_area(CPUX86State
*env
, abi_ulong ptr
)
2685 uint64_t *gdt_table
= g2h(env
->gdt
.base
);
2686 struct target_modify_ldt_ldt_s ldt_info
;
2687 struct target_modify_ldt_ldt_s
*target_ldt_info
;
2688 int seg_32bit
, contents
, read_exec_only
, limit_in_pages
;
2689 int seg_not_present
, useable
, lm
;
2690 uint32_t *lp
, entry_1
, entry_2
;
2693 lock_user_struct(VERIFY_WRITE
, target_ldt_info
, ptr
, 1);
2694 if (!target_ldt_info
)
2695 return -TARGET_EFAULT
;
2696 ldt_info
.entry_number
= tswap32(target_ldt_info
->entry_number
);
2697 ldt_info
.base_addr
= tswapl(target_ldt_info
->base_addr
);
2698 ldt_info
.limit
= tswap32(target_ldt_info
->limit
);
2699 ldt_info
.flags
= tswap32(target_ldt_info
->flags
);
2700 if (ldt_info
.entry_number
== -1) {
2701 for (i
=TARGET_GDT_ENTRY_TLS_MIN
; i
<=TARGET_GDT_ENTRY_TLS_MAX
; i
++) {
2702 if (gdt_table
[i
] == 0) {
2703 ldt_info
.entry_number
= i
;
2704 target_ldt_info
->entry_number
= tswap32(i
);
2709 unlock_user_struct(target_ldt_info
, ptr
, 1);
2711 if (ldt_info
.entry_number
< TARGET_GDT_ENTRY_TLS_MIN
||
2712 ldt_info
.entry_number
> TARGET_GDT_ENTRY_TLS_MAX
)
2713 return -TARGET_EINVAL
;
2714 seg_32bit
= ldt_info
.flags
& 1;
2715 contents
= (ldt_info
.flags
>> 1) & 3;
2716 read_exec_only
= (ldt_info
.flags
>> 3) & 1;
2717 limit_in_pages
= (ldt_info
.flags
>> 4) & 1;
2718 seg_not_present
= (ldt_info
.flags
>> 5) & 1;
2719 useable
= (ldt_info
.flags
>> 6) & 1;
2723 lm
= (ldt_info
.flags
>> 7) & 1;
2726 if (contents
== 3) {
2727 if (seg_not_present
== 0)
2728 return -TARGET_EINVAL
;
2731 /* NOTE: same code as Linux kernel */
2732 /* Allow LDTs to be cleared by the user. */
2733 if (ldt_info
.base_addr
== 0 && ldt_info
.limit
== 0) {
2734 if ((contents
== 0 &&
2735 read_exec_only
== 1 &&
2737 limit_in_pages
== 0 &&
2738 seg_not_present
== 1 &&
2746 entry_1
= ((ldt_info
.base_addr
& 0x0000ffff) << 16) |
2747 (ldt_info
.limit
& 0x0ffff);
2748 entry_2
= (ldt_info
.base_addr
& 0xff000000) |
2749 ((ldt_info
.base_addr
& 0x00ff0000) >> 16) |
2750 (ldt_info
.limit
& 0xf0000) |
2751 ((read_exec_only
^ 1) << 9) |
2753 ((seg_not_present
^ 1) << 15) |
2755 (limit_in_pages
<< 23) |
2760 /* Install the new entry ... */
2762 lp
= (uint32_t *)(gdt_table
+ ldt_info
.entry_number
);
2763 lp
[0] = tswap32(entry_1
);
2764 lp
[1] = tswap32(entry_2
);
2768 static abi_long
do_get_thread_area(CPUX86State
*env
, abi_ulong ptr
)
2770 struct target_modify_ldt_ldt_s
*target_ldt_info
;
2771 uint64_t *gdt_table
= g2h(env
->gdt
.base
);
2772 uint32_t base_addr
, limit
, flags
;
2773 int seg_32bit
, contents
, read_exec_only
, limit_in_pages
, idx
;
2774 int seg_not_present
, useable
, lm
;
2775 uint32_t *lp
, entry_1
, entry_2
;
2777 lock_user_struct(VERIFY_WRITE
, target_ldt_info
, ptr
, 1);
2778 if (!target_ldt_info
)
2779 return -TARGET_EFAULT
;
2780 idx
= tswap32(target_ldt_info
->entry_number
);
2781 if (idx
< TARGET_GDT_ENTRY_TLS_MIN
||
2782 idx
> TARGET_GDT_ENTRY_TLS_MAX
) {
2783 unlock_user_struct(target_ldt_info
, ptr
, 1);
2784 return -TARGET_EINVAL
;
2786 lp
= (uint32_t *)(gdt_table
+ idx
);
2787 entry_1
= tswap32(lp
[0]);
2788 entry_2
= tswap32(lp
[1]);
2790 read_exec_only
= ((entry_2
>> 9) & 1) ^ 1;
2791 contents
= (entry_2
>> 10) & 3;
2792 seg_not_present
= ((entry_2
>> 15) & 1) ^ 1;
2793 seg_32bit
= (entry_2
>> 22) & 1;
2794 limit_in_pages
= (entry_2
>> 23) & 1;
2795 useable
= (entry_2
>> 20) & 1;
2799 lm
= (entry_2
>> 21) & 1;
2801 flags
= (seg_32bit
<< 0) | (contents
<< 1) |
2802 (read_exec_only
<< 3) | (limit_in_pages
<< 4) |
2803 (seg_not_present
<< 5) | (useable
<< 6) | (lm
<< 7);
2804 limit
= (entry_1
& 0xffff) | (entry_2
& 0xf0000);
2805 base_addr
= (entry_1
>> 16) |
2806 (entry_2
& 0xff000000) |
2807 ((entry_2
& 0xff) << 16);
2808 target_ldt_info
->base_addr
= tswapl(base_addr
);
2809 target_ldt_info
->limit
= tswap32(limit
);
2810 target_ldt_info
->flags
= tswap32(flags
);
2811 unlock_user_struct(target_ldt_info
, ptr
, 1);
2814 #endif /* TARGET_I386 && TARGET_ABI32 */
2816 #ifndef TARGET_ABI32
2817 static abi_long
do_arch_prctl(CPUX86State
*env
, int code
, abi_ulong addr
)
2824 case TARGET_ARCH_SET_GS
:
2825 case TARGET_ARCH_SET_FS
:
2826 if (code
== TARGET_ARCH_SET_GS
)
2830 cpu_x86_load_seg(env
, idx
, 0);
2831 env
->segs
[idx
].base
= addr
;
2833 case TARGET_ARCH_GET_GS
:
2834 case TARGET_ARCH_GET_FS
:
2835 if (code
== TARGET_ARCH_GET_GS
)
2839 val
= env
->segs
[idx
].base
;
2840 if (put_user(val
, addr
, abi_ulong
))
2841 return -TARGET_EFAULT
;
2844 ret
= -TARGET_EINVAL
;
2851 #endif /* defined(TARGET_I386) */
2853 #if defined(USE_NPTL)
2855 #define NEW_STACK_SIZE PTHREAD_STACK_MIN
2857 static pthread_mutex_t clone_lock
= PTHREAD_MUTEX_INITIALIZER
;
2860 pthread_mutex_t mutex
;
2861 pthread_cond_t cond
;
2864 abi_ulong child_tidptr
;
2865 abi_ulong parent_tidptr
;
2869 static void *clone_func(void *arg
)
2871 new_thread_info
*info
= arg
;
2876 info
->tid
= gettid();
2877 if (info
->child_tidptr
)
2878 put_user_u32(info
->tid
, info
->child_tidptr
);
2879 if (info
->parent_tidptr
)
2880 put_user_u32(info
->tid
, info
->parent_tidptr
);
2881 /* Enable signals. */
2882 sigprocmask(SIG_SETMASK
, &info
->sigmask
, NULL
);
2883 /* Signal to the parent that we're ready. */
2884 pthread_mutex_lock(&info
->mutex
);
2885 pthread_cond_broadcast(&info
->cond
);
2886 pthread_mutex_unlock(&info
->mutex
);
2887 /* Wait until the parent has finshed initializing the tls state. */
2888 pthread_mutex_lock(&clone_lock
);
2889 pthread_mutex_unlock(&clone_lock
);
2895 /* this stack is the equivalent of the kernel stack associated with a
2897 #define NEW_STACK_SIZE 8192
2899 static int clone_func(void *arg
)
2901 CPUState
*env
= arg
;
2908 /* do_fork() Must return host values and target errnos (unlike most
2909 do_*() functions). */
2910 static int do_fork(CPUState
*env
, unsigned int flags
, abi_ulong newsp
,
2911 abi_ulong parent_tidptr
, target_ulong newtls
,
2912 abi_ulong child_tidptr
)
2918 #if defined(USE_NPTL)
2919 unsigned int nptl_flags
;
2923 /* Emulate vfork() with fork() */
2924 if (flags
& CLONE_VFORK
)
2925 flags
&= ~(CLONE_VFORK
| CLONE_VM
);
2927 if (flags
& CLONE_VM
) {
2928 #if defined(USE_NPTL)
2929 new_thread_info info
;
2930 pthread_attr_t attr
;
2932 ts
= qemu_mallocz(sizeof(TaskState
) + NEW_STACK_SIZE
);
2933 init_task_state(ts
);
2934 new_stack
= ts
->stack
;
2935 /* we create a new CPU instance. */
2936 new_env
= cpu_copy(env
);
2937 /* Init regs that differ from the parent. */
2938 cpu_clone_regs(new_env
, newsp
);
2939 new_env
->opaque
= ts
;
2940 #if defined(USE_NPTL)
2942 flags
&= ~CLONE_NPTL_FLAGS2
;
2944 if (nptl_flags
& CLONE_CHILD_CLEARTID
) {
2945 ts
->child_tidptr
= child_tidptr
;
2948 if (nptl_flags
& CLONE_SETTLS
)
2949 cpu_set_tls (new_env
, newtls
);
2951 /* Grab a mutex so that thread setup appears atomic. */
2952 pthread_mutex_lock(&clone_lock
);
2954 memset(&info
, 0, sizeof(info
));
2955 pthread_mutex_init(&info
.mutex
, NULL
);
2956 pthread_mutex_lock(&info
.mutex
);
2957 pthread_cond_init(&info
.cond
, NULL
);
2959 if (nptl_flags
& CLONE_CHILD_SETTID
)
2960 info
.child_tidptr
= child_tidptr
;
2961 if (nptl_flags
& CLONE_PARENT_SETTID
)
2962 info
.parent_tidptr
= parent_tidptr
;
2964 ret
= pthread_attr_init(&attr
);
2965 ret
= pthread_attr_setstack(&attr
, new_stack
, NEW_STACK_SIZE
);
2966 /* It is not safe to deliver signals until the child has finished
2967 initializing, so temporarily block all signals. */
2968 sigfillset(&sigmask
);
2969 sigprocmask(SIG_BLOCK
, &sigmask
, &info
.sigmask
);
2971 ret
= pthread_create(&info
.thread
, &attr
, clone_func
, &info
);
2972 /* TODO: Free new CPU state if thread creation failed. */
2974 sigprocmask(SIG_SETMASK
, &info
.sigmask
, NULL
);
2975 pthread_attr_destroy(&attr
);
2977 /* Wait for the child to initialize. */
2978 pthread_cond_wait(&info
.cond
, &info
.mutex
);
2980 if (flags
& CLONE_PARENT_SETTID
)
2981 put_user_u32(ret
, parent_tidptr
);
2985 pthread_mutex_unlock(&info
.mutex
);
2986 pthread_cond_destroy(&info
.cond
);
2987 pthread_mutex_destroy(&info
.mutex
);
2988 pthread_mutex_unlock(&clone_lock
);
2990 if (flags
& CLONE_NPTL_FLAGS2
)
2992 /* This is probably going to die very quickly, but do it anyway. */
2994 ret
= __clone2(clone_func
, new_stack
+ NEW_STACK_SIZE
, flags
, new_env
);
2996 ret
= clone(clone_func
, new_stack
+ NEW_STACK_SIZE
, flags
, new_env
);
3000 /* if no CLONE_VM, we consider it is a fork */
3001 if ((flags
& ~(CSIGNAL
| CLONE_NPTL_FLAGS2
)) != 0)
3006 /* Child Process. */
3007 cpu_clone_regs(env
, newsp
);
3009 #if defined(USE_NPTL)
3010 /* There is a race condition here. The parent process could
3011 theoretically read the TID in the child process before the child
3012 tid is set. This would require using either ptrace
3013 (not implemented) or having *_tidptr to point at a shared memory
3014 mapping. We can't repeat the spinlock hack used above because
3015 the child process gets its own copy of the lock. */
3016 if (flags
& CLONE_CHILD_SETTID
)
3017 put_user_u32(gettid(), child_tidptr
);
3018 if (flags
& CLONE_PARENT_SETTID
)
3019 put_user_u32(gettid(), parent_tidptr
);
3020 ts
= (TaskState
*)env
->opaque
;
3021 if (flags
& CLONE_SETTLS
)
3022 cpu_set_tls (env
, newtls
);
3023 if (flags
& CLONE_CHILD_CLEARTID
)
3024 ts
->child_tidptr
= child_tidptr
;
3033 static abi_long
do_fcntl(int fd
, int cmd
, abi_ulong arg
)
3036 struct target_flock
*target_fl
;
3037 struct flock64 fl64
;
3038 struct target_flock64
*target_fl64
;
3042 case TARGET_F_GETLK
:
3043 if (!lock_user_struct(VERIFY_READ
, target_fl
, arg
, 1))
3044 return -TARGET_EFAULT
;
3045 fl
.l_type
= tswap16(target_fl
->l_type
);
3046 fl
.l_whence
= tswap16(target_fl
->l_whence
);
3047 fl
.l_start
= tswapl(target_fl
->l_start
);
3048 fl
.l_len
= tswapl(target_fl
->l_len
);
3049 fl
.l_pid
= tswapl(target_fl
->l_pid
);
3050 unlock_user_struct(target_fl
, arg
, 0);
3051 ret
= get_errno(fcntl(fd
, cmd
, &fl
));
3053 if (!lock_user_struct(VERIFY_WRITE
, target_fl
, arg
, 0))
3054 return -TARGET_EFAULT
;
3055 target_fl
->l_type
= tswap16(fl
.l_type
);
3056 target_fl
->l_whence
= tswap16(fl
.l_whence
);
3057 target_fl
->l_start
= tswapl(fl
.l_start
);
3058 target_fl
->l_len
= tswapl(fl
.l_len
);
3059 target_fl
->l_pid
= tswapl(fl
.l_pid
);
3060 unlock_user_struct(target_fl
, arg
, 1);
3064 case TARGET_F_SETLK
:
3065 case TARGET_F_SETLKW
:
3066 if (!lock_user_struct(VERIFY_READ
, target_fl
, arg
, 1))
3067 return -TARGET_EFAULT
;
3068 fl
.l_type
= tswap16(target_fl
->l_type
);
3069 fl
.l_whence
= tswap16(target_fl
->l_whence
);
3070 fl
.l_start
= tswapl(target_fl
->l_start
);
3071 fl
.l_len
= tswapl(target_fl
->l_len
);
3072 fl
.l_pid
= tswapl(target_fl
->l_pid
);
3073 unlock_user_struct(target_fl
, arg
, 0);
3074 ret
= get_errno(fcntl(fd
, cmd
, &fl
));
3077 case TARGET_F_GETLK64
:
3078 if (!lock_user_struct(VERIFY_READ
, target_fl64
, arg
, 1))
3079 return -TARGET_EFAULT
;
3080 fl64
.l_type
= tswap16(target_fl64
->l_type
) >> 1;
3081 fl64
.l_whence
= tswap16(target_fl64
->l_whence
);
3082 fl64
.l_start
= tswapl(target_fl64
->l_start
);
3083 fl64
.l_len
= tswapl(target_fl64
->l_len
);
3084 fl64
.l_pid
= tswap16(target_fl64
->l_pid
);
3085 unlock_user_struct(target_fl64
, arg
, 0);
3086 ret
= get_errno(fcntl(fd
, cmd
>> 1, &fl64
));
3088 if (!lock_user_struct(VERIFY_WRITE
, target_fl64
, arg
, 0))
3089 return -TARGET_EFAULT
;
3090 target_fl64
->l_type
= tswap16(fl64
.l_type
) >> 1;
3091 target_fl64
->l_whence
= tswap16(fl64
.l_whence
);
3092 target_fl64
->l_start
= tswapl(fl64
.l_start
);
3093 target_fl64
->l_len
= tswapl(fl64
.l_len
);
3094 target_fl64
->l_pid
= tswapl(fl64
.l_pid
);
3095 unlock_user_struct(target_fl64
, arg
, 1);
3098 case TARGET_F_SETLK64
:
3099 case TARGET_F_SETLKW64
:
3100 if (!lock_user_struct(VERIFY_READ
, target_fl64
, arg
, 1))
3101 return -TARGET_EFAULT
;
3102 fl64
.l_type
= tswap16(target_fl64
->l_type
) >> 1;
3103 fl64
.l_whence
= tswap16(target_fl64
->l_whence
);
3104 fl64
.l_start
= tswapl(target_fl64
->l_start
);
3105 fl64
.l_len
= tswapl(target_fl64
->l_len
);
3106 fl64
.l_pid
= tswap16(target_fl64
->l_pid
);
3107 unlock_user_struct(target_fl64
, arg
, 0);
3108 ret
= get_errno(fcntl(fd
, cmd
>> 1, &fl64
));
3112 ret
= get_errno(fcntl(fd
, cmd
, arg
));
3114 ret
= host_to_target_bitmask(ret
, fcntl_flags_tbl
);
3119 ret
= get_errno(fcntl(fd
, cmd
, target_to_host_bitmask(arg
, fcntl_flags_tbl
)));
3123 ret
= get_errno(fcntl(fd
, cmd
, arg
));
3131 static inline int high2lowuid(int uid
)
3139 static inline int high2lowgid(int gid
)
3147 static inline int low2highuid(int uid
)
3149 if ((int16_t)uid
== -1)
3155 static inline int low2highgid(int gid
)
3157 if ((int16_t)gid
== -1)
3163 #endif /* USE_UID16 */
3165 void syscall_init(void)
3168 const argtype
*arg_type
;
3172 #define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3173 #define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3174 #include "syscall_types.h"
3176 #undef STRUCT_SPECIAL
3178 /* we patch the ioctl size if necessary. We rely on the fact that
3179 no ioctl has all the bits at '1' in the size field */
3181 while (ie
->target_cmd
!= 0) {
3182 if (((ie
->target_cmd
>> TARGET_IOC_SIZESHIFT
) & TARGET_IOC_SIZEMASK
) ==
3183 TARGET_IOC_SIZEMASK
) {
3184 arg_type
= ie
->arg_type
;
3185 if (arg_type
[0] != TYPE_PTR
) {
3186 fprintf(stderr
, "cannot patch size for ioctl 0x%x\n",
3191 size
= thunk_type_size(arg_type
, 0);
3192 ie
->target_cmd
= (ie
->target_cmd
&
3193 ~(TARGET_IOC_SIZEMASK
<< TARGET_IOC_SIZESHIFT
)) |
3194 (size
<< TARGET_IOC_SIZESHIFT
);
3197 /* Build target_to_host_errno_table[] table from
3198 * host_to_target_errno_table[]. */
3199 for (i
=0; i
< ERRNO_TABLE_SIZE
; i
++)
3200 target_to_host_errno_table
[host_to_target_errno_table
[i
]] = i
;
3202 /* automatic consistency check if same arch */
3203 #if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
3204 (defined(__x86_64__) && defined(TARGET_X86_64))
3205 if (unlikely(ie
->target_cmd
!= ie
->host_cmd
)) {
3206 fprintf(stderr
, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
3207 ie
->name
, ie
->target_cmd
, ie
->host_cmd
);
3214 #if TARGET_ABI_BITS == 32
3215 static inline uint64_t target_offset64(uint32_t word0
, uint32_t word1
)
3217 #ifdef TARGET_WORDS_BIGENDIAN
3218 return ((uint64_t)word0
<< 32) | word1
;
3220 return ((uint64_t)word1
<< 32) | word0
;
3223 #else /* TARGET_ABI_BITS == 32 */
3224 static inline uint64_t target_offset64(uint64_t word0
, uint64_t word1
)
3228 #endif /* TARGET_ABI_BITS != 32 */
3230 #ifdef TARGET_NR_truncate64
3231 static inline abi_long
target_truncate64(void *cpu_env
, const char *arg1
,
3237 if (((CPUARMState
*)cpu_env
)->eabi
)
3243 return get_errno(truncate64(arg1
, target_offset64(arg2
, arg3
)));
3247 #ifdef TARGET_NR_ftruncate64
3248 static inline abi_long
target_ftruncate64(void *cpu_env
, abi_long arg1
,
3254 if (((CPUARMState
*)cpu_env
)->eabi
)
3260 return get_errno(ftruncate64(arg1
, target_offset64(arg2
, arg3
)));
3264 static inline abi_long
target_to_host_timespec(struct timespec
*host_ts
,
3265 abi_ulong target_addr
)
3267 struct target_timespec
*target_ts
;
3269 if (!lock_user_struct(VERIFY_READ
, target_ts
, target_addr
, 1))
3270 return -TARGET_EFAULT
;
3271 host_ts
->tv_sec
= tswapl(target_ts
->tv_sec
);
3272 host_ts
->tv_nsec
= tswapl(target_ts
->tv_nsec
);
3273 unlock_user_struct(target_ts
, target_addr
, 0);
3277 static inline abi_long
host_to_target_timespec(abi_ulong target_addr
,
3278 struct timespec
*host_ts
)
3280 struct target_timespec
*target_ts
;
3282 if (!lock_user_struct(VERIFY_WRITE
, target_ts
, target_addr
, 0))
3283 return -TARGET_EFAULT
;
3284 target_ts
->tv_sec
= tswapl(host_ts
->tv_sec
);
3285 target_ts
->tv_nsec
= tswapl(host_ts
->tv_nsec
);
3286 unlock_user_struct(target_ts
, target_addr
, 1);
3290 #if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
3291 static inline abi_long
host_to_target_stat64(void *cpu_env
,
3292 abi_ulong target_addr
,
3293 struct stat
*host_st
)
3296 if (((CPUARMState
*)cpu_env
)->eabi
) {
3297 struct target_eabi_stat64
*target_st
;
3299 if (!lock_user_struct(VERIFY_WRITE
, target_st
, target_addr
, 0))
3300 return -TARGET_EFAULT
;
3301 memset(target_st
, 0, sizeof(struct target_eabi_stat64
));
3302 __put_user(host_st
->st_dev
, &target_st
->st_dev
);
3303 __put_user(host_st
->st_ino
, &target_st
->st_ino
);
3304 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3305 __put_user(host_st
->st_ino
, &target_st
->__st_ino
);
3307 __put_user(host_st
->st_mode
, &target_st
->st_mode
);
3308 __put_user(host_st
->st_nlink
, &target_st
->st_nlink
);
3309 __put_user(host_st
->st_uid
, &target_st
->st_uid
);
3310 __put_user(host_st
->st_gid
, &target_st
->st_gid
);
3311 __put_user(host_st
->st_rdev
, &target_st
->st_rdev
);
3312 __put_user(host_st
->st_size
, &target_st
->st_size
);
3313 __put_user(host_st
->st_blksize
, &target_st
->st_blksize
);
3314 __put_user(host_st
->st_blocks
, &target_st
->st_blocks
);
3315 __put_user(host_st
->st_atime
, &target_st
->target_st_atime
);
3316 __put_user(host_st
->st_mtime
, &target_st
->target_st_mtime
);
3317 __put_user(host_st
->st_ctime
, &target_st
->target_st_ctime
);
3318 unlock_user_struct(target_st
, target_addr
, 1);
3322 #if TARGET_LONG_BITS == 64
3323 struct target_stat
*target_st
;
3325 struct target_stat64
*target_st
;
3328 if (!lock_user_struct(VERIFY_WRITE
, target_st
, target_addr
, 0))
3329 return -TARGET_EFAULT
;
3330 memset(target_st
, 0, sizeof(*target_st
));
3331 __put_user(host_st
->st_dev
, &target_st
->st_dev
);
3332 __put_user(host_st
->st_ino
, &target_st
->st_ino
);
3333 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3334 __put_user(host_st
->st_ino
, &target_st
->__st_ino
);
3336 __put_user(host_st
->st_mode
, &target_st
->st_mode
);
3337 __put_user(host_st
->st_nlink
, &target_st
->st_nlink
);
3338 __put_user(host_st
->st_uid
, &target_st
->st_uid
);
3339 __put_user(host_st
->st_gid
, &target_st
->st_gid
);
3340 __put_user(host_st
->st_rdev
, &target_st
->st_rdev
);
3341 /* XXX: better use of kernel struct */
3342 __put_user(host_st
->st_size
, &target_st
->st_size
);
3343 __put_user(host_st
->st_blksize
, &target_st
->st_blksize
);
3344 __put_user(host_st
->st_blocks
, &target_st
->st_blocks
);
3345 __put_user(host_st
->st_atime
, &target_st
->target_st_atime
);
3346 __put_user(host_st
->st_mtime
, &target_st
->target_st_mtime
);
3347 __put_user(host_st
->st_ctime
, &target_st
->target_st_ctime
);
3348 unlock_user_struct(target_st
, target_addr
, 1);
3355 #if defined(USE_NPTL)
3356 /* ??? Using host futex calls even when target atomic operations
3357 are not really atomic probably breaks things. However implementing
3358 futexes locally would make futexes shared between multiple processes
3359 tricky. However they're probably useless because guest atomic
3360 operations won't work either. */
3361 static int do_futex(target_ulong uaddr
, int op
, int val
, target_ulong timeout
,
3362 target_ulong uaddr2
, int val3
)
3364 struct timespec ts
, *pts
;
3366 /* ??? We assume FUTEX_* constants are the same on both host
3372 target_to_host_timespec(pts
, timeout
);
3376 return get_errno(sys_futex(g2h(uaddr
), FUTEX_WAIT
, tswap32(val
),
3379 return get_errno(sys_futex(g2h(uaddr
), FUTEX_WAKE
, val
, NULL
, NULL
, 0));
3381 return get_errno(sys_futex(g2h(uaddr
), FUTEX_FD
, val
, NULL
, NULL
, 0));
3383 return get_errno(sys_futex(g2h(uaddr
), FUTEX_REQUEUE
, val
,
3384 NULL
, g2h(uaddr2
), 0));
3385 case FUTEX_CMP_REQUEUE
:
3386 return get_errno(sys_futex(g2h(uaddr
), FUTEX_CMP_REQUEUE
, val
,
3387 NULL
, g2h(uaddr2
), tswap32(val3
)));
3389 return -TARGET_ENOSYS
;
3394 int get_osversion(void)
3396 static int osversion
;
3397 struct new_utsname buf
;
3402 if (qemu_uname_release
&& *qemu_uname_release
) {
3403 s
= qemu_uname_release
;
3405 if (sys_uname(&buf
))
3410 for (i
= 0; i
< 3; i
++) {
3412 while (*s
>= '0' && *s
<= '9') {
3417 tmp
= (tmp
<< 8) + n
;
3425 /* do_syscall() should always have a single exit point at the end so
3426 that actions, such as logging of syscall results, can be performed.
3427 All errnos that do_syscall() returns must be -TARGET_<errcode>. */
3428 abi_long
do_syscall(void *cpu_env
, int num
, abi_long arg1
,
3429 abi_long arg2
, abi_long arg3
, abi_long arg4
,
3430 abi_long arg5
, abi_long arg6
)
3438 gemu_log("syscall %d", num
);
3441 print_syscall(num
, arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
3444 case TARGET_NR_exit
:
3446 /* In old applications this may be used to implement _exit(2).
3447 However in threaded applictions it is used for thread termination,
3448 and _exit_group is used for application termination.
3449 Do thread termination if we have more then one thread. */
3450 /* FIXME: This probably breaks if a signal arrives. We should probably
3451 be disabling signals. */
3452 if (first_cpu
->next_cpu
) {
3459 while (p
&& p
!= (CPUState
*)cpu_env
) {
3460 lastp
= &p
->next_cpu
;
3463 /* If we didn't find the CPU for this thread then something is
3467 /* Remove the CPU from the list. */
3468 *lastp
= p
->next_cpu
;
3470 TaskState
*ts
= ((CPUState
*)cpu_env
)->opaque
;
3471 if (ts
->child_tidptr
) {
3472 put_user_u32(0, ts
->child_tidptr
);
3473 sys_futex(g2h(ts
->child_tidptr
), FUTEX_WAKE
, INT_MAX
,
3476 /* TODO: Free CPU state. */
3483 gdb_exit(cpu_env
, arg1
);
3485 ret
= 0; /* avoid warning */
3487 case TARGET_NR_read
:
3491 if (!(p
= lock_user(VERIFY_WRITE
, arg2
, arg3
, 0)))
3493 ret
= get_errno(read(arg1
, p
, arg3
));
3494 unlock_user(p
, arg2
, ret
);
3497 case TARGET_NR_write
:
3498 if (!(p
= lock_user(VERIFY_READ
, arg2
, arg3
, 1)))
3500 ret
= get_errno(write(arg1
, p
, arg3
));
3501 unlock_user(p
, arg2
, 0);
3503 case TARGET_NR_open
:
3504 if (!(p
= lock_user_string(arg1
)))
3506 ret
= get_errno(open(path(p
),
3507 target_to_host_bitmask(arg2
, fcntl_flags_tbl
),
3509 unlock_user(p
, arg1
, 0);
3511 #if defined(TARGET_NR_openat) && defined(__NR_openat)
3512 case TARGET_NR_openat
:
3513 if (!(p
= lock_user_string(arg2
)))
3515 ret
= get_errno(sys_openat(arg1
,
3517 target_to_host_bitmask(arg3
, fcntl_flags_tbl
),
3519 unlock_user(p
, arg2
, 0);
3522 case TARGET_NR_close
:
3523 ret
= get_errno(close(arg1
));
3528 case TARGET_NR_fork
:
3529 ret
= get_errno(do_fork(cpu_env
, SIGCHLD
, 0, 0, 0, 0));
3531 #ifdef TARGET_NR_waitpid
3532 case TARGET_NR_waitpid
:
3535 ret
= get_errno(waitpid(arg1
, &status
, arg3
));
3536 if (!is_error(ret
) && arg2
3537 && put_user_s32(status
, arg2
))
3542 #ifdef TARGET_NR_waitid
3543 case TARGET_NR_waitid
:
3547 ret
= get_errno(waitid(arg1
, arg2
, &info
, arg4
));
3548 if (!is_error(ret
) && arg3
&& info
.si_pid
!= 0) {
3549 if (!(p
= lock_user(VERIFY_WRITE
, arg3
, sizeof(target_siginfo_t
), 0)))
3551 host_to_target_siginfo(p
, &info
);
3552 unlock_user(p
, arg3
, sizeof(target_siginfo_t
));
3557 #ifdef TARGET_NR_creat /* not on alpha */
3558 case TARGET_NR_creat
:
3559 if (!(p
= lock_user_string(arg1
)))
3561 ret
= get_errno(creat(p
, arg2
));
3562 unlock_user(p
, arg1
, 0);
3565 case TARGET_NR_link
:
3568 p
= lock_user_string(arg1
);
3569 p2
= lock_user_string(arg2
);
3571 ret
= -TARGET_EFAULT
;
3573 ret
= get_errno(link(p
, p2
));
3574 unlock_user(p2
, arg2
, 0);
3575 unlock_user(p
, arg1
, 0);
3578 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
3579 case TARGET_NR_linkat
:
3584 p
= lock_user_string(arg2
);
3585 p2
= lock_user_string(arg4
);
3587 ret
= -TARGET_EFAULT
;
3589 ret
= get_errno(sys_linkat(arg1
, p
, arg3
, p2
, arg5
));
3590 unlock_user(p
, arg2
, 0);
3591 unlock_user(p2
, arg4
, 0);
3595 case TARGET_NR_unlink
:
3596 if (!(p
= lock_user_string(arg1
)))
3598 ret
= get_errno(unlink(p
));
3599 unlock_user(p
, arg1
, 0);
3601 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
3602 case TARGET_NR_unlinkat
:
3603 if (!(p
= lock_user_string(arg2
)))
3605 ret
= get_errno(sys_unlinkat(arg1
, p
, arg3
));
3606 unlock_user(p
, arg2
, 0);
3609 case TARGET_NR_execve
:
3611 char **argp
, **envp
;
3614 abi_ulong guest_argp
;
3615 abi_ulong guest_envp
;
3621 for (gp
= guest_argp
; gp
; gp
+= sizeof(abi_ulong
)) {
3622 if (get_user_ual(addr
, gp
))
3630 for (gp
= guest_envp
; gp
; gp
+= sizeof(abi_ulong
)) {
3631 if (get_user_ual(addr
, gp
))
3638 argp
= alloca((argc
+ 1) * sizeof(void *));
3639 envp
= alloca((envc
+ 1) * sizeof(void *));
3641 for (gp
= guest_argp
, q
= argp
; gp
;
3642 gp
+= sizeof(abi_ulong
), q
++) {
3643 if (get_user_ual(addr
, gp
))
3647 if (!(*q
= lock_user_string(addr
)))
3652 for (gp
= guest_envp
, q
= envp
; gp
;
3653 gp
+= sizeof(abi_ulong
), q
++) {
3654 if (get_user_ual(addr
, gp
))
3658 if (!(*q
= lock_user_string(addr
)))
3663 if (!(p
= lock_user_string(arg1
)))
3665 ret
= get_errno(execve(p
, argp
, envp
));
3666 unlock_user(p
, arg1
, 0);
3671 ret
= -TARGET_EFAULT
;
3674 for (gp
= guest_argp
, q
= argp
; *q
;
3675 gp
+= sizeof(abi_ulong
), q
++) {
3676 if (get_user_ual(addr
, gp
)
3679 unlock_user(*q
, addr
, 0);
3681 for (gp
= guest_envp
, q
= envp
; *q
;
3682 gp
+= sizeof(abi_ulong
), q
++) {
3683 if (get_user_ual(addr
, gp
)
3686 unlock_user(*q
, addr
, 0);
3690 case TARGET_NR_chdir
:
3691 if (!(p
= lock_user_string(arg1
)))
3693 ret
= get_errno(chdir(p
));
3694 unlock_user(p
, arg1
, 0);
3696 #ifdef TARGET_NR_time
3697 case TARGET_NR_time
:
3700 ret
= get_errno(time(&host_time
));
3703 && put_user_sal(host_time
, arg1
))
3708 case TARGET_NR_mknod
:
3709 if (!(p
= lock_user_string(arg1
)))
3711 ret
= get_errno(mknod(p
, arg2
, arg3
));
3712 unlock_user(p
, arg1
, 0);
3714 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
3715 case TARGET_NR_mknodat
:
3716 if (!(p
= lock_user_string(arg2
)))
3718 ret
= get_errno(sys_mknodat(arg1
, p
, arg3
, arg4
));
3719 unlock_user(p
, arg2
, 0);
3722 case TARGET_NR_chmod
:
3723 if (!(p
= lock_user_string(arg1
)))
3725 ret
= get_errno(chmod(p
, arg2
));
3726 unlock_user(p
, arg1
, 0);
3728 #ifdef TARGET_NR_break
3729 case TARGET_NR_break
:
3732 #ifdef TARGET_NR_oldstat
3733 case TARGET_NR_oldstat
:
3736 case TARGET_NR_lseek
:
3737 ret
= get_errno(lseek(arg1
, arg2
, arg3
));
3739 #ifdef TARGET_NR_getxpid
3740 case TARGET_NR_getxpid
:
3742 case TARGET_NR_getpid
:
3744 ret
= get_errno(getpid());
3746 case TARGET_NR_mount
:
3748 /* need to look at the data field */
3750 p
= lock_user_string(arg1
);
3751 p2
= lock_user_string(arg2
);
3752 p3
= lock_user_string(arg3
);
3753 if (!p
|| !p2
|| !p3
)
3754 ret
= -TARGET_EFAULT
;
3756 /* FIXME - arg5 should be locked, but it isn't clear how to
3757 * do that since it's not guaranteed to be a NULL-terminated
3760 ret
= get_errno(mount(p
, p2
, p3
, (unsigned long)arg4
, g2h(arg5
)));
3761 unlock_user(p
, arg1
, 0);
3762 unlock_user(p2
, arg2
, 0);
3763 unlock_user(p3
, arg3
, 0);
3766 #ifdef TARGET_NR_umount
3767 case TARGET_NR_umount
:
3768 if (!(p
= lock_user_string(arg1
)))
3770 ret
= get_errno(umount(p
));
3771 unlock_user(p
, arg1
, 0);
3774 #ifdef TARGET_NR_stime /* not on alpha */
3775 case TARGET_NR_stime
:
3778 if (get_user_sal(host_time
, arg1
))
3780 ret
= get_errno(stime(&host_time
));
3784 case TARGET_NR_ptrace
:
3786 #ifdef TARGET_NR_alarm /* not on alpha */
3787 case TARGET_NR_alarm
:
3791 #ifdef TARGET_NR_oldfstat
3792 case TARGET_NR_oldfstat
:
3795 #ifdef TARGET_NR_pause /* not on alpha */
3796 case TARGET_NR_pause
:
3797 ret
= get_errno(pause());
3800 #ifdef TARGET_NR_utime
3801 case TARGET_NR_utime
:
3803 struct utimbuf tbuf
, *host_tbuf
;
3804 struct target_utimbuf
*target_tbuf
;
3806 if (!lock_user_struct(VERIFY_READ
, target_tbuf
, arg2
, 1))
3808 tbuf
.actime
= tswapl(target_tbuf
->actime
);
3809 tbuf
.modtime
= tswapl(target_tbuf
->modtime
);
3810 unlock_user_struct(target_tbuf
, arg2
, 0);
3815 if (!(p
= lock_user_string(arg1
)))
3817 ret
= get_errno(utime(p
, host_tbuf
));
3818 unlock_user(p
, arg1
, 0);
3822 case TARGET_NR_utimes
:
3824 struct timeval
*tvp
, tv
[2];
3826 if (copy_from_user_timeval(&tv
[0], arg2
)
3827 || copy_from_user_timeval(&tv
[1],
3828 arg2
+ sizeof(struct target_timeval
)))
3834 if (!(p
= lock_user_string(arg1
)))
3836 ret
= get_errno(utimes(p
, tvp
));
3837 unlock_user(p
, arg1
, 0);
3840 #if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
3841 case TARGET_NR_futimesat
:
3843 struct timeval
*tvp
, tv
[2];
3845 if (copy_from_user_timeval(&tv
[0], arg3
)
3846 || copy_from_user_timeval(&tv
[1],
3847 arg3
+ sizeof(struct target_timeval
)))
3853 if (!(p
= lock_user_string(arg2
)))
3855 ret
= get_errno(sys_futimesat(arg1
, path(p
), tvp
));
3856 unlock_user(p
, arg2
, 0);
3860 #ifdef TARGET_NR_stty
3861 case TARGET_NR_stty
:
3864 #ifdef TARGET_NR_gtty
3865 case TARGET_NR_gtty
:
3868 case TARGET_NR_access
:
3869 if (!(p
= lock_user_string(arg1
)))
3871 ret
= get_errno(access(p
, arg2
));
3872 unlock_user(p
, arg1
, 0);
3874 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
3875 case TARGET_NR_faccessat
:
3876 if (!(p
= lock_user_string(arg2
)))
3878 ret
= get_errno(sys_faccessat(arg1
, p
, arg3
, arg4
));
3879 unlock_user(p
, arg2
, 0);
3882 #ifdef TARGET_NR_nice /* not on alpha */
3883 case TARGET_NR_nice
:
3884 ret
= get_errno(nice(arg1
));
3887 #ifdef TARGET_NR_ftime
3888 case TARGET_NR_ftime
:
3891 case TARGET_NR_sync
:
3895 case TARGET_NR_kill
:
3896 ret
= get_errno(kill(arg1
, target_to_host_signal(arg2
)));
3898 case TARGET_NR_rename
:
3901 p
= lock_user_string(arg1
);
3902 p2
= lock_user_string(arg2
);
3904 ret
= -TARGET_EFAULT
;
3906 ret
= get_errno(rename(p
, p2
));
3907 unlock_user(p2
, arg2
, 0);
3908 unlock_user(p
, arg1
, 0);
3911 #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
3912 case TARGET_NR_renameat
:
3915 p
= lock_user_string(arg2
);
3916 p2
= lock_user_string(arg4
);
3918 ret
= -TARGET_EFAULT
;
3920 ret
= get_errno(sys_renameat(arg1
, p
, arg3
, p2
));
3921 unlock_user(p2
, arg4
, 0);
3922 unlock_user(p
, arg2
, 0);
3926 case TARGET_NR_mkdir
:
3927 if (!(p
= lock_user_string(arg1
)))
3929 ret
= get_errno(mkdir(p
, arg2
));
3930 unlock_user(p
, arg1
, 0);
3932 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
3933 case TARGET_NR_mkdirat
:
3934 if (!(p
= lock_user_string(arg2
)))
3936 ret
= get_errno(sys_mkdirat(arg1
, p
, arg3
));
3937 unlock_user(p
, arg2
, 0);
3940 case TARGET_NR_rmdir
:
3941 if (!(p
= lock_user_string(arg1
)))
3943 ret
= get_errno(rmdir(p
));
3944 unlock_user(p
, arg1
, 0);
3947 ret
= get_errno(dup(arg1
));
3949 case TARGET_NR_pipe
:
3952 ret
= get_errno(pipe(host_pipe
));
3953 if (!is_error(ret
)) {
3954 #if defined(TARGET_MIPS)
3955 CPUMIPSState
*env
= (CPUMIPSState
*)cpu_env
;
3956 env
->active_tc
.gpr
[3] = host_pipe
[1];
3958 #elif defined(TARGET_SH4)
3959 ((CPUSH4State
*)cpu_env
)->gregs
[1] = host_pipe
[1];
3962 if (put_user_s32(host_pipe
[0], arg1
)
3963 || put_user_s32(host_pipe
[1], arg1
+ sizeof(host_pipe
[0])))
3969 case TARGET_NR_times
:
3971 struct target_tms
*tmsp
;
3973 ret
= get_errno(times(&tms
));
3975 tmsp
= lock_user(VERIFY_WRITE
, arg1
, sizeof(struct target_tms
), 0);
3978 tmsp
->tms_utime
= tswapl(host_to_target_clock_t(tms
.tms_utime
));
3979 tmsp
->tms_stime
= tswapl(host_to_target_clock_t(tms
.tms_stime
));
3980 tmsp
->tms_cutime
= tswapl(host_to_target_clock_t(tms
.tms_cutime
));
3981 tmsp
->tms_cstime
= tswapl(host_to_target_clock_t(tms
.tms_cstime
));
3984 ret
= host_to_target_clock_t(ret
);
3987 #ifdef TARGET_NR_prof
3988 case TARGET_NR_prof
:
3991 #ifdef TARGET_NR_signal
3992 case TARGET_NR_signal
:
3995 case TARGET_NR_acct
:
3997 ret
= get_errno(acct(NULL
));
3999 if (!(p
= lock_user_string(arg1
)))
4001 ret
= get_errno(acct(path(p
)));
4002 unlock_user(p
, arg1
, 0);
4005 #ifdef TARGET_NR_umount2 /* not on alpha */
4006 case TARGET_NR_umount2
:
4007 if (!(p
= lock_user_string(arg1
)))
4009 ret
= get_errno(umount2(p
, arg2
));
4010 unlock_user(p
, arg1
, 0);
4013 #ifdef TARGET_NR_lock
4014 case TARGET_NR_lock
:
4017 case TARGET_NR_ioctl
:
4018 ret
= do_ioctl(arg1
, arg2
, arg3
);
4020 case TARGET_NR_fcntl
:
4021 ret
= do_fcntl(arg1
, arg2
, arg3
);
4023 #ifdef TARGET_NR_mpx
4027 case TARGET_NR_setpgid
:
4028 ret
= get_errno(setpgid(arg1
, arg2
));
4030 #ifdef TARGET_NR_ulimit
4031 case TARGET_NR_ulimit
:
4034 #ifdef TARGET_NR_oldolduname
4035 case TARGET_NR_oldolduname
:
4038 case TARGET_NR_umask
:
4039 ret
= get_errno(umask(arg1
));
4041 case TARGET_NR_chroot
:
4042 if (!(p
= lock_user_string(arg1
)))
4044 ret
= get_errno(chroot(p
));
4045 unlock_user(p
, arg1
, 0);
4047 case TARGET_NR_ustat
:
4049 case TARGET_NR_dup2
:
4050 ret
= get_errno(dup2(arg1
, arg2
));
4052 #ifdef TARGET_NR_getppid /* not on alpha */
4053 case TARGET_NR_getppid
:
4054 ret
= get_errno(getppid());
4057 case TARGET_NR_getpgrp
:
4058 ret
= get_errno(getpgrp());
4060 case TARGET_NR_setsid
:
4061 ret
= get_errno(setsid());
4063 #ifdef TARGET_NR_sigaction
4064 case TARGET_NR_sigaction
:
4066 #if !defined(TARGET_MIPS)
4067 struct target_old_sigaction
*old_act
;
4068 struct target_sigaction act
, oact
, *pact
;
4070 if (!lock_user_struct(VERIFY_READ
, old_act
, arg2
, 1))
4072 act
._sa_handler
= old_act
->_sa_handler
;
4073 target_siginitset(&act
.sa_mask
, old_act
->sa_mask
);
4074 act
.sa_flags
= old_act
->sa_flags
;
4075 act
.sa_restorer
= old_act
->sa_restorer
;
4076 unlock_user_struct(old_act
, arg2
, 0);
4081 ret
= get_errno(do_sigaction(arg1
, pact
, &oact
));
4082 if (!is_error(ret
) && arg3
) {
4083 if (!lock_user_struct(VERIFY_WRITE
, old_act
, arg3
, 0))
4085 old_act
->_sa_handler
= oact
._sa_handler
;
4086 old_act
->sa_mask
= oact
.sa_mask
.sig
[0];
4087 old_act
->sa_flags
= oact
.sa_flags
;
4088 old_act
->sa_restorer
= oact
.sa_restorer
;
4089 unlock_user_struct(old_act
, arg3
, 1);
4092 struct target_sigaction act
, oact
, *pact
, *old_act
;
4095 if (!lock_user_struct(VERIFY_READ
, old_act
, arg2
, 1))
4097 act
._sa_handler
= old_act
->_sa_handler
;
4098 target_siginitset(&act
.sa_mask
, old_act
->sa_mask
.sig
[0]);
4099 act
.sa_flags
= old_act
->sa_flags
;
4100 unlock_user_struct(old_act
, arg2
, 0);
4106 ret
= get_errno(do_sigaction(arg1
, pact
, &oact
));
4108 if (!is_error(ret
) && arg3
) {
4109 if (!lock_user_struct(VERIFY_WRITE
, old_act
, arg3
, 0))
4111 old_act
->_sa_handler
= oact
._sa_handler
;
4112 old_act
->sa_flags
= oact
.sa_flags
;
4113 old_act
->sa_mask
.sig
[0] = oact
.sa_mask
.sig
[0];
4114 old_act
->sa_mask
.sig
[1] = 0;
4115 old_act
->sa_mask
.sig
[2] = 0;
4116 old_act
->sa_mask
.sig
[3] = 0;
4117 unlock_user_struct(old_act
, arg3
, 1);
4123 case TARGET_NR_rt_sigaction
:
4125 struct target_sigaction
*act
;
4126 struct target_sigaction
*oact
;
4129 if (!lock_user_struct(VERIFY_READ
, act
, arg2
, 1))
4134 if (!lock_user_struct(VERIFY_WRITE
, oact
, arg3
, 0)) {
4135 ret
= -TARGET_EFAULT
;
4136 goto rt_sigaction_fail
;
4140 ret
= get_errno(do_sigaction(arg1
, act
, oact
));
4143 unlock_user_struct(act
, arg2
, 0);
4145 unlock_user_struct(oact
, arg3
, 1);
4148 #ifdef TARGET_NR_sgetmask /* not on alpha */
4149 case TARGET_NR_sgetmask
:
4152 abi_ulong target_set
;
4153 sigprocmask(0, NULL
, &cur_set
);
4154 host_to_target_old_sigset(&target_set
, &cur_set
);
4159 #ifdef TARGET_NR_ssetmask /* not on alpha */
4160 case TARGET_NR_ssetmask
:
4162 sigset_t set
, oset
, cur_set
;
4163 abi_ulong target_set
= arg1
;
4164 sigprocmask(0, NULL
, &cur_set
);
4165 target_to_host_old_sigset(&set
, &target_set
);
4166 sigorset(&set
, &set
, &cur_set
);
4167 sigprocmask(SIG_SETMASK
, &set
, &oset
);
4168 host_to_target_old_sigset(&target_set
, &oset
);
4173 #ifdef TARGET_NR_sigprocmask
4174 case TARGET_NR_sigprocmask
:
4177 sigset_t set
, oldset
, *set_ptr
;
4181 case TARGET_SIG_BLOCK
:
4184 case TARGET_SIG_UNBLOCK
:
4187 case TARGET_SIG_SETMASK
:
4191 ret
= -TARGET_EINVAL
;
4194 if (!(p
= lock_user(VERIFY_READ
, arg2
, sizeof(target_sigset_t
), 1)))
4196 target_to_host_old_sigset(&set
, p
);
4197 unlock_user(p
, arg2
, 0);
4203 ret
= get_errno(sigprocmask(arg1
, set_ptr
, &oldset
));
4204 if (!is_error(ret
) && arg3
) {
4205 if (!(p
= lock_user(VERIFY_WRITE
, arg3
, sizeof(target_sigset_t
), 0)))
4207 host_to_target_old_sigset(p
, &oldset
);
4208 unlock_user(p
, arg3
, sizeof(target_sigset_t
));
4213 case TARGET_NR_rt_sigprocmask
:
4216 sigset_t set
, oldset
, *set_ptr
;
4220 case TARGET_SIG_BLOCK
:
4223 case TARGET_SIG_UNBLOCK
:
4226 case TARGET_SIG_SETMASK
:
4230 ret
= -TARGET_EINVAL
;
4233 if (!(p
= lock_user(VERIFY_READ
, arg2
, sizeof(target_sigset_t
), 1)))
4235 target_to_host_sigset(&set
, p
);
4236 unlock_user(p
, arg2
, 0);
4242 ret
= get_errno(sigprocmask(how
, set_ptr
, &oldset
));
4243 if (!is_error(ret
) && arg3
) {
4244 if (!(p
= lock_user(VERIFY_WRITE
, arg3
, sizeof(target_sigset_t
), 0)))
4246 host_to_target_sigset(p
, &oldset
);
4247 unlock_user(p
, arg3
, sizeof(target_sigset_t
));
4251 #ifdef TARGET_NR_sigpending
4252 case TARGET_NR_sigpending
:
4255 ret
= get_errno(sigpending(&set
));
4256 if (!is_error(ret
)) {
4257 if (!(p
= lock_user(VERIFY_WRITE
, arg1
, sizeof(target_sigset_t
), 0)))
4259 host_to_target_old_sigset(p
, &set
);
4260 unlock_user(p
, arg1
, sizeof(target_sigset_t
));
4265 case TARGET_NR_rt_sigpending
:
4268 ret
= get_errno(sigpending(&set
));
4269 if (!is_error(ret
)) {
4270 if (!(p
= lock_user(VERIFY_WRITE
, arg1
, sizeof(target_sigset_t
), 0)))
4272 host_to_target_sigset(p
, &set
);
4273 unlock_user(p
, arg1
, sizeof(target_sigset_t
));
4277 #ifdef TARGET_NR_sigsuspend
4278 case TARGET_NR_sigsuspend
:
4281 if (!(p
= lock_user(VERIFY_READ
, arg1
, sizeof(target_sigset_t
), 1)))
4283 target_to_host_old_sigset(&set
, p
);
4284 unlock_user(p
, arg1
, 0);
4285 ret
= get_errno(sigsuspend(&set
));
4289 case TARGET_NR_rt_sigsuspend
:
4292 if (!(p
= lock_user(VERIFY_READ
, arg1
, sizeof(target_sigset_t
), 1)))
4294 target_to_host_sigset(&set
, p
);
4295 unlock_user(p
, arg1
, 0);
4296 ret
= get_errno(sigsuspend(&set
));
4299 case TARGET_NR_rt_sigtimedwait
:
4302 struct timespec uts
, *puts
;
4305 if (!(p
= lock_user(VERIFY_READ
, arg1
, sizeof(target_sigset_t
), 1)))
4307 target_to_host_sigset(&set
, p
);
4308 unlock_user(p
, arg1
, 0);
4311 target_to_host_timespec(puts
, arg3
);
4315 ret
= get_errno(sigtimedwait(&set
, &uinfo
, puts
));
4316 if (!is_error(ret
) && arg2
) {
4317 if (!(p
= lock_user(VERIFY_WRITE
, arg2
, sizeof(target_siginfo_t
), 0)))
4319 host_to_target_siginfo(p
, &uinfo
);
4320 unlock_user(p
, arg2
, sizeof(target_siginfo_t
));
4324 case TARGET_NR_rt_sigqueueinfo
:
4327 if (!(p
= lock_user(VERIFY_READ
, arg3
, sizeof(target_sigset_t
), 1)))
4329 target_to_host_siginfo(&uinfo
, p
);
4330 unlock_user(p
, arg1
, 0);
4331 ret
= get_errno(sys_rt_sigqueueinfo(arg1
, arg2
, &uinfo
));
4334 #ifdef TARGET_NR_sigreturn
4335 case TARGET_NR_sigreturn
:
4336 /* NOTE: ret is eax, so not transcoding must be done */
4337 ret
= do_sigreturn(cpu_env
);
4340 case TARGET_NR_rt_sigreturn
:
4341 /* NOTE: ret is eax, so not transcoding must be done */
4342 ret
= do_rt_sigreturn(cpu_env
);
4344 case TARGET_NR_sethostname
:
4345 if (!(p
= lock_user_string(arg1
)))
4347 ret
= get_errno(sethostname(p
, arg2
));
4348 unlock_user(p
, arg1
, 0);
4350 case TARGET_NR_setrlimit
:
4352 /* XXX: convert resource ? */
4353 int resource
= arg1
;
4354 struct target_rlimit
*target_rlim
;
4356 if (!lock_user_struct(VERIFY_READ
, target_rlim
, arg2
, 1))
4358 rlim
.rlim_cur
= tswapl(target_rlim
->rlim_cur
);
4359 rlim
.rlim_max
= tswapl(target_rlim
->rlim_max
);
4360 unlock_user_struct(target_rlim
, arg2
, 0);
4361 ret
= get_errno(setrlimit(resource
, &rlim
));
4364 case TARGET_NR_getrlimit
:
4366 /* XXX: convert resource ? */
4367 int resource
= arg1
;
4368 struct target_rlimit
*target_rlim
;
4371 ret
= get_errno(getrlimit(resource
, &rlim
));
4372 if (!is_error(ret
)) {
4373 if (!lock_user_struct(VERIFY_WRITE
, target_rlim
, arg2
, 0))
4375 rlim
.rlim_cur
= tswapl(target_rlim
->rlim_cur
);
4376 rlim
.rlim_max
= tswapl(target_rlim
->rlim_max
);
4377 unlock_user_struct(target_rlim
, arg2
, 1);
4381 case TARGET_NR_getrusage
:
4383 struct rusage rusage
;
4384 ret
= get_errno(getrusage(arg1
, &rusage
));
4385 if (!is_error(ret
)) {
4386 host_to_target_rusage(arg2
, &rusage
);
4390 case TARGET_NR_gettimeofday
:
4393 ret
= get_errno(gettimeofday(&tv
, NULL
));
4394 if (!is_error(ret
)) {
4395 if (copy_to_user_timeval(arg1
, &tv
))
4400 case TARGET_NR_settimeofday
:
4403 if (copy_from_user_timeval(&tv
, arg1
))
4405 ret
= get_errno(settimeofday(&tv
, NULL
));
4408 #ifdef TARGET_NR_select
4409 case TARGET_NR_select
:
4411 struct target_sel_arg_struct
*sel
;
4412 abi_ulong inp
, outp
, exp
, tvp
;
4415 if (!lock_user_struct(VERIFY_READ
, sel
, arg1
, 1))
4417 nsel
= tswapl(sel
->n
);
4418 inp
= tswapl(sel
->inp
);
4419 outp
= tswapl(sel
->outp
);
4420 exp
= tswapl(sel
->exp
);
4421 tvp
= tswapl(sel
->tvp
);
4422 unlock_user_struct(sel
, arg1
, 0);
4423 ret
= do_select(nsel
, inp
, outp
, exp
, tvp
);
4427 case TARGET_NR_symlink
:
4430 p
= lock_user_string(arg1
);
4431 p2
= lock_user_string(arg2
);
4433 ret
= -TARGET_EFAULT
;
4435 ret
= get_errno(symlink(p
, p2
));
4436 unlock_user(p2
, arg2
, 0);
4437 unlock_user(p
, arg1
, 0);
4440 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
4441 case TARGET_NR_symlinkat
:
4444 p
= lock_user_string(arg1
);
4445 p2
= lock_user_string(arg3
);
4447 ret
= -TARGET_EFAULT
;
4449 ret
= get_errno(sys_symlinkat(p
, arg2
, p2
));
4450 unlock_user(p2
, arg3
, 0);
4451 unlock_user(p
, arg1
, 0);
4455 #ifdef TARGET_NR_oldlstat
4456 case TARGET_NR_oldlstat
:
4459 case TARGET_NR_readlink
:
4462 p
= lock_user_string(arg1
);
4463 p2
= lock_user(VERIFY_WRITE
, arg2
, arg3
, 0);
4465 ret
= -TARGET_EFAULT
;
4467 if (strncmp((const char *)p
, "/proc/self/exe", 14) == 0) {
4468 char real
[PATH_MAX
];
4469 temp
= realpath(exec_path
,real
);
4470 ret
= (temp
==NULL
) ? get_errno(-1) : strlen(real
) ;
4471 snprintf((char *)p2
, arg3
, "%s", real
);
4474 ret
= get_errno(readlink(path(p
), p2
, arg3
));
4476 unlock_user(p2
, arg2
, ret
);
4477 unlock_user(p
, arg1
, 0);
4480 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
4481 case TARGET_NR_readlinkat
:
4484 p
= lock_user_string(arg2
);
4485 p2
= lock_user(VERIFY_WRITE
, arg3
, arg4
, 0);
4487 ret
= -TARGET_EFAULT
;
4489 ret
= get_errno(sys_readlinkat(arg1
, path(p
), p2
, arg4
));
4490 unlock_user(p2
, arg3
, ret
);
4491 unlock_user(p
, arg2
, 0);
4495 #ifdef TARGET_NR_uselib
4496 case TARGET_NR_uselib
:
4499 #ifdef TARGET_NR_swapon
4500 case TARGET_NR_swapon
:
4501 if (!(p
= lock_user_string(arg1
)))
4503 ret
= get_errno(swapon(p
, arg2
));
4504 unlock_user(p
, arg1
, 0);
4507 case TARGET_NR_reboot
:
4509 #ifdef TARGET_NR_readdir
4510 case TARGET_NR_readdir
:
4513 #ifdef TARGET_NR_mmap
4514 case TARGET_NR_mmap
:
4515 #if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS)
4518 abi_ulong v1
, v2
, v3
, v4
, v5
, v6
;
4519 if (!(v
= lock_user(VERIFY_READ
, arg1
, 6 * sizeof(abi_ulong
), 1)))
4527 unlock_user(v
, arg1
, 0);
4528 ret
= get_errno(target_mmap(v1
, v2
, v3
,
4529 target_to_host_bitmask(v4
, mmap_flags_tbl
),
4533 ret
= get_errno(target_mmap(arg1
, arg2
, arg3
,
4534 target_to_host_bitmask(arg4
, mmap_flags_tbl
),
4540 #ifdef TARGET_NR_mmap2
4541 case TARGET_NR_mmap2
:
4543 #define MMAP_SHIFT 12
4545 ret
= get_errno(target_mmap(arg1
, arg2
, arg3
,
4546 target_to_host_bitmask(arg4
, mmap_flags_tbl
),
4548 arg6
<< MMAP_SHIFT
));
4551 case TARGET_NR_munmap
:
4552 ret
= get_errno(target_munmap(arg1
, arg2
));
4554 case TARGET_NR_mprotect
:
4555 ret
= get_errno(target_mprotect(arg1
, arg2
, arg3
));
4557 #ifdef TARGET_NR_mremap
4558 case TARGET_NR_mremap
:
4559 ret
= get_errno(target_mremap(arg1
, arg2
, arg3
, arg4
, arg5
));
4562 /* ??? msync/mlock/munlock are broken for softmmu. */
4563 #ifdef TARGET_NR_msync
4564 case TARGET_NR_msync
:
4565 ret
= get_errno(msync(g2h(arg1
), arg2
, arg3
));
4568 #ifdef TARGET_NR_mlock
4569 case TARGET_NR_mlock
:
4570 ret
= get_errno(mlock(g2h(arg1
), arg2
));
4573 #ifdef TARGET_NR_munlock
4574 case TARGET_NR_munlock
:
4575 ret
= get_errno(munlock(g2h(arg1
), arg2
));
4578 #ifdef TARGET_NR_mlockall
4579 case TARGET_NR_mlockall
:
4580 ret
= get_errno(mlockall(arg1
));
4583 #ifdef TARGET_NR_munlockall
4584 case TARGET_NR_munlockall
:
4585 ret
= get_errno(munlockall());
4588 case TARGET_NR_truncate
:
4589 if (!(p
= lock_user_string(arg1
)))
4591 ret
= get_errno(truncate(p
, arg2
));
4592 unlock_user(p
, arg1
, 0);
4594 case TARGET_NR_ftruncate
:
4595 ret
= get_errno(ftruncate(arg1
, arg2
));
4597 case TARGET_NR_fchmod
:
4598 ret
= get_errno(fchmod(arg1
, arg2
));
4600 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
4601 case TARGET_NR_fchmodat
:
4602 if (!(p
= lock_user_string(arg2
)))
4604 ret
= get_errno(sys_fchmodat(arg1
, p
, arg3
, arg4
));
4605 unlock_user(p
, arg2
, 0);
4608 case TARGET_NR_getpriority
:
4609 /* libc does special remapping of the return value of
4610 * sys_getpriority() so it's just easiest to call
4611 * sys_getpriority() directly rather than through libc. */
4612 ret
= sys_getpriority(arg1
, arg2
);
4614 case TARGET_NR_setpriority
:
4615 ret
= get_errno(setpriority(arg1
, arg2
, arg3
));
4617 #ifdef TARGET_NR_profil
4618 case TARGET_NR_profil
:
4621 case TARGET_NR_statfs
:
4622 if (!(p
= lock_user_string(arg1
)))
4624 ret
= get_errno(statfs(path(p
), &stfs
));
4625 unlock_user(p
, arg1
, 0);
4627 if (!is_error(ret
)) {
4628 struct target_statfs
*target_stfs
;
4630 if (!lock_user_struct(VERIFY_WRITE
, target_stfs
, arg2
, 0))
4632 __put_user(stfs
.f_type
, &target_stfs
->f_type
);
4633 __put_user(stfs
.f_bsize
, &target_stfs
->f_bsize
);
4634 __put_user(stfs
.f_blocks
, &target_stfs
->f_blocks
);
4635 __put_user(stfs
.f_bfree
, &target_stfs
->f_bfree
);
4636 __put_user(stfs
.f_bavail
, &target_stfs
->f_bavail
);
4637 __put_user(stfs
.f_files
, &target_stfs
->f_files
);
4638 __put_user(stfs
.f_ffree
, &target_stfs
->f_ffree
);
4639 __put_user(stfs
.f_fsid
.__val
[0], &target_stfs
->f_fsid
.val
[0]);
4640 __put_user(stfs
.f_fsid
.__val
[1], &target_stfs
->f_fsid
.val
[1]);
4641 __put_user(stfs
.f_namelen
, &target_stfs
->f_namelen
);
4642 unlock_user_struct(target_stfs
, arg2
, 1);
4645 case TARGET_NR_fstatfs
:
4646 ret
= get_errno(fstatfs(arg1
, &stfs
));
4647 goto convert_statfs
;
4648 #ifdef TARGET_NR_statfs64
4649 case TARGET_NR_statfs64
:
4650 if (!(p
= lock_user_string(arg1
)))
4652 ret
= get_errno(statfs(path(p
), &stfs
));
4653 unlock_user(p
, arg1
, 0);
4655 if (!is_error(ret
)) {
4656 struct target_statfs64
*target_stfs
;
4658 if (!lock_user_struct(VERIFY_WRITE
, target_stfs
, arg3
, 0))
4660 __put_user(stfs
.f_type
, &target_stfs
->f_type
);
4661 __put_user(stfs
.f_bsize
, &target_stfs
->f_bsize
);
4662 __put_user(stfs
.f_blocks
, &target_stfs
->f_blocks
);
4663 __put_user(stfs
.f_bfree
, &target_stfs
->f_bfree
);
4664 __put_user(stfs
.f_bavail
, &target_stfs
->f_bavail
);
4665 __put_user(stfs
.f_files
, &target_stfs
->f_files
);
4666 __put_user(stfs
.f_ffree
, &target_stfs
->f_ffree
);
4667 __put_user(stfs
.f_fsid
.__val
[0], &target_stfs
->f_fsid
.val
[0]);
4668 __put_user(stfs
.f_fsid
.__val
[1], &target_stfs
->f_fsid
.val
[1]);
4669 __put_user(stfs
.f_namelen
, &target_stfs
->f_namelen
);
4670 unlock_user_struct(target_stfs
, arg3
, 1);
4673 case TARGET_NR_fstatfs64
:
4674 ret
= get_errno(fstatfs(arg1
, &stfs
));
4675 goto convert_statfs64
;
4677 #ifdef TARGET_NR_ioperm
4678 case TARGET_NR_ioperm
:
4681 #ifdef TARGET_NR_socketcall
4682 case TARGET_NR_socketcall
:
4683 ret
= do_socketcall(arg1
, arg2
);
4686 #ifdef TARGET_NR_accept
4687 case TARGET_NR_accept
:
4688 ret
= do_accept(arg1
, arg2
, arg3
);
4691 #ifdef TARGET_NR_bind
4692 case TARGET_NR_bind
:
4693 ret
= do_bind(arg1
, arg2
, arg3
);
4696 #ifdef TARGET_NR_connect
4697 case TARGET_NR_connect
:
4698 ret
= do_connect(arg1
, arg2
, arg3
);
4701 #ifdef TARGET_NR_getpeername
4702 case TARGET_NR_getpeername
:
4703 ret
= do_getpeername(arg1
, arg2
, arg3
);
4706 #ifdef TARGET_NR_getsockname
4707 case TARGET_NR_getsockname
:
4708 ret
= do_getsockname(arg1
, arg2
, arg3
);
4711 #ifdef TARGET_NR_getsockopt
4712 case TARGET_NR_getsockopt
:
4713 ret
= do_getsockopt(arg1
, arg2
, arg3
, arg4
, arg5
);
4716 #ifdef TARGET_NR_listen
4717 case TARGET_NR_listen
:
4718 ret
= get_errno(listen(arg1
, arg2
));
4721 #ifdef TARGET_NR_recv
4722 case TARGET_NR_recv
:
4723 ret
= do_recvfrom(arg1
, arg2
, arg3
, arg4
, 0, 0);
4726 #ifdef TARGET_NR_recvfrom
4727 case TARGET_NR_recvfrom
:
4728 ret
= do_recvfrom(arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
4731 #ifdef TARGET_NR_recvmsg
4732 case TARGET_NR_recvmsg
:
4733 ret
= do_sendrecvmsg(arg1
, arg2
, arg3
, 0);
4736 #ifdef TARGET_NR_send
4737 case TARGET_NR_send
:
4738 ret
= do_sendto(arg1
, arg2
, arg3
, arg4
, 0, 0);
4741 #ifdef TARGET_NR_sendmsg
4742 case TARGET_NR_sendmsg
:
4743 ret
= do_sendrecvmsg(arg1
, arg2
, arg3
, 1);
4746 #ifdef TARGET_NR_sendto
4747 case TARGET_NR_sendto
:
4748 ret
= do_sendto(arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
4751 #ifdef TARGET_NR_shutdown
4752 case TARGET_NR_shutdown
:
4753 ret
= get_errno(shutdown(arg1
, arg2
));
4756 #ifdef TARGET_NR_socket
4757 case TARGET_NR_socket
:
4758 ret
= do_socket(arg1
, arg2
, arg3
);
4761 #ifdef TARGET_NR_socketpair
4762 case TARGET_NR_socketpair
:
4763 ret
= do_socketpair(arg1
, arg2
, arg3
, arg4
);
4766 #ifdef TARGET_NR_setsockopt
4767 case TARGET_NR_setsockopt
:
4768 ret
= do_setsockopt(arg1
, arg2
, arg3
, arg4
, (socklen_t
) arg5
);
4772 case TARGET_NR_syslog
:
4773 if (!(p
= lock_user_string(arg2
)))
4775 ret
= get_errno(sys_syslog((int)arg1
, p
, (int)arg3
));
4776 unlock_user(p
, arg2
, 0);
4779 case TARGET_NR_setitimer
:
4781 struct itimerval value
, ovalue
, *pvalue
;
4785 if (copy_from_user_timeval(&pvalue
->it_interval
, arg2
)
4786 || copy_from_user_timeval(&pvalue
->it_value
,
4787 arg2
+ sizeof(struct target_timeval
)))
4792 ret
= get_errno(setitimer(arg1
, pvalue
, &ovalue
));
4793 if (!is_error(ret
) && arg3
) {
4794 if (copy_to_user_timeval(arg3
,
4795 &ovalue
.it_interval
)
4796 || copy_to_user_timeval(arg3
+ sizeof(struct target_timeval
),
4802 case TARGET_NR_getitimer
:
4804 struct itimerval value
;
4806 ret
= get_errno(getitimer(arg1
, &value
));
4807 if (!is_error(ret
) && arg2
) {
4808 if (copy_to_user_timeval(arg2
,
4810 || copy_to_user_timeval(arg2
+ sizeof(struct target_timeval
),
4816 case TARGET_NR_stat
:
4817 if (!(p
= lock_user_string(arg1
)))
4819 ret
= get_errno(stat(path(p
), &st
));
4820 unlock_user(p
, arg1
, 0);
4822 case TARGET_NR_lstat
:
4823 if (!(p
= lock_user_string(arg1
)))
4825 ret
= get_errno(lstat(path(p
), &st
));
4826 unlock_user(p
, arg1
, 0);
4828 case TARGET_NR_fstat
:
4830 ret
= get_errno(fstat(arg1
, &st
));
4832 if (!is_error(ret
)) {
4833 struct target_stat
*target_st
;
4835 if (!lock_user_struct(VERIFY_WRITE
, target_st
, arg2
, 0))
4837 __put_user(st
.st_dev
, &target_st
->st_dev
);
4838 __put_user(st
.st_ino
, &target_st
->st_ino
);
4839 __put_user(st
.st_mode
, &target_st
->st_mode
);
4840 __put_user(st
.st_uid
, &target_st
->st_uid
);
4841 __put_user(st
.st_gid
, &target_st
->st_gid
);
4842 __put_user(st
.st_nlink
, &target_st
->st_nlink
);
4843 __put_user(st
.st_rdev
, &target_st
->st_rdev
);
4844 __put_user(st
.st_size
, &target_st
->st_size
);
4845 __put_user(st
.st_blksize
, &target_st
->st_blksize
);
4846 __put_user(st
.st_blocks
, &target_st
->st_blocks
);
4847 __put_user(st
.st_atime
, &target_st
->target_st_atime
);
4848 __put_user(st
.st_mtime
, &target_st
->target_st_mtime
);
4849 __put_user(st
.st_ctime
, &target_st
->target_st_ctime
);
4850 unlock_user_struct(target_st
, arg2
, 1);
4854 #ifdef TARGET_NR_olduname
4855 case TARGET_NR_olduname
:
4858 #ifdef TARGET_NR_iopl
4859 case TARGET_NR_iopl
:
4862 case TARGET_NR_vhangup
:
4863 ret
= get_errno(vhangup());
4865 #ifdef TARGET_NR_idle
4866 case TARGET_NR_idle
:
4869 #ifdef TARGET_NR_syscall
4870 case TARGET_NR_syscall
:
4871 ret
= do_syscall(cpu_env
,arg1
& 0xffff,arg2
,arg3
,arg4
,arg5
,arg6
,0);
4874 case TARGET_NR_wait4
:
4877 abi_long status_ptr
= arg2
;
4878 struct rusage rusage
, *rusage_ptr
;
4879 abi_ulong target_rusage
= arg4
;
4881 rusage_ptr
= &rusage
;
4884 ret
= get_errno(wait4(arg1
, &status
, arg3
, rusage_ptr
));
4885 if (!is_error(ret
)) {
4887 if (put_user_s32(status
, status_ptr
))
4891 host_to_target_rusage(target_rusage
, &rusage
);
4895 #ifdef TARGET_NR_swapoff
4896 case TARGET_NR_swapoff
:
4897 if (!(p
= lock_user_string(arg1
)))
4899 ret
= get_errno(swapoff(p
));
4900 unlock_user(p
, arg1
, 0);
4903 case TARGET_NR_sysinfo
:
4905 struct target_sysinfo
*target_value
;
4906 struct sysinfo value
;
4907 ret
= get_errno(sysinfo(&value
));
4908 if (!is_error(ret
) && arg1
)
4910 if (!lock_user_struct(VERIFY_WRITE
, target_value
, arg1
, 0))
4912 __put_user(value
.uptime
, &target_value
->uptime
);
4913 __put_user(value
.loads
[0], &target_value
->loads
[0]);
4914 __put_user(value
.loads
[1], &target_value
->loads
[1]);
4915 __put_user(value
.loads
[2], &target_value
->loads
[2]);
4916 __put_user(value
.totalram
, &target_value
->totalram
);
4917 __put_user(value
.freeram
, &target_value
->freeram
);
4918 __put_user(value
.sharedram
, &target_value
->sharedram
);
4919 __put_user(value
.bufferram
, &target_value
->bufferram
);
4920 __put_user(value
.totalswap
, &target_value
->totalswap
);
4921 __put_user(value
.freeswap
, &target_value
->freeswap
);
4922 __put_user(value
.procs
, &target_value
->procs
);
4923 __put_user(value
.totalhigh
, &target_value
->totalhigh
);
4924 __put_user(value
.freehigh
, &target_value
->freehigh
);
4925 __put_user(value
.mem_unit
, &target_value
->mem_unit
);
4926 unlock_user_struct(target_value
, arg1
, 1);
4930 #ifdef TARGET_NR_ipc
4932 ret
= do_ipc(arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
4936 #ifdef TARGET_NR_msgctl
4937 case TARGET_NR_msgctl
:
4938 ret
= do_msgctl(arg1
, arg2
, arg3
);
4941 #ifdef TARGET_NR_msgget
4942 case TARGET_NR_msgget
:
4943 ret
= get_errno(msgget(arg1
, arg2
));
4946 #ifdef TARGET_NR_msgrcv
4947 case TARGET_NR_msgrcv
:
4948 ret
= do_msgrcv(arg1
, arg2
, arg3
, arg4
, arg5
);
4951 #ifdef TARGET_NR_msgsnd
4952 case TARGET_NR_msgsnd
:
4953 ret
= do_msgsnd(arg1
, arg2
, arg3
, arg4
);
4956 case TARGET_NR_fsync
:
4957 ret
= get_errno(fsync(arg1
));
4959 case TARGET_NR_clone
:
4960 #if defined(TARGET_SH4)
4961 ret
= get_errno(do_fork(cpu_env
, arg1
, arg2
, arg3
, arg5
, arg4
));
4962 #elif defined(TARGET_CRIS)
4963 ret
= get_errno(do_fork(cpu_env
, arg2
, arg1
, arg3
, arg4
, arg5
));
4965 ret
= get_errno(do_fork(cpu_env
, arg1
, arg2
, arg3
, arg4
, arg5
));
4968 #ifdef __NR_exit_group
4969 /* new thread calls */
4970 case TARGET_NR_exit_group
:
4974 gdb_exit(cpu_env
, arg1
);
4975 ret
= get_errno(exit_group(arg1
));
4978 case TARGET_NR_setdomainname
:
4979 if (!(p
= lock_user_string(arg1
)))
4981 ret
= get_errno(setdomainname(p
, arg2
));
4982 unlock_user(p
, arg1
, 0);
4984 case TARGET_NR_uname
:
4985 /* no need to transcode because we use the linux syscall */
4987 struct new_utsname
* buf
;
4989 if (!lock_user_struct(VERIFY_WRITE
, buf
, arg1
, 0))
4991 ret
= get_errno(sys_uname(buf
));
4992 if (!is_error(ret
)) {
4993 /* Overrite the native machine name with whatever is being
4995 strcpy (buf
->machine
, UNAME_MACHINE
);
4996 /* Allow the user to override the reported release. */
4997 if (qemu_uname_release
&& *qemu_uname_release
)
4998 strcpy (buf
->release
, qemu_uname_release
);
5000 unlock_user_struct(buf
, arg1
, 1);
5004 case TARGET_NR_modify_ldt
:
5005 ret
= do_modify_ldt(cpu_env
, arg1
, arg2
, arg3
);
5007 #if !defined(TARGET_X86_64)
5008 case TARGET_NR_vm86old
:
5010 case TARGET_NR_vm86
:
5011 ret
= do_vm86(cpu_env
, arg1
, arg2
);
5015 case TARGET_NR_adjtimex
:
5017 #ifdef TARGET_NR_create_module
5018 case TARGET_NR_create_module
:
5020 case TARGET_NR_init_module
:
5021 case TARGET_NR_delete_module
:
5022 #ifdef TARGET_NR_get_kernel_syms
5023 case TARGET_NR_get_kernel_syms
:
5026 case TARGET_NR_quotactl
:
5028 case TARGET_NR_getpgid
:
5029 ret
= get_errno(getpgid(arg1
));
5031 case TARGET_NR_fchdir
:
5032 ret
= get_errno(fchdir(arg1
));
5034 #ifdef TARGET_NR_bdflush /* not on x86_64 */
5035 case TARGET_NR_bdflush
:
5038 #ifdef TARGET_NR_sysfs
5039 case TARGET_NR_sysfs
:
5042 case TARGET_NR_personality
:
5043 ret
= get_errno(personality(arg1
));
5045 #ifdef TARGET_NR_afs_syscall
5046 case TARGET_NR_afs_syscall
:
5049 #ifdef TARGET_NR__llseek /* Not on alpha */
5050 case TARGET_NR__llseek
:
5052 #if defined (__x86_64__)
5053 ret
= get_errno(lseek(arg1
, ((uint64_t )arg2
<< 32) | arg3
, arg5
));
5054 if (put_user_s64(ret
, arg4
))
5058 ret
= get_errno(_llseek(arg1
, arg2
, arg3
, &res
, arg5
));
5059 if (put_user_s64(res
, arg4
))
5065 case TARGET_NR_getdents
:
5066 #if TARGET_ABI_BITS != 32
5068 #elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
5070 struct target_dirent
*target_dirp
;
5071 struct linux_dirent
*dirp
;
5072 abi_long count
= arg3
;
5074 dirp
= malloc(count
);
5076 ret
= -TARGET_ENOMEM
;
5080 ret
= get_errno(sys_getdents(arg1
, dirp
, count
));
5081 if (!is_error(ret
)) {
5082 struct linux_dirent
*de
;
5083 struct target_dirent
*tde
;
5085 int reclen
, treclen
;
5086 int count1
, tnamelen
;
5090 if (!(target_dirp
= lock_user(VERIFY_WRITE
, arg2
, count
, 0)))
5094 reclen
= de
->d_reclen
;
5095 treclen
= reclen
- (2 * (sizeof(long) - sizeof(abi_long
)));
5096 tde
->d_reclen
= tswap16(treclen
);
5097 tde
->d_ino
= tswapl(de
->d_ino
);
5098 tde
->d_off
= tswapl(de
->d_off
);
5099 tnamelen
= treclen
- (2 * sizeof(abi_long
) + 2);
5102 /* XXX: may not be correct */
5103 pstrcpy(tde
->d_name
, tnamelen
, de
->d_name
);
5104 de
= (struct linux_dirent
*)((char *)de
+ reclen
);
5106 tde
= (struct target_dirent
*)((char *)tde
+ treclen
);
5110 unlock_user(target_dirp
, arg2
, ret
);
5116 struct linux_dirent
*dirp
;
5117 abi_long count
= arg3
;
5119 if (!(dirp
= lock_user(VERIFY_WRITE
, arg2
, count
, 0)))
5121 ret
= get_errno(sys_getdents(arg1
, dirp
, count
));
5122 if (!is_error(ret
)) {
5123 struct linux_dirent
*de
;
5128 reclen
= de
->d_reclen
;
5131 de
->d_reclen
= tswap16(reclen
);
5132 tswapls(&de
->d_ino
);
5133 tswapls(&de
->d_off
);
5134 de
= (struct linux_dirent
*)((char *)de
+ reclen
);
5138 unlock_user(dirp
, arg2
, ret
);
5142 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
5143 case TARGET_NR_getdents64
:
5145 struct linux_dirent64
*dirp
;
5146 abi_long count
= arg3
;
5147 if (!(dirp
= lock_user(VERIFY_WRITE
, arg2
, count
, 0)))
5149 ret
= get_errno(sys_getdents64(arg1
, dirp
, count
));
5150 if (!is_error(ret
)) {
5151 struct linux_dirent64
*de
;
5156 reclen
= de
->d_reclen
;
5159 de
->d_reclen
= tswap16(reclen
);
5160 tswap64s((uint64_t *)&de
->d_ino
);
5161 tswap64s((uint64_t *)&de
->d_off
);
5162 de
= (struct linux_dirent64
*)((char *)de
+ reclen
);
5166 unlock_user(dirp
, arg2
, ret
);
5169 #endif /* TARGET_NR_getdents64 */
5170 #ifdef TARGET_NR__newselect
5171 case TARGET_NR__newselect
:
5172 ret
= do_select(arg1
, arg2
, arg3
, arg4
, arg5
);
5175 #ifdef TARGET_NR_poll
5176 case TARGET_NR_poll
:
5178 struct target_pollfd
*target_pfd
;
5179 unsigned int nfds
= arg2
;
5184 target_pfd
= lock_user(VERIFY_WRITE
, arg1
, sizeof(struct target_pollfd
) * nfds
, 1);
5187 pfd
= alloca(sizeof(struct pollfd
) * nfds
);
5188 for(i
= 0; i
< nfds
; i
++) {
5189 pfd
[i
].fd
= tswap32(target_pfd
[i
].fd
);
5190 pfd
[i
].events
= tswap16(target_pfd
[i
].events
);
5192 ret
= get_errno(poll(pfd
, nfds
, timeout
));
5193 if (!is_error(ret
)) {
5194 for(i
= 0; i
< nfds
; i
++) {
5195 target_pfd
[i
].revents
= tswap16(pfd
[i
].revents
);
5197 ret
+= nfds
* (sizeof(struct target_pollfd
)
5198 - sizeof(struct pollfd
));
5200 unlock_user(target_pfd
, arg1
, ret
);
5204 case TARGET_NR_flock
:
5205 /* NOTE: the flock constant seems to be the same for every
5207 ret
= get_errno(flock(arg1
, arg2
));
5209 case TARGET_NR_readv
:
5214 vec
= alloca(count
* sizeof(struct iovec
));
5215 if (lock_iovec(VERIFY_WRITE
, vec
, arg2
, count
, 0) < 0)
5217 ret
= get_errno(readv(arg1
, vec
, count
));
5218 unlock_iovec(vec
, arg2
, count
, 1);
5221 case TARGET_NR_writev
:
5226 vec
= alloca(count
* sizeof(struct iovec
));
5227 if (lock_iovec(VERIFY_READ
, vec
, arg2
, count
, 1) < 0)
5229 ret
= get_errno(writev(arg1
, vec
, count
));
5230 unlock_iovec(vec
, arg2
, count
, 0);
5233 case TARGET_NR_getsid
:
5234 ret
= get_errno(getsid(arg1
));
5236 #if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
5237 case TARGET_NR_fdatasync
:
5238 ret
= get_errno(fdatasync(arg1
));
5241 case TARGET_NR__sysctl
:
5242 /* We don't implement this, but ENOTDIR is always a safe
5244 ret
= -TARGET_ENOTDIR
;
5246 case TARGET_NR_sched_setparam
:
5248 struct sched_param
*target_schp
;
5249 struct sched_param schp
;
5251 if (!lock_user_struct(VERIFY_READ
, target_schp
, arg2
, 1))
5253 schp
.sched_priority
= tswap32(target_schp
->sched_priority
);
5254 unlock_user_struct(target_schp
, arg2
, 0);
5255 ret
= get_errno(sched_setparam(arg1
, &schp
));
5258 case TARGET_NR_sched_getparam
:
5260 struct sched_param
*target_schp
;
5261 struct sched_param schp
;
5262 ret
= get_errno(sched_getparam(arg1
, &schp
));
5263 if (!is_error(ret
)) {
5264 if (!lock_user_struct(VERIFY_WRITE
, target_schp
, arg2
, 0))
5266 target_schp
->sched_priority
= tswap32(schp
.sched_priority
);
5267 unlock_user_struct(target_schp
, arg2
, 1);
5271 case TARGET_NR_sched_setscheduler
:
5273 struct sched_param
*target_schp
;
5274 struct sched_param schp
;
5275 if (!lock_user_struct(VERIFY_READ
, target_schp
, arg3
, 1))
5277 schp
.sched_priority
= tswap32(target_schp
->sched_priority
);
5278 unlock_user_struct(target_schp
, arg3
, 0);
5279 ret
= get_errno(sched_setscheduler(arg1
, arg2
, &schp
));
5282 case TARGET_NR_sched_getscheduler
:
5283 ret
= get_errno(sched_getscheduler(arg1
));
5285 case TARGET_NR_sched_yield
:
5286 ret
= get_errno(sched_yield());
5288 case TARGET_NR_sched_get_priority_max
:
5289 ret
= get_errno(sched_get_priority_max(arg1
));
5291 case TARGET_NR_sched_get_priority_min
:
5292 ret
= get_errno(sched_get_priority_min(arg1
));
5294 case TARGET_NR_sched_rr_get_interval
:
5297 ret
= get_errno(sched_rr_get_interval(arg1
, &ts
));
5298 if (!is_error(ret
)) {
5299 host_to_target_timespec(arg2
, &ts
);
5303 case TARGET_NR_nanosleep
:
5305 struct timespec req
, rem
;
5306 target_to_host_timespec(&req
, arg1
);
5307 ret
= get_errno(nanosleep(&req
, &rem
));
5308 if (is_error(ret
) && arg2
) {
5309 host_to_target_timespec(arg2
, &rem
);
5313 #ifdef TARGET_NR_query_module
5314 case TARGET_NR_query_module
:
5317 #ifdef TARGET_NR_nfsservctl
5318 case TARGET_NR_nfsservctl
:
5321 case TARGET_NR_prctl
:
5324 case PR_GET_PDEATHSIG
:
5327 ret
= get_errno(prctl(arg1
, &deathsig
, arg3
, arg4
, arg5
));
5328 if (!is_error(ret
) && arg2
5329 && put_user_ual(deathsig
, arg2
))
5334 ret
= get_errno(prctl(arg1
, arg2
, arg3
, arg4
, arg5
));
5338 #ifdef TARGET_NR_arch_prctl
5339 case TARGET_NR_arch_prctl
:
5340 #if defined(TARGET_I386) && !defined(TARGET_ABI32)
5341 ret
= do_arch_prctl(cpu_env
, arg1
, arg2
);
5347 #ifdef TARGET_NR_pread
5348 case TARGET_NR_pread
:
5350 if (((CPUARMState
*)cpu_env
)->eabi
)
5353 if (!(p
= lock_user(VERIFY_WRITE
, arg2
, arg3
, 0)))
5355 ret
= get_errno(pread(arg1
, p
, arg3
, arg4
));
5356 unlock_user(p
, arg2
, ret
);
5358 case TARGET_NR_pwrite
:
5360 if (((CPUARMState
*)cpu_env
)->eabi
)
5363 if (!(p
= lock_user(VERIFY_READ
, arg2
, arg3
, 1)))
5365 ret
= get_errno(pwrite(arg1
, p
, arg3
, arg4
));
5366 unlock_user(p
, arg2
, 0);
5369 #ifdef TARGET_NR_pread64
5370 case TARGET_NR_pread64
:
5371 if (!(p
= lock_user(VERIFY_WRITE
, arg2
, arg3
, 0)))
5373 ret
= get_errno(pread64(arg1
, p
, arg3
, target_offset64(arg4
, arg5
)));
5374 unlock_user(p
, arg2
, ret
);
5376 case TARGET_NR_pwrite64
:
5377 if (!(p
= lock_user(VERIFY_READ
, arg2
, arg3
, 1)))
5379 ret
= get_errno(pwrite64(arg1
, p
, arg3
, target_offset64(arg4
, arg5
)));
5380 unlock_user(p
, arg2
, 0);
5383 case TARGET_NR_getcwd
:
5384 if (!(p
= lock_user(VERIFY_WRITE
, arg1
, arg2
, 0)))
5386 ret
= get_errno(sys_getcwd1(p
, arg2
));
5387 unlock_user(p
, arg1
, ret
);
5389 case TARGET_NR_capget
:
5391 case TARGET_NR_capset
:
5393 case TARGET_NR_sigaltstack
:
5394 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
5395 defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA)
5396 ret
= do_sigaltstack(arg1
, arg2
, get_sp_from_cpustate((CPUState
*)cpu_env
));
5401 case TARGET_NR_sendfile
:
5403 #ifdef TARGET_NR_getpmsg
5404 case TARGET_NR_getpmsg
:
5407 #ifdef TARGET_NR_putpmsg
5408 case TARGET_NR_putpmsg
:
5411 #ifdef TARGET_NR_vfork
5412 case TARGET_NR_vfork
:
5413 ret
= get_errno(do_fork(cpu_env
, CLONE_VFORK
| CLONE_VM
| SIGCHLD
,
5417 #ifdef TARGET_NR_ugetrlimit
5418 case TARGET_NR_ugetrlimit
:
5421 ret
= get_errno(getrlimit(arg1
, &rlim
));
5422 if (!is_error(ret
)) {
5423 struct target_rlimit
*target_rlim
;
5424 if (!lock_user_struct(VERIFY_WRITE
, target_rlim
, arg2
, 0))
5426 target_rlim
->rlim_cur
= tswapl(rlim
.rlim_cur
);
5427 target_rlim
->rlim_max
= tswapl(rlim
.rlim_max
);
5428 unlock_user_struct(target_rlim
, arg2
, 1);
5433 #ifdef TARGET_NR_truncate64
5434 case TARGET_NR_truncate64
:
5435 if (!(p
= lock_user_string(arg1
)))
5437 ret
= target_truncate64(cpu_env
, p
, arg2
, arg3
, arg4
);
5438 unlock_user(p
, arg1
, 0);
5441 #ifdef TARGET_NR_ftruncate64
5442 case TARGET_NR_ftruncate64
:
5443 ret
= target_ftruncate64(cpu_env
, arg1
, arg2
, arg3
, arg4
);
5446 #ifdef TARGET_NR_stat64
5447 case TARGET_NR_stat64
:
5448 if (!(p
= lock_user_string(arg1
)))
5450 ret
= get_errno(stat(path(p
), &st
));
5451 unlock_user(p
, arg1
, 0);
5453 ret
= host_to_target_stat64(cpu_env
, arg2
, &st
);
5456 #ifdef TARGET_NR_lstat64
5457 case TARGET_NR_lstat64
:
5458 if (!(p
= lock_user_string(arg1
)))
5460 ret
= get_errno(lstat(path(p
), &st
));
5461 unlock_user(p
, arg1
, 0);
5463 ret
= host_to_target_stat64(cpu_env
, arg2
, &st
);
5466 #ifdef TARGET_NR_fstat64
5467 case TARGET_NR_fstat64
:
5468 ret
= get_errno(fstat(arg1
, &st
));
5470 ret
= host_to_target_stat64(cpu_env
, arg2
, &st
);
5473 #if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
5474 (defined(__NR_fstatat64) || defined(__NR_newfstatat))
5475 #ifdef TARGET_NR_fstatat64
5476 case TARGET_NR_fstatat64
:
5478 #ifdef TARGET_NR_newfstatat
5479 case TARGET_NR_newfstatat
:
5481 if (!(p
= lock_user_string(arg2
)))
5483 #ifdef __NR_fstatat64
5484 ret
= get_errno(sys_fstatat64(arg1
, path(p
), &st
, arg4
));
5486 ret
= get_errno(sys_newfstatat(arg1
, path(p
), &st
, arg4
));
5489 ret
= host_to_target_stat64(cpu_env
, arg3
, &st
);
5493 case TARGET_NR_lchown
:
5494 if (!(p
= lock_user_string(arg1
)))
5496 ret
= get_errno(lchown(p
, low2highuid(arg2
), low2highgid(arg3
)));
5497 unlock_user(p
, arg1
, 0);
5499 case TARGET_NR_getuid
:
5500 ret
= get_errno(high2lowuid(getuid()));
5502 case TARGET_NR_getgid
:
5503 ret
= get_errno(high2lowgid(getgid()));
5505 case TARGET_NR_geteuid
:
5506 ret
= get_errno(high2lowuid(geteuid()));
5508 case TARGET_NR_getegid
:
5509 ret
= get_errno(high2lowgid(getegid()));
5511 case TARGET_NR_setreuid
:
5512 ret
= get_errno(setreuid(low2highuid(arg1
), low2highuid(arg2
)));
5514 case TARGET_NR_setregid
:
5515 ret
= get_errno(setregid(low2highgid(arg1
), low2highgid(arg2
)));
5517 case TARGET_NR_getgroups
:
5519 int gidsetsize
= arg1
;
5520 uint16_t *target_grouplist
;
5524 grouplist
= alloca(gidsetsize
* sizeof(gid_t
));
5525 ret
= get_errno(getgroups(gidsetsize
, grouplist
));
5526 if (gidsetsize
== 0)
5528 if (!is_error(ret
)) {
5529 target_grouplist
= lock_user(VERIFY_WRITE
, arg2
, gidsetsize
* 2, 0);
5530 if (!target_grouplist
)
5532 for(i
= 0;i
< ret
; i
++)
5533 target_grouplist
[i
] = tswap16(grouplist
[i
]);
5534 unlock_user(target_grouplist
, arg2
, gidsetsize
* 2);
5538 case TARGET_NR_setgroups
:
5540 int gidsetsize
= arg1
;
5541 uint16_t *target_grouplist
;
5545 grouplist
= alloca(gidsetsize
* sizeof(gid_t
));
5546 target_grouplist
= lock_user(VERIFY_READ
, arg2
, gidsetsize
* 2, 1);
5547 if (!target_grouplist
) {
5548 ret
= -TARGET_EFAULT
;
5551 for(i
= 0;i
< gidsetsize
; i
++)
5552 grouplist
[i
] = tswap16(target_grouplist
[i
]);
5553 unlock_user(target_grouplist
, arg2
, 0);
5554 ret
= get_errno(setgroups(gidsetsize
, grouplist
));
5557 case TARGET_NR_fchown
:
5558 ret
= get_errno(fchown(arg1
, low2highuid(arg2
), low2highgid(arg3
)));
5560 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
5561 case TARGET_NR_fchownat
:
5562 if (!(p
= lock_user_string(arg2
)))
5564 ret
= get_errno(sys_fchownat(arg1
, p
, low2highuid(arg3
), low2highgid(arg4
), arg5
));
5565 unlock_user(p
, arg2
, 0);
5568 #ifdef TARGET_NR_setresuid
5569 case TARGET_NR_setresuid
:
5570 ret
= get_errno(setresuid(low2highuid(arg1
),
5572 low2highuid(arg3
)));
5575 #ifdef TARGET_NR_getresuid
5576 case TARGET_NR_getresuid
:
5578 uid_t ruid
, euid
, suid
;
5579 ret
= get_errno(getresuid(&ruid
, &euid
, &suid
));
5580 if (!is_error(ret
)) {
5581 if (put_user_u16(high2lowuid(ruid
), arg1
)
5582 || put_user_u16(high2lowuid(euid
), arg2
)
5583 || put_user_u16(high2lowuid(suid
), arg3
))
5589 #ifdef TARGET_NR_getresgid
5590 case TARGET_NR_setresgid
:
5591 ret
= get_errno(setresgid(low2highgid(arg1
),
5593 low2highgid(arg3
)));
5596 #ifdef TARGET_NR_getresgid
5597 case TARGET_NR_getresgid
:
5599 gid_t rgid
, egid
, sgid
;
5600 ret
= get_errno(getresgid(&rgid
, &egid
, &sgid
));
5601 if (!is_error(ret
)) {
5602 if (put_user_u16(high2lowgid(rgid
), arg1
)
5603 || put_user_u16(high2lowgid(egid
), arg2
)
5604 || put_user_u16(high2lowgid(sgid
), arg3
))
5610 case TARGET_NR_chown
:
5611 if (!(p
= lock_user_string(arg1
)))
5613 ret
= get_errno(chown(p
, low2highuid(arg2
), low2highgid(arg3
)));
5614 unlock_user(p
, arg1
, 0);
5616 case TARGET_NR_setuid
:
5617 ret
= get_errno(setuid(low2highuid(arg1
)));
5619 case TARGET_NR_setgid
:
5620 ret
= get_errno(setgid(low2highgid(arg1
)));
5622 case TARGET_NR_setfsuid
:
5623 ret
= get_errno(setfsuid(arg1
));
5625 case TARGET_NR_setfsgid
:
5626 ret
= get_errno(setfsgid(arg1
));
5628 #endif /* USE_UID16 */
5630 #ifdef TARGET_NR_lchown32
5631 case TARGET_NR_lchown32
:
5632 if (!(p
= lock_user_string(arg1
)))
5634 ret
= get_errno(lchown(p
, arg2
, arg3
));
5635 unlock_user(p
, arg1
, 0);
5638 #ifdef TARGET_NR_getuid32
5639 case TARGET_NR_getuid32
:
5640 ret
= get_errno(getuid());
5644 #if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
5645 /* Alpha specific */
5646 case TARGET_NR_getxuid
:
5650 ((CPUAlphaState
*)cpu_env
)->ir
[IR_A4
]=euid
;
5652 ret
= get_errno(getuid());
5655 #if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
5656 /* Alpha specific */
5657 case TARGET_NR_getxgid
:
5661 ((CPUAlphaState
*)cpu_env
)->ir
[IR_A4
]=egid
;
5663 ret
= get_errno(getgid());
5667 #ifdef TARGET_NR_getgid32
5668 case TARGET_NR_getgid32
:
5669 ret
= get_errno(getgid());
5672 #ifdef TARGET_NR_geteuid32
5673 case TARGET_NR_geteuid32
:
5674 ret
= get_errno(geteuid());
5677 #ifdef TARGET_NR_getegid32
5678 case TARGET_NR_getegid32
:
5679 ret
= get_errno(getegid());
5682 #ifdef TARGET_NR_setreuid32
5683 case TARGET_NR_setreuid32
:
5684 ret
= get_errno(setreuid(arg1
, arg2
));
5687 #ifdef TARGET_NR_setregid32
5688 case TARGET_NR_setregid32
:
5689 ret
= get_errno(setregid(arg1
, arg2
));
5692 #ifdef TARGET_NR_getgroups32
5693 case TARGET_NR_getgroups32
:
5695 int gidsetsize
= arg1
;
5696 uint32_t *target_grouplist
;
5700 grouplist
= alloca(gidsetsize
* sizeof(gid_t
));
5701 ret
= get_errno(getgroups(gidsetsize
, grouplist
));
5702 if (gidsetsize
== 0)
5704 if (!is_error(ret
)) {
5705 target_grouplist
= lock_user(VERIFY_WRITE
, arg2
, gidsetsize
* 4, 0);
5706 if (!target_grouplist
) {
5707 ret
= -TARGET_EFAULT
;
5710 for(i
= 0;i
< ret
; i
++)
5711 target_grouplist
[i
] = tswap32(grouplist
[i
]);
5712 unlock_user(target_grouplist
, arg2
, gidsetsize
* 4);
5717 #ifdef TARGET_NR_setgroups32
5718 case TARGET_NR_setgroups32
:
5720 int gidsetsize
= arg1
;
5721 uint32_t *target_grouplist
;
5725 grouplist
= alloca(gidsetsize
* sizeof(gid_t
));
5726 target_grouplist
= lock_user(VERIFY_READ
, arg2
, gidsetsize
* 4, 1);
5727 if (!target_grouplist
) {
5728 ret
= -TARGET_EFAULT
;
5731 for(i
= 0;i
< gidsetsize
; i
++)
5732 grouplist
[i
] = tswap32(target_grouplist
[i
]);
5733 unlock_user(target_grouplist
, arg2
, 0);
5734 ret
= get_errno(setgroups(gidsetsize
, grouplist
));
5738 #ifdef TARGET_NR_fchown32
5739 case TARGET_NR_fchown32
:
5740 ret
= get_errno(fchown(arg1
, arg2
, arg3
));
5743 #ifdef TARGET_NR_setresuid32
5744 case TARGET_NR_setresuid32
:
5745 ret
= get_errno(setresuid(arg1
, arg2
, arg3
));
5748 #ifdef TARGET_NR_getresuid32
5749 case TARGET_NR_getresuid32
:
5751 uid_t ruid
, euid
, suid
;
5752 ret
= get_errno(getresuid(&ruid
, &euid
, &suid
));
5753 if (!is_error(ret
)) {
5754 if (put_user_u32(ruid
, arg1
)
5755 || put_user_u32(euid
, arg2
)
5756 || put_user_u32(suid
, arg3
))
5762 #ifdef TARGET_NR_setresgid32
5763 case TARGET_NR_setresgid32
:
5764 ret
= get_errno(setresgid(arg1
, arg2
, arg3
));
5767 #ifdef TARGET_NR_getresgid32
5768 case TARGET_NR_getresgid32
:
5770 gid_t rgid
, egid
, sgid
;
5771 ret
= get_errno(getresgid(&rgid
, &egid
, &sgid
));
5772 if (!is_error(ret
)) {
5773 if (put_user_u32(rgid
, arg1
)
5774 || put_user_u32(egid
, arg2
)
5775 || put_user_u32(sgid
, arg3
))
5781 #ifdef TARGET_NR_chown32
5782 case TARGET_NR_chown32
:
5783 if (!(p
= lock_user_string(arg1
)))
5785 ret
= get_errno(chown(p
, arg2
, arg3
));
5786 unlock_user(p
, arg1
, 0);
5789 #ifdef TARGET_NR_setuid32
5790 case TARGET_NR_setuid32
:
5791 ret
= get_errno(setuid(arg1
));
5794 #ifdef TARGET_NR_setgid32
5795 case TARGET_NR_setgid32
:
5796 ret
= get_errno(setgid(arg1
));
5799 #ifdef TARGET_NR_setfsuid32
5800 case TARGET_NR_setfsuid32
:
5801 ret
= get_errno(setfsuid(arg1
));
5804 #ifdef TARGET_NR_setfsgid32
5805 case TARGET_NR_setfsgid32
:
5806 ret
= get_errno(setfsgid(arg1
));
5810 case TARGET_NR_pivot_root
:
5812 #ifdef TARGET_NR_mincore
5813 case TARGET_NR_mincore
:
5816 ret
= -TARGET_EFAULT
;
5817 if (!(a
= lock_user(VERIFY_READ
, arg1
,arg2
, 0)))
5819 if (!(p
= lock_user_string(arg3
)))
5821 ret
= get_errno(mincore(a
, arg2
, p
));
5822 unlock_user(p
, arg3
, ret
);
5824 unlock_user(a
, arg1
, 0);
5828 #ifdef TARGET_NR_arm_fadvise64_64
5829 case TARGET_NR_arm_fadvise64_64
:
5832 * arm_fadvise64_64 looks like fadvise64_64 but
5833 * with different argument order
5841 #if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64)
5842 #ifdef TARGET_NR_fadvise64_64
5843 case TARGET_NR_fadvise64_64
:
5845 /* This is a hint, so ignoring and returning success is ok. */
5849 #ifdef TARGET_NR_madvise
5850 case TARGET_NR_madvise
:
5851 /* A straight passthrough may not be safe because qemu sometimes
5852 turns private flie-backed mappings into anonymous mappings.
5853 This will break MADV_DONTNEED.
5854 This is a hint, so ignoring and returning success is ok. */
5858 #if TARGET_ABI_BITS == 32
5859 case TARGET_NR_fcntl64
:
5863 struct target_flock64
*target_fl
;
5865 struct target_eabi_flock64
*target_efl
;
5869 case TARGET_F_GETLK64
:
5872 case TARGET_F_SETLK64
:
5875 case TARGET_F_SETLKW64
:
5884 case TARGET_F_GETLK64
:
5886 if (((CPUARMState
*)cpu_env
)->eabi
) {
5887 if (!lock_user_struct(VERIFY_READ
, target_efl
, arg3
, 1))
5889 fl
.l_type
= tswap16(target_efl
->l_type
);
5890 fl
.l_whence
= tswap16(target_efl
->l_whence
);
5891 fl
.l_start
= tswap64(target_efl
->l_start
);
5892 fl
.l_len
= tswap64(target_efl
->l_len
);
5893 fl
.l_pid
= tswapl(target_efl
->l_pid
);
5894 unlock_user_struct(target_efl
, arg3
, 0);
5898 if (!lock_user_struct(VERIFY_READ
, target_fl
, arg3
, 1))
5900 fl
.l_type
= tswap16(target_fl
->l_type
);
5901 fl
.l_whence
= tswap16(target_fl
->l_whence
);
5902 fl
.l_start
= tswap64(target_fl
->l_start
);
5903 fl
.l_len
= tswap64(target_fl
->l_len
);
5904 fl
.l_pid
= tswapl(target_fl
->l_pid
);
5905 unlock_user_struct(target_fl
, arg3
, 0);
5907 ret
= get_errno(fcntl(arg1
, cmd
, &fl
));
5910 if (((CPUARMState
*)cpu_env
)->eabi
) {
5911 if (!lock_user_struct(VERIFY_WRITE
, target_efl
, arg3
, 0))
5913 target_efl
->l_type
= tswap16(fl
.l_type
);
5914 target_efl
->l_whence
= tswap16(fl
.l_whence
);
5915 target_efl
->l_start
= tswap64(fl
.l_start
);
5916 target_efl
->l_len
= tswap64(fl
.l_len
);
5917 target_efl
->l_pid
= tswapl(fl
.l_pid
);
5918 unlock_user_struct(target_efl
, arg3
, 1);
5922 if (!lock_user_struct(VERIFY_WRITE
, target_fl
, arg3
, 0))
5924 target_fl
->l_type
= tswap16(fl
.l_type
);
5925 target_fl
->l_whence
= tswap16(fl
.l_whence
);
5926 target_fl
->l_start
= tswap64(fl
.l_start
);
5927 target_fl
->l_len
= tswap64(fl
.l_len
);
5928 target_fl
->l_pid
= tswapl(fl
.l_pid
);
5929 unlock_user_struct(target_fl
, arg3
, 1);
5934 case TARGET_F_SETLK64
:
5935 case TARGET_F_SETLKW64
:
5937 if (((CPUARMState
*)cpu_env
)->eabi
) {
5938 if (!lock_user_struct(VERIFY_READ
, target_efl
, arg3
, 1))
5940 fl
.l_type
= tswap16(target_efl
->l_type
);
5941 fl
.l_whence
= tswap16(target_efl
->l_whence
);
5942 fl
.l_start
= tswap64(target_efl
->l_start
);
5943 fl
.l_len
= tswap64(target_efl
->l_len
);
5944 fl
.l_pid
= tswapl(target_efl
->l_pid
);
5945 unlock_user_struct(target_efl
, arg3
, 0);
5949 if (!lock_user_struct(VERIFY_READ
, target_fl
, arg3
, 1))
5951 fl
.l_type
= tswap16(target_fl
->l_type
);
5952 fl
.l_whence
= tswap16(target_fl
->l_whence
);
5953 fl
.l_start
= tswap64(target_fl
->l_start
);
5954 fl
.l_len
= tswap64(target_fl
->l_len
);
5955 fl
.l_pid
= tswapl(target_fl
->l_pid
);
5956 unlock_user_struct(target_fl
, arg3
, 0);
5958 ret
= get_errno(fcntl(arg1
, cmd
, &fl
));
5961 ret
= do_fcntl(arg1
, cmd
, arg3
);
5967 #ifdef TARGET_NR_cacheflush
5968 case TARGET_NR_cacheflush
:
5969 /* self-modifying code is handled automatically, so nothing needed */
5973 #ifdef TARGET_NR_security
5974 case TARGET_NR_security
:
5977 #ifdef TARGET_NR_getpagesize
5978 case TARGET_NR_getpagesize
:
5979 ret
= TARGET_PAGE_SIZE
;
5982 case TARGET_NR_gettid
:
5983 ret
= get_errno(gettid());
5985 #ifdef TARGET_NR_readahead
5986 case TARGET_NR_readahead
:
5987 #if TARGET_ABI_BITS == 32
5989 if (((CPUARMState
*)cpu_env
)->eabi
)
5996 ret
= get_errno(readahead(arg1
, ((off64_t
)arg3
<< 32) | arg2
, arg4
));
5998 ret
= get_errno(readahead(arg1
, arg2
, arg3
));
6002 #ifdef TARGET_NR_setxattr
6003 case TARGET_NR_setxattr
:
6004 case TARGET_NR_lsetxattr
:
6005 case TARGET_NR_fsetxattr
:
6006 case TARGET_NR_getxattr
:
6007 case TARGET_NR_lgetxattr
:
6008 case TARGET_NR_fgetxattr
:
6009 case TARGET_NR_listxattr
:
6010 case TARGET_NR_llistxattr
:
6011 case TARGET_NR_flistxattr
:
6012 case TARGET_NR_removexattr
:
6013 case TARGET_NR_lremovexattr
:
6014 case TARGET_NR_fremovexattr
:
6015 goto unimplemented_nowarn
;
6017 #ifdef TARGET_NR_set_thread_area
6018 case TARGET_NR_set_thread_area
:
6019 #if defined(TARGET_MIPS)
6020 ((CPUMIPSState
*) cpu_env
)->tls_value
= arg1
;
6023 #elif defined(TARGET_CRIS)
6025 ret
= -TARGET_EINVAL
;
6027 ((CPUCRISState
*) cpu_env
)->pregs
[PR_PID
] = arg1
;
6031 #elif defined(TARGET_I386) && defined(TARGET_ABI32)
6032 ret
= do_set_thread_area(cpu_env
, arg1
);
6035 goto unimplemented_nowarn
;
6038 #ifdef TARGET_NR_get_thread_area
6039 case TARGET_NR_get_thread_area
:
6040 #if defined(TARGET_I386) && defined(TARGET_ABI32)
6041 ret
= do_get_thread_area(cpu_env
, arg1
);
6043 goto unimplemented_nowarn
;
6046 #ifdef TARGET_NR_getdomainname
6047 case TARGET_NR_getdomainname
:
6048 goto unimplemented_nowarn
;
6051 #ifdef TARGET_NR_clock_gettime
6052 case TARGET_NR_clock_gettime
:
6055 ret
= get_errno(clock_gettime(arg1
, &ts
));
6056 if (!is_error(ret
)) {
6057 host_to_target_timespec(arg2
, &ts
);
6062 #ifdef TARGET_NR_clock_getres
6063 case TARGET_NR_clock_getres
:
6066 ret
= get_errno(clock_getres(arg1
, &ts
));
6067 if (!is_error(ret
)) {
6068 host_to_target_timespec(arg2
, &ts
);
6073 #ifdef TARGET_NR_clock_nanosleep
6074 case TARGET_NR_clock_nanosleep
:
6077 target_to_host_timespec(&ts
, arg3
);
6078 ret
= get_errno(clock_nanosleep(arg1
, arg2
, &ts
, arg4
? &ts
: NULL
));
6080 host_to_target_timespec(arg4
, &ts
);
6085 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
6086 case TARGET_NR_set_tid_address
:
6087 ret
= get_errno(set_tid_address((int *)g2h(arg1
)));
6091 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
6092 case TARGET_NR_tkill
:
6093 ret
= get_errno(sys_tkill((int)arg1
, target_to_host_signal(arg2
)));
6097 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
6098 case TARGET_NR_tgkill
:
6099 ret
= get_errno(sys_tgkill((int)arg1
, (int)arg2
,
6100 target_to_host_signal(arg3
)));
6104 #ifdef TARGET_NR_set_robust_list
6105 case TARGET_NR_set_robust_list
:
6106 goto unimplemented_nowarn
;
6109 #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
6110 case TARGET_NR_utimensat
:
6112 struct timespec ts
[2];
6113 target_to_host_timespec(ts
, arg3
);
6114 target_to_host_timespec(ts
+1, arg3
+sizeof(struct target_timespec
));
6116 ret
= get_errno(sys_utimensat(arg1
, NULL
, ts
, arg4
));
6118 if (!(p
= lock_user_string(arg2
))) {
6119 ret
= -TARGET_EFAULT
;
6122 ret
= get_errno(sys_utimensat(arg1
, path(p
), ts
, arg4
));
6123 unlock_user(p
, arg2
, 0);
6128 #if defined(USE_NPTL)
6129 case TARGET_NR_futex
:
6130 ret
= do_futex(arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
6133 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
6134 case TARGET_NR_inotify_init
:
6135 ret
= get_errno(sys_inotify_init());
6138 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
6139 case TARGET_NR_inotify_add_watch
:
6140 p
= lock_user_string(arg2
);
6141 ret
= get_errno(sys_inotify_add_watch(arg1
, path(p
), arg3
));
6142 unlock_user(p
, arg2
, 0);
6145 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
6146 case TARGET_NR_inotify_rm_watch
:
6147 ret
= get_errno(sys_inotify_rm_watch(arg1
, arg2
));
6153 gemu_log("qemu: Unsupported syscall: %d\n", num
);
6154 #if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
6155 unimplemented_nowarn
:
6157 ret
= -TARGET_ENOSYS
;
6162 gemu_log(" = %ld\n", ret
);
6165 print_syscall_ret(num
, ret
);
6168 ret
= -TARGET_EFAULT
;