Remove reserved registers from tcg_target_reg_alloc_order
[qemu-kvm/fedora.git] / linux-user / syscall.c
blob052e8e6558beae88ad196b0c1c5d1ec834a19b6a
1 /*
2 * Linux syscalls
4 * Copyright (c) 2003 Fabrice Bellard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 * MA 02110-1301, USA.
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <stdarg.h>
24 #include <string.h>
25 #include <elf.h>
26 #include <endian.h>
27 #include <errno.h>
28 #include <unistd.h>
29 #include <fcntl.h>
30 #include <time.h>
31 #include <limits.h>
32 #include <sys/types.h>
33 #include <sys/ipc.h>
34 #include <sys/msg.h>
35 #include <sys/wait.h>
36 #include <sys/time.h>
37 #include <sys/stat.h>
38 #include <sys/mount.h>
39 #include <sys/prctl.h>
40 #include <sys/resource.h>
41 #include <sys/mman.h>
42 #include <sys/swap.h>
43 #include <signal.h>
44 #include <sched.h>
45 #include <sys/socket.h>
46 #include <sys/uio.h>
47 #include <sys/poll.h>
48 #include <sys/times.h>
49 #include <sys/shm.h>
50 #include <sys/sem.h>
51 #include <sys/statfs.h>
52 #include <utime.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>
58 #ifdef HAVE_GPROF
59 #include <sys/gmon.h>
60 #endif
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>
75 #include <linux/kd.h>
76 #include <linux/mtio.h>
77 #include "linux_loop.h"
79 #include "qemu.h"
80 #include "qemu-common.h"
82 #if defined(USE_NPTL)
83 #include <linux/futex.h>
84 #define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
85 CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
86 #else
87 /* XXX: Hardcode the above values. */
88 #define CLONE_NPTL_FLAGS2 0
89 #endif
91 //#define DEBUG
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 */
96 #define USE_UID16
97 #endif
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])
104 #undef _syscall0
105 #undef _syscall1
106 #undef _syscall2
107 #undef _syscall3
108 #undef _syscall4
109 #undef _syscall5
110 #undef _syscall6
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, \
143 type5,arg5) \
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, \
153 type6 arg6) \
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
190 #endif
192 #ifdef __NR_gettid
193 _syscall0(int, gettid)
194 #else
195 /* This is a replacement for the host gettid() and must return a host
196 errno. */
197 static int gettid(void) {
198 return -ENOSYS;
200 #endif
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)
204 #endif
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)
208 #endif
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)
212 #endif
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)
217 #endif
218 #if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
219 _syscall3(int,sys_futimesat,int,dirfd,const char *,pathname,
220 const struct timeval *,times)
221 #endif
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);
225 #endif
226 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
227 _syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
228 #endif
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);
233 #endif
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)
237 #endif
238 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
239 _syscall3(int,sys_mkdirat,int,dirfd,const char *,pathname,mode_t,mode)
240 #endif
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)
244 #endif
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)
249 #endif
250 #if defined(TARGET_NR_openat) && defined(__NR_openat)
251 _syscall4(int,sys_openat,int,dirfd,const char *,pathname,int,flags,mode_t,mode)
252 #endif
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)
256 #endif
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)
260 #endif
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)
265 #endif
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)
269 #endif
270 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
271 _syscall2(int,sys_tkill,int,tid,int,sig)
272 #endif
273 #ifdef __NR_exit_group
274 _syscall1(int,exit_group,int,error_code)
275 #endif
276 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
277 _syscall1(int,set_tid_address,int *,tidptr)
278 #endif
279 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
280 _syscall3(int,sys_unlinkat,int,dirfd,const char *,pathname,int,flags)
281 #endif
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)
285 #endif
286 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
287 _syscall0(int,sys_inotify_init)
288 #endif
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)
291 #endif
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)
294 #endif
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)
299 #endif
300 #endif
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,
407 #ifdef ENOKEY
408 [ENOKEY] = TARGET_ENOKEY,
409 #endif
410 #ifdef EKEYEXPIRED
411 [EKEYEXPIRED] = TARGET_EKEYEXPIRED,
412 #endif
413 #ifdef EKEYREVOKED
414 [EKEYREVOKED] = TARGET_EKEYREVOKED,
415 #endif
416 #ifdef EKEYREJECTED
417 [EKEYREJECTED] = TARGET_EKEYREJECTED,
418 #endif
419 #ifdef EOWNERDEAD
420 [EOWNERDEAD] = TARGET_EOWNERDEAD,
421 #endif
422 #ifdef ENOTRECOVERABLE
423 [ENOTRECOVERABLE] = TARGET_ENOTRECOVERABLE,
424 #endif
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];
431 return 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];
438 return err;
441 static inline abi_long get_errno(abi_long ret)
443 if (ret == -1)
444 return -host_to_target_errno(errno);
445 else
446 return ret;
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)
470 abi_ulong brk_page;
471 abi_long mapped_addr;
472 int new_alloc_size;
474 if (!new_brk)
475 return target_brk;
476 if (new_brk < target_original_brk)
477 return target_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;
484 return target_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;
496 return target_brk;
499 static inline abi_long copy_from_user_fdset(fd_set *fds,
500 abi_ulong target_fds_addr,
501 int n)
503 int i, nw, j, k;
504 abi_ulong b, *target_fds;
506 nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
507 if (!(target_fds = lock_user(VERIFY_READ,
508 target_fds_addr,
509 sizeof(abi_ulong) * nw,
510 1)))
511 return -TARGET_EFAULT;
513 FD_ZERO(fds);
514 k = 0;
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 */
520 if ((b >> j) & 1)
521 FD_SET(k, fds);
522 k++;
526 unlock_user(target_fds, target_fds_addr, 0);
528 return 0;
531 static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
532 const fd_set *fds,
533 int n)
535 int i, nw, j, k;
536 abi_long v;
537 abi_ulong *target_fds;
539 nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
540 if (!(target_fds = lock_user(VERIFY_WRITE,
541 target_fds_addr,
542 sizeof(abi_ulong) * nw,
543 0)))
544 return -TARGET_EFAULT;
546 k = 0;
547 for (i = 0; i < nw; i++) {
548 v = 0;
549 for (j = 0; j < TARGET_ABI_BITS; j++) {
550 v |= ((FD_ISSET(k, fds) != 0) << j);
551 k++;
553 __put_user(v, &target_fds[i]);
556 unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
558 return 0;
561 #if defined(__alpha__)
562 #define HOST_HZ 1024
563 #else
564 #define HOST_HZ 100
565 #endif
567 static inline abi_long host_to_target_clock_t(long ticks)
569 #if HOST_HZ == TARGET_HZ
570 return ticks;
571 #else
572 return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
573 #endif
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);
603 return 0;
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);
619 return 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);
635 return 0;
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;
647 abi_long ret;
649 if (rfd_addr) {
650 if (copy_from_user_fdset(&rfds, rfd_addr, n))
651 return -TARGET_EFAULT;
652 rfds_ptr = &rfds;
653 } else {
654 rfds_ptr = NULL;
656 if (wfd_addr) {
657 if (copy_from_user_fdset(&wfds, wfd_addr, n))
658 return -TARGET_EFAULT;
659 wfds_ptr = &wfds;
660 } else {
661 wfds_ptr = NULL;
663 if (efd_addr) {
664 if (copy_from_user_fdset(&efds, efd_addr, n))
665 return -TARGET_EFAULT;
666 efds_ptr = &efds;
667 } else {
668 efds_ptr = NULL;
671 if (target_tv_addr) {
672 if (copy_from_user_timeval(&tv, target_tv_addr))
673 return -TARGET_EFAULT;
674 tv_ptr = &tv;
675 } else {
676 tv_ptr = NULL;
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;
693 return ret;
696 static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
697 abi_ulong target_addr,
698 socklen_t len)
700 struct target_sockaddr *target_saddr;
702 target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
703 if (!target_saddr)
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);
709 return 0;
712 static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
713 struct sockaddr *addr,
714 socklen_t len)
716 struct target_sockaddr *target_saddr;
718 target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
719 if (!target_saddr)
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);
725 return 0;
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;
736 socklen_t space = 0;
738 msg_controllen = tswapl(target_msgh->msg_controllen);
739 if (msg_controllen < sizeof (struct target_cmsghdr))
740 goto the_end;
741 target_cmsg_addr = tswapl(target_msgh->msg_control);
742 target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
743 if (!target_cmsg)
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");
757 break;
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);
767 } else {
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);
780 the_end:
781 msgh->msg_controllen = space;
782 return 0;
785 /* ??? Should this also swap msgh->name? */
786 static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
787 struct msghdr *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;
793 socklen_t space = 0;
795 msg_controllen = tswapl(target_msgh->msg_controllen);
796 if (msg_controllen < sizeof (struct target_cmsghdr))
797 goto the_end;
798 target_cmsg_addr = tswapl(target_msgh->msg_control);
799 target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
800 if (!target_cmsg)
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");
813 break;
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);
823 } else {
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);
836 the_end:
837 target_msgh->msg_controllen = tswapl(space);
838 return 0;
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)
845 abi_long ret;
846 int val;
848 switch(level) {
849 case SOL_TCP:
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)));
857 break;
858 case SOL_IP:
859 switch(optname) {
860 case IP_TOS:
861 case IP_TTL:
862 case IP_HDRINCL:
863 case IP_ROUTER_ALERT:
864 case IP_RECVOPTS:
865 case IP_RETOPTS:
866 case IP_PKTINFO:
867 case IP_MTU_DISCOVER:
868 case IP_RECVERR:
869 case IP_RECVTOS:
870 #ifdef IP_FREEBIND
871 case IP_FREEBIND:
872 #endif
873 case IP_MULTICAST_TTL:
874 case IP_MULTICAST_LOOP:
875 val = 0;
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)));
884 break;
885 default:
886 goto unimplemented;
888 break;
889 case TARGET_SOL_SOCKET:
890 switch (optname) {
891 /* Options with 'int' argument. */
892 case TARGET_SO_DEBUG:
893 optname = SO_DEBUG;
894 break;
895 case TARGET_SO_REUSEADDR:
896 optname = SO_REUSEADDR;
897 break;
898 case TARGET_SO_TYPE:
899 optname = SO_TYPE;
900 break;
901 case TARGET_SO_ERROR:
902 optname = SO_ERROR;
903 break;
904 case TARGET_SO_DONTROUTE:
905 optname = SO_DONTROUTE;
906 break;
907 case TARGET_SO_BROADCAST:
908 optname = SO_BROADCAST;
909 break;
910 case TARGET_SO_SNDBUF:
911 optname = SO_SNDBUF;
912 break;
913 case TARGET_SO_RCVBUF:
914 optname = SO_RCVBUF;
915 break;
916 case TARGET_SO_KEEPALIVE:
917 optname = SO_KEEPALIVE;
918 break;
919 case TARGET_SO_OOBINLINE:
920 optname = SO_OOBINLINE;
921 break;
922 case TARGET_SO_NO_CHECK:
923 optname = SO_NO_CHECK;
924 break;
925 case TARGET_SO_PRIORITY:
926 optname = SO_PRIORITY;
927 break;
928 #ifdef SO_BSDCOMPAT
929 case TARGET_SO_BSDCOMPAT:
930 optname = SO_BSDCOMPAT;
931 break;
932 #endif
933 case TARGET_SO_PASSCRED:
934 optname = SO_PASSCRED;
935 break;
936 case TARGET_SO_TIMESTAMP:
937 optname = SO_TIMESTAMP;
938 break;
939 case TARGET_SO_RCVLOWAT:
940 optname = SO_RCVLOWAT;
941 break;
942 case TARGET_SO_RCVTIMEO:
943 optname = SO_RCVTIMEO;
944 break;
945 case TARGET_SO_SNDTIMEO:
946 optname = SO_SNDTIMEO;
947 break;
948 break;
949 default:
950 goto unimplemented;
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)));
958 break;
959 default:
960 unimplemented:
961 gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
962 ret = -TARGET_ENOPROTOOPT;
964 return ret;
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)
971 abi_long ret;
972 int len, val;
973 socklen_t lv;
975 switch(level) {
976 case TARGET_SOL_SOCKET:
977 level = SOL_SOCKET;
978 switch (optname) {
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 */
985 goto unimplemented;
986 default:
987 goto int_case;
989 break;
990 case SOL_TCP:
991 /* TCP options all take an 'int' value. */
992 int_case:
993 if (get_user_u32(len, optlen))
994 return -TARGET_EFAULT;
995 if (len < 0)
996 return -TARGET_EINVAL;
997 lv = sizeof(int);
998 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
999 if (ret < 0)
1000 return ret;
1001 val = tswap32(val);
1002 if (len > lv)
1003 len = lv;
1004 if (len == 4) {
1005 if (put_user_u32(val, optval_addr))
1006 return -TARGET_EFAULT;
1007 } else {
1008 if (put_user_u8(val, optval_addr))
1009 return -TARGET_EFAULT;
1011 if (put_user_u32(len, optlen))
1012 return -TARGET_EFAULT;
1013 break;
1014 case SOL_IP:
1015 switch(optname) {
1016 case IP_TOS:
1017 case IP_TTL:
1018 case IP_HDRINCL:
1019 case IP_ROUTER_ALERT:
1020 case IP_RECVOPTS:
1021 case IP_RETOPTS:
1022 case IP_PKTINFO:
1023 case IP_MTU_DISCOVER:
1024 case IP_RECVERR:
1025 case IP_RECVTOS:
1026 #ifdef IP_FREEBIND
1027 case IP_FREEBIND:
1028 #endif
1029 case IP_MULTICAST_TTL:
1030 case IP_MULTICAST_LOOP:
1031 if (get_user_u32(len, optlen))
1032 return -TARGET_EFAULT;
1033 if (len < 0)
1034 return -TARGET_EINVAL;
1035 lv = sizeof(int);
1036 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1037 if (ret < 0)
1038 return ret;
1039 if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
1040 len = 1;
1041 if (put_user_u32(len, optlen)
1042 || put_user_u8(val, optval_addr))
1043 return -TARGET_EFAULT;
1044 } else {
1045 if (len > sizeof(int))
1046 len = sizeof(int);
1047 if (put_user_u32(len, optlen)
1048 || put_user_u32(val, optval_addr))
1049 return -TARGET_EFAULT;
1051 break;
1052 default:
1053 ret = -TARGET_ENOPROTOOPT;
1054 break;
1056 break;
1057 default:
1058 unimplemented:
1059 gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1060 level, optname);
1061 ret = -TARGET_EOPNOTSUPP;
1062 break;
1064 return ret;
1067 /* FIXME
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;
1075 abi_ulong base;
1076 int i;
1078 target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1079 if (!target_vec)
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. */
1088 } else {
1089 /* zero length pointer is ignored */
1090 vec[i].iov_base = NULL;
1093 unlock_user (target_vec, target_addr, 0);
1094 return 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;
1101 abi_ulong base;
1102 int i;
1104 target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1105 if (!target_vec)
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);
1115 return 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)
1122 switch(type) {
1123 case TARGET_SOCK_DGRAM:
1124 type = SOCK_DGRAM;
1125 break;
1126 case TARGET_SOCK_STREAM:
1127 type = SOCK_STREAM;
1128 break;
1129 case TARGET_SOCK_RAW:
1130 type = SOCK_RAW;
1131 break;
1132 case TARGET_SOCK_RDM:
1133 type = SOCK_RDM;
1134 break;
1135 case TARGET_SOCK_SEQPACKET:
1136 type = SOCK_SEQPACKET;
1137 break;
1138 case TARGET_SOCK_PACKET:
1139 type = SOCK_PACKET;
1140 break;
1142 #endif
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,
1153 socklen_t addrlen)
1155 void *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,
1168 socklen_t addrlen)
1170 void *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)
1185 abi_long ret, len;
1186 struct target_msghdr *msgp;
1187 struct msghdr msg;
1188 int count;
1189 struct iovec *vec;
1190 abi_ulong target_vec;
1192 /* FIXME */
1193 if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1194 msgp,
1195 target_msg,
1196 send ? 1 : 0))
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),
1202 msg.msg_namelen);
1203 } else {
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;
1216 msg.msg_iov = vec;
1218 if (send) {
1219 ret = target_to_host_cmsg(&msg, msgp);
1220 if (ret == 0)
1221 ret = get_errno(sendmsg(fd, &msg, flags));
1222 } else {
1223 ret = get_errno(recvmsg(fd, &msg, flags));
1224 if (!is_error(ret)) {
1225 len = ret;
1226 ret = host_to_target_cmsg(msgp, &msg);
1227 if (!is_error(ret))
1228 ret = len;
1231 unlock_iovec(vec, target_vec, count, !send);
1232 unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1233 return ret;
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)
1240 socklen_t addrlen;
1241 void *addr;
1242 abi_long ret;
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;
1258 return ret;
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)
1265 socklen_t addrlen;
1266 void *addr;
1267 abi_long ret;
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;
1283 return ret;
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)
1290 socklen_t addrlen;
1291 void *addr;
1292 abi_long ret;
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;
1311 return ret;
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)
1318 int tab[2];
1319 abi_long ret;
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;
1327 return ret;
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)
1334 void *addr;
1335 void *host_msg;
1336 abi_long ret;
1338 if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
1339 return -TARGET_EINVAL;
1341 host_msg = lock_user(VERIFY_READ, msg, len, 1);
1342 if (!host_msg)
1343 return -TARGET_EFAULT;
1344 if (target_addr) {
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));
1348 } else {
1349 ret = get_errno(send(fd, host_msg, len, flags));
1351 unlock_user(host_msg, msg, 0);
1352 return ret;
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)
1360 socklen_t addrlen;
1361 void *addr;
1362 void *host_msg;
1363 abi_long ret;
1365 host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
1366 if (!host_msg)
1367 return -TARGET_EFAULT;
1368 if (target_addr) {
1369 if (get_user_u32(addrlen, target_addrlen)) {
1370 ret = -TARGET_EFAULT;
1371 goto fail;
1373 if (addrlen < 0 || addrlen > MAX_SOCK_ADDR) {
1374 ret = -TARGET_EINVAL;
1375 goto fail;
1377 addr = alloca(addrlen);
1378 ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
1379 } else {
1380 addr = NULL; /* To keep compiler quiet. */
1381 ret = get_errno(recv(fd, host_msg, len, flags));
1383 if (!is_error(ret)) {
1384 if (target_addr) {
1385 host_to_target_sockaddr(target_addr, addr, addrlen);
1386 if (put_user_u32(addrlen, target_addrlen)) {
1387 ret = -TARGET_EFAULT;
1388 goto fail;
1391 unlock_user(host_msg, msg, len);
1392 } else {
1393 fail:
1394 unlock_user(host_msg, msg, 0);
1396 return ret;
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)
1403 abi_long ret;
1404 const int n = sizeof(abi_ulong);
1406 switch(num) {
1407 case SOCKOP_socket:
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);
1418 break;
1419 case SOCKOP_bind:
1421 int sockfd;
1422 abi_ulong target_addr;
1423 socklen_t addrlen;
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);
1432 break;
1433 case SOCKOP_connect:
1435 int sockfd;
1436 abi_ulong target_addr;
1437 socklen_t addrlen;
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);
1446 break;
1447 case SOCKOP_listen:
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));
1457 break;
1458 case SOCKOP_accept:
1460 int sockfd;
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);
1470 break;
1471 case SOCKOP_getsockname:
1473 int sockfd;
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);
1483 break;
1484 case SOCKOP_getpeername:
1486 int sockfd;
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);
1496 break;
1497 case SOCKOP_socketpair:
1499 int domain, type, protocol;
1500 abi_ulong tab;
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);
1510 break;
1511 case SOCKOP_send:
1513 int sockfd;
1514 abi_ulong msg;
1515 size_t len;
1516 int flags;
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);
1526 break;
1527 case SOCKOP_recv:
1529 int sockfd;
1530 abi_ulong msg;
1531 size_t len;
1532 int flags;
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);
1542 break;
1543 case SOCKOP_sendto:
1545 int sockfd;
1546 abi_ulong msg;
1547 size_t len;
1548 int flags;
1549 abi_ulong addr;
1550 socklen_t addrlen;
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);
1562 break;
1563 case SOCKOP_recvfrom:
1565 int sockfd;
1566 abi_ulong msg;
1567 size_t len;
1568 int flags;
1569 abi_ulong addr;
1570 socklen_t addrlen;
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);
1582 break;
1583 case SOCKOP_shutdown:
1585 int sockfd, how;
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));
1593 break;
1594 case SOCKOP_sendmsg:
1595 case SOCKOP_recvmsg:
1597 int fd;
1598 abi_ulong target_msg;
1599 int flags;
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));
1609 break;
1610 case SOCKOP_setsockopt:
1612 int sockfd;
1613 int level;
1614 int optname;
1615 abi_ulong optval;
1616 socklen_t optlen;
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);
1627 break;
1628 case SOCKOP_getsockopt:
1630 int sockfd;
1631 int level;
1632 int optname;
1633 abi_ulong optval;
1634 socklen_t optlen;
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);
1645 break;
1646 default:
1647 gemu_log("Unsupported socketcall: %d\n", num);
1648 ret = -TARGET_ENOSYS;
1649 break;
1651 return ret;
1653 #endif
1655 #ifdef TARGET_NR_ipc
1656 #define N_SHM_REGIONS 32
1658 static struct shm_region {
1659 abi_ulong start;
1660 abi_ulong size;
1661 } shm_regions[N_SHM_REGIONS];
1662 #endif
1664 struct target_ipc_perm
1666 abi_long __key;
1667 abi_ulong uid;
1668 abi_ulong gid;
1669 abi_ulong cuid;
1670 abi_ulong cgid;
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);
1707 return 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);
1726 return 0;
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);
1741 return 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);
1756 return 0;
1759 union semun {
1760 int val;
1761 struct semid_ds *buf;
1762 unsigned short *array;
1765 union target_semun {
1766 int val;
1767 abi_long buf;
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;
1778 switch( cmd ) {
1779 case IPC_STAT:
1780 case IPC_SET:
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);
1784 host_su->buf = ds;
1785 unlock_user_struct(target_su, target_addr, 0);
1786 break;
1787 case GETVAL:
1788 case SETVAL:
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);
1793 break;
1794 case GETALL:
1795 case SETALL:
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);
1800 break;
1801 default:
1802 gemu_log("semun operation not fully supported: %d\n", (int)cmd);
1804 return 0;
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;
1814 switch( cmd ) {
1815 case IPC_STAT:
1816 case IPC_SET:
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);
1821 break;
1822 case GETVAL:
1823 case SETVAL:
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);
1828 break;
1829 case GETALL:
1830 case SETALL:
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);
1835 break;
1836 default:
1837 gemu_log("semun operation not fully supported: %d\n", (int)cmd);
1839 return 0;
1842 static inline abi_long do_semctl(int first, int second, int third,
1843 abi_long ptr)
1845 union semun arg;
1846 struct semid_ds dsarg;
1847 int cmd = third&0xff;
1848 abi_long ret = 0;
1850 switch( cmd ) {
1851 case GETVAL:
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);
1855 break;
1856 case SETVAL:
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);
1860 break;
1861 case GETALL:
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);
1865 break;
1866 case SETALL:
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);
1870 break;
1871 case IPC_STAT:
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);
1875 break;
1876 case IPC_SET:
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);
1880 break;
1881 default:
1882 ret = get_errno(semctl(first, second, cmd, arg));
1885 return ret;
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;
1894 #endif
1895 abi_ulong msg_rtime;
1896 #if TARGET_ABI_BITS == 32
1897 abi_ulong __unused2;
1898 #endif
1899 abi_ulong msg_ctime;
1900 #if TARGET_ABI_BITS == 32
1901 abi_ulong __unused3;
1902 #endif
1903 abi_ulong __msg_cbytes;
1904 abi_ulong msg_qnum;
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);
1930 return 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);
1951 return 0;
1954 struct target_msginfo {
1955 int msgpool;
1956 int msgmap;
1957 int msgmax;
1958 int msgmnb;
1959 int msgmni;
1960 int msgssz;
1961 int msgtql;
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);
1980 return 0;
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;
1989 cmd &= 0xff;
1991 switch (cmd) {
1992 case IPC_STAT:
1993 case IPC_SET:
1994 case MSG_STAT:
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;
2000 break;
2001 case IPC_RMID:
2002 ret = get_errno(msgctl(msgid, cmd, NULL));
2003 break;
2004 case IPC_INFO:
2005 case MSG_INFO:
2006 ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
2007 if (host_to_target_msginfo(ptr, &msginfo))
2008 return -TARGET_EFAULT;
2009 break;
2012 return ret;
2015 struct target_msgbuf {
2016 abi_long mtype;
2017 char mtext[1];
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;
2025 abi_long ret = 0;
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));
2033 free(host_mb);
2034 unlock_user_struct(target_mb, msgp, 0);
2036 return ret;
2039 static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2040 unsigned int msgsz, abi_long msgtyp,
2041 int msgflg)
2043 struct target_msgbuf *target_mb;
2044 char *target_mtext;
2045 struct msgbuf *host_mb;
2046 abi_long ret = 0;
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));
2054 if (ret > 0) {
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;
2059 goto end;
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);
2066 free(host_mb);
2068 end:
2069 if (target_mb)
2070 unlock_user_struct(target_mb, msgp, 1);
2071 return ret;
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)
2081 int version;
2082 abi_long ret = 0;
2083 struct shmid_ds shm_info;
2084 int i;
2086 version = call >> 16;
2087 call &= 0xffff;
2089 switch (call) {
2090 case IPCOP_semop:
2091 ret = get_errno(semop(first,(struct sembuf *)g2h(ptr), second));
2092 break;
2094 case IPCOP_semget:
2095 ret = get_errno(semget(first, second, third));
2096 break;
2098 case IPCOP_semctl:
2099 ret = do_semctl(first, second, third, ptr);
2100 break;
2102 case IPCOP_semtimedop:
2103 gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2104 ret = -TARGET_ENOSYS;
2105 break;
2107 case IPCOP_msgget:
2108 ret = get_errno(msgget(first, second));
2109 break;
2111 case IPCOP_msgsnd:
2112 ret = do_msgsnd(first, ptr, second, third);
2113 break;
2115 case IPCOP_msgctl:
2116 ret = do_msgctl(first, second, ptr);
2117 break;
2119 case IPCOP_msgrcv:
2120 switch (version) {
2121 case 0:
2123 struct target_ipc_kludge {
2124 abi_long msgp;
2125 abi_long msgtyp;
2126 } *tmp;
2128 if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
2129 ret = -TARGET_EFAULT;
2130 break;
2133 ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
2135 unlock_user_struct(tmp, ptr, 0);
2136 break;
2138 default:
2139 ret = do_msgrcv(first, ptr, second, fifth, third);
2141 break;
2143 case IPCOP_shmat:
2145 abi_ulong raddr;
2146 void *host_addr;
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);
2151 break;
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 */
2159 shmdt(host_addr);
2160 break;
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;
2169 break;
2172 if (put_user_ual(raddr, third))
2173 return -TARGET_EFAULT;
2174 ret = 0;
2176 break;
2177 case IPCOP_shmdt:
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);
2182 break;
2185 ret = get_errno(shmdt((void *)g2h(ptr)));
2186 break;
2188 case IPCOP_shmget:
2189 /* IPC_* flag values are the same on all linux platforms */
2190 ret = get_errno(shmget(first, second, third));
2191 break;
2193 /* IPC_* and SHM_* command values are the same on all linux platforms */
2194 case IPCOP_shmctl:
2195 switch(second) {
2196 case IPC_RMID:
2197 case SHM_LOCK:
2198 case SHM_UNLOCK:
2199 ret = get_errno(shmctl(first, second, NULL));
2200 break;
2201 default:
2202 goto unimplemented;
2204 break;
2205 default:
2206 unimplemented:
2207 gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2208 ret = -TARGET_ENOSYS;
2209 break;
2211 return ret;
2213 #endif
2215 /* kernel structure types definitions */
2216 #define IFNAMSIZ 16
2218 #define STRUCT(name, list...) STRUCT_ ## name,
2219 #define STRUCT_SPECIAL(name) STRUCT_ ## name,
2220 enum {
2221 #include "syscall_types.h"
2223 #undef STRUCT
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"
2229 #undef STRUCT
2230 #undef STRUCT_SPECIAL
2232 typedef struct IOCTLEntry {
2233 unsigned int target_cmd;
2234 unsigned int host_cmd;
2235 const char *name;
2236 int access;
2237 const argtype arg_type[5];
2238 } IOCTLEntry;
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 } },
2249 #include "ioctls.h"
2250 { 0, 0, },
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;
2259 abi_long ret;
2260 uint8_t buf_temp[MAX_STRUCT_SIZE];
2261 int target_size;
2262 void *argptr;
2264 ie = ioctl_entries;
2265 for(;;) {
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)
2271 break;
2272 ie++;
2274 arg_type = ie->arg_type;
2275 #if defined(DEBUG)
2276 gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
2277 #endif
2278 switch(arg_type[0]) {
2279 case TYPE_NULL:
2280 /* no argument */
2281 ret = get_errno(ioctl(fd, ie->host_cmd));
2282 break;
2283 case TYPE_PTRVOID:
2284 case TYPE_INT:
2285 /* int argment */
2286 ret = get_errno(ioctl(fd, ie->host_cmd, arg));
2287 break;
2288 case TYPE_PTR:
2289 arg_type++;
2290 target_size = thunk_type_size(arg_type, 0);
2291 switch(ie->access) {
2292 case IOC_R:
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);
2296 if (!argptr)
2297 return -TARGET_EFAULT;
2298 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2299 unlock_user(argptr, arg, target_size);
2301 break;
2302 case IOC_W:
2303 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2304 if (!argptr)
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));
2309 break;
2310 default:
2311 case IOC_RW:
2312 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2313 if (!argptr)
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);
2320 if (!argptr)
2321 return -TARGET_EFAULT;
2322 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2323 unlock_user(argptr, arg, target_size);
2325 break;
2327 break;
2328 default:
2329 gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
2330 (long)cmd, arg_type[0]);
2331 ret = -TARGET_ENOSYS;
2332 break;
2334 return ret;
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 },
2352 { 0, 0, 0, 0 }
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 },
2380 { 0, 0, 0, 0 }
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 },
2415 { 0, 0, 0, 0 }
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 },
2434 { 0, 0, 0, 0 }
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;
2442 host->c_iflag =
2443 target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
2444 host->c_oflag =
2445 target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
2446 host->c_cflag =
2447 target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
2448 host->c_lflag =
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;
2476 target->c_iflag =
2477 tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
2478 target->c_oflag =
2479 tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
2480 target->c_cflag =
2481 tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
2482 target->c_lflag =
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 },
2520 { 0, 0, 0, 0 }
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, },
2539 #endif
2540 { 0, 0, 0, 0 }
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)
2550 int size;
2551 void *p;
2553 if (!ldt_table)
2554 return 0;
2555 size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
2556 if (size > bytecount)
2557 size = bytecount;
2558 p = lock_user(VERIFY_WRITE, ptr, size, 0);
2559 if (!p)
2560 return -TARGET_EFAULT;
2561 /* ??? Should this by byteswapped? */
2562 memcpy(p, ldt_table, size);
2563 unlock_user(p, ptr, size);
2564 return 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;
2595 #ifdef TARGET_ABI32
2596 lm = 0;
2597 #else
2598 lm = (ldt_info.flags >> 7) & 1;
2599 #endif
2600 if (contents == 3) {
2601 if (oldmode)
2602 return -TARGET_EINVAL;
2603 if (seg_not_present == 0)
2604 return -TARGET_EINVAL;
2606 /* allocate the LDT */
2607 if (!ldt_table) {
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) {
2623 if (oldmode ||
2624 (contents == 0 &&
2625 read_exec_only == 1 &&
2626 seg_32bit == 0 &&
2627 limit_in_pages == 0 &&
2628 seg_not_present == 1 &&
2629 useable == 0 )) {
2630 entry_1 = 0;
2631 entry_2 = 0;
2632 goto install;
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) |
2642 (contents << 10) |
2643 ((seg_not_present ^ 1) << 15) |
2644 (seg_32bit << 22) |
2645 (limit_in_pages << 23) |
2646 (lm << 21) |
2647 0x7000;
2648 if (!oldmode)
2649 entry_2 |= (useable << 20);
2651 /* Install the new entry ... */
2652 install:
2653 lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
2654 lp[0] = tswap32(entry_1);
2655 lp[1] = tswap32(entry_2);
2656 return 0;
2659 /* specific and weird i386 syscalls */
2660 static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
2661 unsigned long bytecount)
2663 abi_long ret;
2665 switch (func) {
2666 case 0:
2667 ret = read_ldt(ptr, bytecount);
2668 break;
2669 case 1:
2670 ret = write_ldt(env, ptr, bytecount, 1);
2671 break;
2672 case 0x11:
2673 ret = write_ldt(env, ptr, bytecount, 0);
2674 break;
2675 default:
2676 ret = -TARGET_ENOSYS;
2677 break;
2679 return ret;
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;
2691 int i;
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);
2705 break;
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;
2720 #ifdef TARGET_ABI32
2721 lm = 0;
2722 #else
2723 lm = (ldt_info.flags >> 7) & 1;
2724 #endif
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 &&
2736 seg_32bit == 0 &&
2737 limit_in_pages == 0 &&
2738 seg_not_present == 1 &&
2739 useable == 0 )) {
2740 entry_1 = 0;
2741 entry_2 = 0;
2742 goto install;
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) |
2752 (contents << 10) |
2753 ((seg_not_present ^ 1) << 15) |
2754 (seg_32bit << 22) |
2755 (limit_in_pages << 23) |
2756 (useable << 20) |
2757 (lm << 21) |
2758 0x7000;
2760 /* Install the new entry ... */
2761 install:
2762 lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
2763 lp[0] = tswap32(entry_1);
2764 lp[1] = tswap32(entry_2);
2765 return 0;
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;
2796 #ifdef TARGET_ABI32
2797 lm = 0;
2798 #else
2799 lm = (entry_2 >> 21) & 1;
2800 #endif
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);
2812 return 0;
2814 #endif /* TARGET_I386 && TARGET_ABI32 */
2816 #ifndef TARGET_ABI32
2817 static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
2819 abi_long ret;
2820 abi_ulong val;
2821 int idx;
2823 switch(code) {
2824 case TARGET_ARCH_SET_GS:
2825 case TARGET_ARCH_SET_FS:
2826 if (code == TARGET_ARCH_SET_GS)
2827 idx = R_GS;
2828 else
2829 idx = R_FS;
2830 cpu_x86_load_seg(env, idx, 0);
2831 env->segs[idx].base = addr;
2832 break;
2833 case TARGET_ARCH_GET_GS:
2834 case TARGET_ARCH_GET_FS:
2835 if (code == TARGET_ARCH_GET_GS)
2836 idx = R_GS;
2837 else
2838 idx = R_FS;
2839 val = env->segs[idx].base;
2840 if (put_user(val, addr, abi_ulong))
2841 return -TARGET_EFAULT;
2842 break;
2843 default:
2844 ret = -TARGET_EINVAL;
2845 break;
2847 return 0;
2849 #endif
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;
2858 typedef struct {
2859 CPUState *env;
2860 pthread_mutex_t mutex;
2861 pthread_cond_t cond;
2862 pthread_t thread;
2863 uint32_t tid;
2864 abi_ulong child_tidptr;
2865 abi_ulong parent_tidptr;
2866 sigset_t sigmask;
2867 } new_thread_info;
2869 static void *clone_func(void *arg)
2871 new_thread_info *info = arg;
2872 CPUState *env;
2874 env = info->env;
2875 thread_env = env;
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);
2890 cpu_loop(env);
2891 /* never exits */
2892 return NULL;
2894 #else
2895 /* this stack is the equivalent of the kernel stack associated with a
2896 thread/process */
2897 #define NEW_STACK_SIZE 8192
2899 static int clone_func(void *arg)
2901 CPUState *env = arg;
2902 cpu_loop(env);
2903 /* never exits */
2904 return 0;
2906 #endif
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)
2914 int ret;
2915 TaskState *ts;
2916 uint8_t *new_stack;
2917 CPUState *new_env;
2918 #if defined(USE_NPTL)
2919 unsigned int nptl_flags;
2920 sigset_t sigmask;
2921 #endif
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;
2931 #endif
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)
2941 nptl_flags = flags;
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);
2958 info.env = new_env;
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);
2976 if (ret == 0) {
2977 /* Wait for the child to initialize. */
2978 pthread_cond_wait(&info.cond, &info.mutex);
2979 ret = info.tid;
2980 if (flags & CLONE_PARENT_SETTID)
2981 put_user_u32(ret, parent_tidptr);
2982 } else {
2983 ret = -1;
2985 pthread_mutex_unlock(&info.mutex);
2986 pthread_cond_destroy(&info.cond);
2987 pthread_mutex_destroy(&info.mutex);
2988 pthread_mutex_unlock(&clone_lock);
2989 #else
2990 if (flags & CLONE_NPTL_FLAGS2)
2991 return -EINVAL;
2992 /* This is probably going to die very quickly, but do it anyway. */
2993 #ifdef __ia64__
2994 ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
2995 #else
2996 ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
2997 #endif
2998 #endif
2999 } else {
3000 /* if no CLONE_VM, we consider it is a fork */
3001 if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
3002 return -EINVAL;
3003 fork_start();
3004 ret = fork();
3005 if (ret == 0) {
3006 /* Child Process. */
3007 cpu_clone_regs(env, newsp);
3008 fork_end(1);
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;
3025 #endif
3026 } else {
3027 fork_end(0);
3030 return ret;
3033 static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
3035 struct flock fl;
3036 struct target_flock *target_fl;
3037 struct flock64 fl64;
3038 struct target_flock64 *target_fl64;
3039 abi_long ret;
3041 switch(cmd) {
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));
3052 if (ret == 0) {
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);
3062 break;
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));
3075 break;
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));
3087 if (ret == 0) {
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);
3097 break;
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));
3109 break;
3111 case F_GETFL:
3112 ret = get_errno(fcntl(fd, cmd, arg));
3113 if (ret >= 0) {
3114 ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
3116 break;
3118 case F_SETFL:
3119 ret = get_errno(fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
3120 break;
3122 default:
3123 ret = get_errno(fcntl(fd, cmd, arg));
3124 break;
3126 return ret;
3129 #ifdef USE_UID16
3131 static inline int high2lowuid(int uid)
3133 if (uid > 65535)
3134 return 65534;
3135 else
3136 return uid;
3139 static inline int high2lowgid(int gid)
3141 if (gid > 65535)
3142 return 65534;
3143 else
3144 return gid;
3147 static inline int low2highuid(int uid)
3149 if ((int16_t)uid == -1)
3150 return -1;
3151 else
3152 return uid;
3155 static inline int low2highgid(int gid)
3157 if ((int16_t)gid == -1)
3158 return -1;
3159 else
3160 return gid;
3163 #endif /* USE_UID16 */
3165 void syscall_init(void)
3167 IOCTLEntry *ie;
3168 const argtype *arg_type;
3169 int size;
3170 int i;
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"
3175 #undef STRUCT
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 */
3180 ie = ioctl_entries;
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",
3187 ie->target_cmd);
3188 exit(1);
3190 arg_type++;
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);
3209 #endif
3210 ie++;
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;
3219 #else
3220 return ((uint64_t)word1 << 32) | word0;
3221 #endif
3223 #else /* TARGET_ABI_BITS == 32 */
3224 static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
3226 return word0;
3228 #endif /* TARGET_ABI_BITS != 32 */
3230 #ifdef TARGET_NR_truncate64
3231 static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
3232 abi_long arg2,
3233 abi_long arg3,
3234 abi_long arg4)
3236 #ifdef TARGET_ARM
3237 if (((CPUARMState *)cpu_env)->eabi)
3239 arg2 = arg3;
3240 arg3 = arg4;
3242 #endif
3243 return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
3245 #endif
3247 #ifdef TARGET_NR_ftruncate64
3248 static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
3249 abi_long arg2,
3250 abi_long arg3,
3251 abi_long arg4)
3253 #ifdef TARGET_ARM
3254 if (((CPUARMState *)cpu_env)->eabi)
3256 arg2 = arg3;
3257 arg3 = arg4;
3259 #endif
3260 return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
3262 #endif
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);
3274 return 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);
3287 return 0;
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)
3295 #ifdef TARGET_ARM
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);
3306 #endif
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);
3319 } else
3320 #endif
3322 #if TARGET_LONG_BITS == 64
3323 struct target_stat *target_st;
3324 #else
3325 struct target_stat64 *target_st;
3326 #endif
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);
3335 #endif
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);
3351 return 0;
3353 #endif
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
3367 and target. */
3368 switch (op) {
3369 case FUTEX_WAIT:
3370 if (timeout) {
3371 pts = &ts;
3372 target_to_host_timespec(pts, timeout);
3373 } else {
3374 pts = NULL;
3376 return get_errno(sys_futex(g2h(uaddr), FUTEX_WAIT, tswap32(val),
3377 pts, NULL, 0));
3378 case FUTEX_WAKE:
3379 return get_errno(sys_futex(g2h(uaddr), FUTEX_WAKE, val, NULL, NULL, 0));
3380 case FUTEX_FD:
3381 return get_errno(sys_futex(g2h(uaddr), FUTEX_FD, val, NULL, NULL, 0));
3382 case FUTEX_REQUEUE:
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)));
3388 default:
3389 return -TARGET_ENOSYS;
3392 #endif
3394 int get_osversion(void)
3396 static int osversion;
3397 struct new_utsname buf;
3398 const char *s;
3399 int i, n, tmp;
3400 if (osversion)
3401 return osversion;
3402 if (qemu_uname_release && *qemu_uname_release) {
3403 s = qemu_uname_release;
3404 } else {
3405 if (sys_uname(&buf))
3406 return 0;
3407 s = buf.release;
3409 tmp = 0;
3410 for (i = 0; i < 3; i++) {
3411 n = 0;
3412 while (*s >= '0' && *s <= '9') {
3413 n *= 10;
3414 n += *s - '0';
3415 s++;
3417 tmp = (tmp << 8) + n;
3418 if (*s == '.')
3419 s++;
3421 osversion = tmp;
3422 return osversion;
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)
3432 abi_long ret;
3433 struct stat st;
3434 struct statfs stfs;
3435 void *p;
3437 #ifdef DEBUG
3438 gemu_log("syscall %d", num);
3439 #endif
3440 if(do_strace)
3441 print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
3443 switch(num) {
3444 case TARGET_NR_exit:
3445 #ifdef USE_NPTL
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) {
3453 CPUState **lastp;
3454 CPUState *p;
3456 cpu_list_lock();
3457 lastp = &first_cpu;
3458 p = first_cpu;
3459 while (p && p != (CPUState *)cpu_env) {
3460 lastp = &p->next_cpu;
3461 p = p->next_cpu;
3463 /* If we didn't find the CPU for this thread then something is
3464 horribly wrong. */
3465 if (!p)
3466 abort();
3467 /* Remove the CPU from the list. */
3468 *lastp = p->next_cpu;
3469 cpu_list_unlock();
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,
3474 NULL, NULL, 0);
3476 /* TODO: Free CPU state. */
3477 pthread_exit(NULL);
3479 #endif
3480 #ifdef HAVE_GPROF
3481 _mcleanup();
3482 #endif
3483 gdb_exit(cpu_env, arg1);
3484 _exit(arg1);
3485 ret = 0; /* avoid warning */
3486 break;
3487 case TARGET_NR_read:
3488 if (arg3 == 0)
3489 ret = 0;
3490 else {
3491 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
3492 goto efault;
3493 ret = get_errno(read(arg1, p, arg3));
3494 unlock_user(p, arg2, ret);
3496 break;
3497 case TARGET_NR_write:
3498 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
3499 goto efault;
3500 ret = get_errno(write(arg1, p, arg3));
3501 unlock_user(p, arg2, 0);
3502 break;
3503 case TARGET_NR_open:
3504 if (!(p = lock_user_string(arg1)))
3505 goto efault;
3506 ret = get_errno(open(path(p),
3507 target_to_host_bitmask(arg2, fcntl_flags_tbl),
3508 arg3));
3509 unlock_user(p, arg1, 0);
3510 break;
3511 #if defined(TARGET_NR_openat) && defined(__NR_openat)
3512 case TARGET_NR_openat:
3513 if (!(p = lock_user_string(arg2)))
3514 goto efault;
3515 ret = get_errno(sys_openat(arg1,
3516 path(p),
3517 target_to_host_bitmask(arg3, fcntl_flags_tbl),
3518 arg4));
3519 unlock_user(p, arg2, 0);
3520 break;
3521 #endif
3522 case TARGET_NR_close:
3523 ret = get_errno(close(arg1));
3524 break;
3525 case TARGET_NR_brk:
3526 ret = do_brk(arg1);
3527 break;
3528 case TARGET_NR_fork:
3529 ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
3530 break;
3531 #ifdef TARGET_NR_waitpid
3532 case TARGET_NR_waitpid:
3534 int status;
3535 ret = get_errno(waitpid(arg1, &status, arg3));
3536 if (!is_error(ret) && arg2
3537 && put_user_s32(status, arg2))
3538 goto efault;
3540 break;
3541 #endif
3542 #ifdef TARGET_NR_waitid
3543 case TARGET_NR_waitid:
3545 siginfo_t info;
3546 info.si_pid = 0;
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)))
3550 goto efault;
3551 host_to_target_siginfo(p, &info);
3552 unlock_user(p, arg3, sizeof(target_siginfo_t));
3555 break;
3556 #endif
3557 #ifdef TARGET_NR_creat /* not on alpha */
3558 case TARGET_NR_creat:
3559 if (!(p = lock_user_string(arg1)))
3560 goto efault;
3561 ret = get_errno(creat(p, arg2));
3562 unlock_user(p, arg1, 0);
3563 break;
3564 #endif
3565 case TARGET_NR_link:
3567 void * p2;
3568 p = lock_user_string(arg1);
3569 p2 = lock_user_string(arg2);
3570 if (!p || !p2)
3571 ret = -TARGET_EFAULT;
3572 else
3573 ret = get_errno(link(p, p2));
3574 unlock_user(p2, arg2, 0);
3575 unlock_user(p, arg1, 0);
3577 break;
3578 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
3579 case TARGET_NR_linkat:
3581 void * p2 = NULL;
3582 if (!arg2 || !arg4)
3583 goto efault;
3584 p = lock_user_string(arg2);
3585 p2 = lock_user_string(arg4);
3586 if (!p || !p2)
3587 ret = -TARGET_EFAULT;
3588 else
3589 ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
3590 unlock_user(p, arg2, 0);
3591 unlock_user(p2, arg4, 0);
3593 break;
3594 #endif
3595 case TARGET_NR_unlink:
3596 if (!(p = lock_user_string(arg1)))
3597 goto efault;
3598 ret = get_errno(unlink(p));
3599 unlock_user(p, arg1, 0);
3600 break;
3601 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
3602 case TARGET_NR_unlinkat:
3603 if (!(p = lock_user_string(arg2)))
3604 goto efault;
3605 ret = get_errno(sys_unlinkat(arg1, p, arg3));
3606 unlock_user(p, arg2, 0);
3607 break;
3608 #endif
3609 case TARGET_NR_execve:
3611 char **argp, **envp;
3612 int argc, envc;
3613 abi_ulong gp;
3614 abi_ulong guest_argp;
3615 abi_ulong guest_envp;
3616 abi_ulong addr;
3617 char **q;
3619 argc = 0;
3620 guest_argp = arg2;
3621 for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
3622 if (get_user_ual(addr, gp))
3623 goto efault;
3624 if (!addr)
3625 break;
3626 argc++;
3628 envc = 0;
3629 guest_envp = arg3;
3630 for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
3631 if (get_user_ual(addr, gp))
3632 goto efault;
3633 if (!addr)
3634 break;
3635 envc++;
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))
3644 goto execve_efault;
3645 if (!addr)
3646 break;
3647 if (!(*q = lock_user_string(addr)))
3648 goto execve_efault;
3650 *q = NULL;
3652 for (gp = guest_envp, q = envp; gp;
3653 gp += sizeof(abi_ulong), q++) {
3654 if (get_user_ual(addr, gp))
3655 goto execve_efault;
3656 if (!addr)
3657 break;
3658 if (!(*q = lock_user_string(addr)))
3659 goto execve_efault;
3661 *q = NULL;
3663 if (!(p = lock_user_string(arg1)))
3664 goto execve_efault;
3665 ret = get_errno(execve(p, argp, envp));
3666 unlock_user(p, arg1, 0);
3668 goto execve_end;
3670 execve_efault:
3671 ret = -TARGET_EFAULT;
3673 execve_end:
3674 for (gp = guest_argp, q = argp; *q;
3675 gp += sizeof(abi_ulong), q++) {
3676 if (get_user_ual(addr, gp)
3677 || !addr)
3678 break;
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)
3684 || !addr)
3685 break;
3686 unlock_user(*q, addr, 0);
3689 break;
3690 case TARGET_NR_chdir:
3691 if (!(p = lock_user_string(arg1)))
3692 goto efault;
3693 ret = get_errno(chdir(p));
3694 unlock_user(p, arg1, 0);
3695 break;
3696 #ifdef TARGET_NR_time
3697 case TARGET_NR_time:
3699 time_t host_time;
3700 ret = get_errno(time(&host_time));
3701 if (!is_error(ret)
3702 && arg1
3703 && put_user_sal(host_time, arg1))
3704 goto efault;
3706 break;
3707 #endif
3708 case TARGET_NR_mknod:
3709 if (!(p = lock_user_string(arg1)))
3710 goto efault;
3711 ret = get_errno(mknod(p, arg2, arg3));
3712 unlock_user(p, arg1, 0);
3713 break;
3714 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
3715 case TARGET_NR_mknodat:
3716 if (!(p = lock_user_string(arg2)))
3717 goto efault;
3718 ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
3719 unlock_user(p, arg2, 0);
3720 break;
3721 #endif
3722 case TARGET_NR_chmod:
3723 if (!(p = lock_user_string(arg1)))
3724 goto efault;
3725 ret = get_errno(chmod(p, arg2));
3726 unlock_user(p, arg1, 0);
3727 break;
3728 #ifdef TARGET_NR_break
3729 case TARGET_NR_break:
3730 goto unimplemented;
3731 #endif
3732 #ifdef TARGET_NR_oldstat
3733 case TARGET_NR_oldstat:
3734 goto unimplemented;
3735 #endif
3736 case TARGET_NR_lseek:
3737 ret = get_errno(lseek(arg1, arg2, arg3));
3738 break;
3739 #ifdef TARGET_NR_getxpid
3740 case TARGET_NR_getxpid:
3741 #else
3742 case TARGET_NR_getpid:
3743 #endif
3744 ret = get_errno(getpid());
3745 break;
3746 case TARGET_NR_mount:
3748 /* need to look at the data field */
3749 void *p2, *p3;
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;
3755 else
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
3758 * string.
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);
3764 break;
3766 #ifdef TARGET_NR_umount
3767 case TARGET_NR_umount:
3768 if (!(p = lock_user_string(arg1)))
3769 goto efault;
3770 ret = get_errno(umount(p));
3771 unlock_user(p, arg1, 0);
3772 break;
3773 #endif
3774 #ifdef TARGET_NR_stime /* not on alpha */
3775 case TARGET_NR_stime:
3777 time_t host_time;
3778 if (get_user_sal(host_time, arg1))
3779 goto efault;
3780 ret = get_errno(stime(&host_time));
3782 break;
3783 #endif
3784 case TARGET_NR_ptrace:
3785 goto unimplemented;
3786 #ifdef TARGET_NR_alarm /* not on alpha */
3787 case TARGET_NR_alarm:
3788 ret = alarm(arg1);
3789 break;
3790 #endif
3791 #ifdef TARGET_NR_oldfstat
3792 case TARGET_NR_oldfstat:
3793 goto unimplemented;
3794 #endif
3795 #ifdef TARGET_NR_pause /* not on alpha */
3796 case TARGET_NR_pause:
3797 ret = get_errno(pause());
3798 break;
3799 #endif
3800 #ifdef TARGET_NR_utime
3801 case TARGET_NR_utime:
3803 struct utimbuf tbuf, *host_tbuf;
3804 struct target_utimbuf *target_tbuf;
3805 if (arg2) {
3806 if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
3807 goto efault;
3808 tbuf.actime = tswapl(target_tbuf->actime);
3809 tbuf.modtime = tswapl(target_tbuf->modtime);
3810 unlock_user_struct(target_tbuf, arg2, 0);
3811 host_tbuf = &tbuf;
3812 } else {
3813 host_tbuf = NULL;
3815 if (!(p = lock_user_string(arg1)))
3816 goto efault;
3817 ret = get_errno(utime(p, host_tbuf));
3818 unlock_user(p, arg1, 0);
3820 break;
3821 #endif
3822 case TARGET_NR_utimes:
3824 struct timeval *tvp, tv[2];
3825 if (arg2) {
3826 if (copy_from_user_timeval(&tv[0], arg2)
3827 || copy_from_user_timeval(&tv[1],
3828 arg2 + sizeof(struct target_timeval)))
3829 goto efault;
3830 tvp = tv;
3831 } else {
3832 tvp = NULL;
3834 if (!(p = lock_user_string(arg1)))
3835 goto efault;
3836 ret = get_errno(utimes(p, tvp));
3837 unlock_user(p, arg1, 0);
3839 break;
3840 #if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
3841 case TARGET_NR_futimesat:
3843 struct timeval *tvp, tv[2];
3844 if (arg3) {
3845 if (copy_from_user_timeval(&tv[0], arg3)
3846 || copy_from_user_timeval(&tv[1],
3847 arg3 + sizeof(struct target_timeval)))
3848 goto efault;
3849 tvp = tv;
3850 } else {
3851 tvp = NULL;
3853 if (!(p = lock_user_string(arg2)))
3854 goto efault;
3855 ret = get_errno(sys_futimesat(arg1, path(p), tvp));
3856 unlock_user(p, arg2, 0);
3858 break;
3859 #endif
3860 #ifdef TARGET_NR_stty
3861 case TARGET_NR_stty:
3862 goto unimplemented;
3863 #endif
3864 #ifdef TARGET_NR_gtty
3865 case TARGET_NR_gtty:
3866 goto unimplemented;
3867 #endif
3868 case TARGET_NR_access:
3869 if (!(p = lock_user_string(arg1)))
3870 goto efault;
3871 ret = get_errno(access(p, arg2));
3872 unlock_user(p, arg1, 0);
3873 break;
3874 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
3875 case TARGET_NR_faccessat:
3876 if (!(p = lock_user_string(arg2)))
3877 goto efault;
3878 ret = get_errno(sys_faccessat(arg1, p, arg3, arg4));
3879 unlock_user(p, arg2, 0);
3880 break;
3881 #endif
3882 #ifdef TARGET_NR_nice /* not on alpha */
3883 case TARGET_NR_nice:
3884 ret = get_errno(nice(arg1));
3885 break;
3886 #endif
3887 #ifdef TARGET_NR_ftime
3888 case TARGET_NR_ftime:
3889 goto unimplemented;
3890 #endif
3891 case TARGET_NR_sync:
3892 sync();
3893 ret = 0;
3894 break;
3895 case TARGET_NR_kill:
3896 ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
3897 break;
3898 case TARGET_NR_rename:
3900 void *p2;
3901 p = lock_user_string(arg1);
3902 p2 = lock_user_string(arg2);
3903 if (!p || !p2)
3904 ret = -TARGET_EFAULT;
3905 else
3906 ret = get_errno(rename(p, p2));
3907 unlock_user(p2, arg2, 0);
3908 unlock_user(p, arg1, 0);
3910 break;
3911 #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
3912 case TARGET_NR_renameat:
3914 void *p2;
3915 p = lock_user_string(arg2);
3916 p2 = lock_user_string(arg4);
3917 if (!p || !p2)
3918 ret = -TARGET_EFAULT;
3919 else
3920 ret = get_errno(sys_renameat(arg1, p, arg3, p2));
3921 unlock_user(p2, arg4, 0);
3922 unlock_user(p, arg2, 0);
3924 break;
3925 #endif
3926 case TARGET_NR_mkdir:
3927 if (!(p = lock_user_string(arg1)))
3928 goto efault;
3929 ret = get_errno(mkdir(p, arg2));
3930 unlock_user(p, arg1, 0);
3931 break;
3932 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
3933 case TARGET_NR_mkdirat:
3934 if (!(p = lock_user_string(arg2)))
3935 goto efault;
3936 ret = get_errno(sys_mkdirat(arg1, p, arg3));
3937 unlock_user(p, arg2, 0);
3938 break;
3939 #endif
3940 case TARGET_NR_rmdir:
3941 if (!(p = lock_user_string(arg1)))
3942 goto efault;
3943 ret = get_errno(rmdir(p));
3944 unlock_user(p, arg1, 0);
3945 break;
3946 case TARGET_NR_dup:
3947 ret = get_errno(dup(arg1));
3948 break;
3949 case TARGET_NR_pipe:
3951 int host_pipe[2];
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];
3957 ret = host_pipe[0];
3958 #elif defined(TARGET_SH4)
3959 ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
3960 ret = host_pipe[0];
3961 #else
3962 if (put_user_s32(host_pipe[0], arg1)
3963 || put_user_s32(host_pipe[1], arg1 + sizeof(host_pipe[0])))
3964 goto efault;
3965 #endif
3968 break;
3969 case TARGET_NR_times:
3971 struct target_tms *tmsp;
3972 struct tms tms;
3973 ret = get_errno(times(&tms));
3974 if (arg1) {
3975 tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
3976 if (!tmsp)
3977 goto efault;
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));
3983 if (!is_error(ret))
3984 ret = host_to_target_clock_t(ret);
3986 break;
3987 #ifdef TARGET_NR_prof
3988 case TARGET_NR_prof:
3989 goto unimplemented;
3990 #endif
3991 #ifdef TARGET_NR_signal
3992 case TARGET_NR_signal:
3993 goto unimplemented;
3994 #endif
3995 case TARGET_NR_acct:
3996 if (arg1 == 0) {
3997 ret = get_errno(acct(NULL));
3998 } else {
3999 if (!(p = lock_user_string(arg1)))
4000 goto efault;
4001 ret = get_errno(acct(path(p)));
4002 unlock_user(p, arg1, 0);
4004 break;
4005 #ifdef TARGET_NR_umount2 /* not on alpha */
4006 case TARGET_NR_umount2:
4007 if (!(p = lock_user_string(arg1)))
4008 goto efault;
4009 ret = get_errno(umount2(p, arg2));
4010 unlock_user(p, arg1, 0);
4011 break;
4012 #endif
4013 #ifdef TARGET_NR_lock
4014 case TARGET_NR_lock:
4015 goto unimplemented;
4016 #endif
4017 case TARGET_NR_ioctl:
4018 ret = do_ioctl(arg1, arg2, arg3);
4019 break;
4020 case TARGET_NR_fcntl:
4021 ret = do_fcntl(arg1, arg2, arg3);
4022 break;
4023 #ifdef TARGET_NR_mpx
4024 case TARGET_NR_mpx:
4025 goto unimplemented;
4026 #endif
4027 case TARGET_NR_setpgid:
4028 ret = get_errno(setpgid(arg1, arg2));
4029 break;
4030 #ifdef TARGET_NR_ulimit
4031 case TARGET_NR_ulimit:
4032 goto unimplemented;
4033 #endif
4034 #ifdef TARGET_NR_oldolduname
4035 case TARGET_NR_oldolduname:
4036 goto unimplemented;
4037 #endif
4038 case TARGET_NR_umask:
4039 ret = get_errno(umask(arg1));
4040 break;
4041 case TARGET_NR_chroot:
4042 if (!(p = lock_user_string(arg1)))
4043 goto efault;
4044 ret = get_errno(chroot(p));
4045 unlock_user(p, arg1, 0);
4046 break;
4047 case TARGET_NR_ustat:
4048 goto unimplemented;
4049 case TARGET_NR_dup2:
4050 ret = get_errno(dup2(arg1, arg2));
4051 break;
4052 #ifdef TARGET_NR_getppid /* not on alpha */
4053 case TARGET_NR_getppid:
4054 ret = get_errno(getppid());
4055 break;
4056 #endif
4057 case TARGET_NR_getpgrp:
4058 ret = get_errno(getpgrp());
4059 break;
4060 case TARGET_NR_setsid:
4061 ret = get_errno(setsid());
4062 break;
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;
4069 if (arg2) {
4070 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4071 goto efault;
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);
4077 pact = &act;
4078 } else {
4079 pact = NULL;
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))
4084 goto efault;
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);
4091 #else
4092 struct target_sigaction act, oact, *pact, *old_act;
4094 if (arg2) {
4095 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4096 goto efault;
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);
4101 pact = &act;
4102 } else {
4103 pact = NULL;
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))
4110 goto efault;
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);
4119 #endif
4121 break;
4122 #endif
4123 case TARGET_NR_rt_sigaction:
4125 struct target_sigaction *act;
4126 struct target_sigaction *oact;
4128 if (arg2) {
4129 if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
4130 goto efault;
4131 } else
4132 act = NULL;
4133 if (arg3) {
4134 if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
4135 ret = -TARGET_EFAULT;
4136 goto rt_sigaction_fail;
4138 } else
4139 oact = NULL;
4140 ret = get_errno(do_sigaction(arg1, act, oact));
4141 rt_sigaction_fail:
4142 if (act)
4143 unlock_user_struct(act, arg2, 0);
4144 if (oact)
4145 unlock_user_struct(oact, arg3, 1);
4147 break;
4148 #ifdef TARGET_NR_sgetmask /* not on alpha */
4149 case TARGET_NR_sgetmask:
4151 sigset_t cur_set;
4152 abi_ulong target_set;
4153 sigprocmask(0, NULL, &cur_set);
4154 host_to_target_old_sigset(&target_set, &cur_set);
4155 ret = target_set;
4157 break;
4158 #endif
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);
4169 ret = target_set;
4171 break;
4172 #endif
4173 #ifdef TARGET_NR_sigprocmask
4174 case TARGET_NR_sigprocmask:
4176 int how = arg1;
4177 sigset_t set, oldset, *set_ptr;
4179 if (arg2) {
4180 switch(how) {
4181 case TARGET_SIG_BLOCK:
4182 how = SIG_BLOCK;
4183 break;
4184 case TARGET_SIG_UNBLOCK:
4185 how = SIG_UNBLOCK;
4186 break;
4187 case TARGET_SIG_SETMASK:
4188 how = SIG_SETMASK;
4189 break;
4190 default:
4191 ret = -TARGET_EINVAL;
4192 goto fail;
4194 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4195 goto efault;
4196 target_to_host_old_sigset(&set, p);
4197 unlock_user(p, arg2, 0);
4198 set_ptr = &set;
4199 } else {
4200 how = 0;
4201 set_ptr = NULL;
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)))
4206 goto efault;
4207 host_to_target_old_sigset(p, &oldset);
4208 unlock_user(p, arg3, sizeof(target_sigset_t));
4211 break;
4212 #endif
4213 case TARGET_NR_rt_sigprocmask:
4215 int how = arg1;
4216 sigset_t set, oldset, *set_ptr;
4218 if (arg2) {
4219 switch(how) {
4220 case TARGET_SIG_BLOCK:
4221 how = SIG_BLOCK;
4222 break;
4223 case TARGET_SIG_UNBLOCK:
4224 how = SIG_UNBLOCK;
4225 break;
4226 case TARGET_SIG_SETMASK:
4227 how = SIG_SETMASK;
4228 break;
4229 default:
4230 ret = -TARGET_EINVAL;
4231 goto fail;
4233 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4234 goto efault;
4235 target_to_host_sigset(&set, p);
4236 unlock_user(p, arg2, 0);
4237 set_ptr = &set;
4238 } else {
4239 how = 0;
4240 set_ptr = NULL;
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)))
4245 goto efault;
4246 host_to_target_sigset(p, &oldset);
4247 unlock_user(p, arg3, sizeof(target_sigset_t));
4250 break;
4251 #ifdef TARGET_NR_sigpending
4252 case TARGET_NR_sigpending:
4254 sigset_t set;
4255 ret = get_errno(sigpending(&set));
4256 if (!is_error(ret)) {
4257 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4258 goto efault;
4259 host_to_target_old_sigset(p, &set);
4260 unlock_user(p, arg1, sizeof(target_sigset_t));
4263 break;
4264 #endif
4265 case TARGET_NR_rt_sigpending:
4267 sigset_t set;
4268 ret = get_errno(sigpending(&set));
4269 if (!is_error(ret)) {
4270 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4271 goto efault;
4272 host_to_target_sigset(p, &set);
4273 unlock_user(p, arg1, sizeof(target_sigset_t));
4276 break;
4277 #ifdef TARGET_NR_sigsuspend
4278 case TARGET_NR_sigsuspend:
4280 sigset_t set;
4281 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4282 goto efault;
4283 target_to_host_old_sigset(&set, p);
4284 unlock_user(p, arg1, 0);
4285 ret = get_errno(sigsuspend(&set));
4287 break;
4288 #endif
4289 case TARGET_NR_rt_sigsuspend:
4291 sigset_t set;
4292 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4293 goto efault;
4294 target_to_host_sigset(&set, p);
4295 unlock_user(p, arg1, 0);
4296 ret = get_errno(sigsuspend(&set));
4298 break;
4299 case TARGET_NR_rt_sigtimedwait:
4301 sigset_t set;
4302 struct timespec uts, *puts;
4303 siginfo_t uinfo;
4305 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4306 goto efault;
4307 target_to_host_sigset(&set, p);
4308 unlock_user(p, arg1, 0);
4309 if (arg3) {
4310 puts = &uts;
4311 target_to_host_timespec(puts, arg3);
4312 } else {
4313 puts = NULL;
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)))
4318 goto efault;
4319 host_to_target_siginfo(p, &uinfo);
4320 unlock_user(p, arg2, sizeof(target_siginfo_t));
4323 break;
4324 case TARGET_NR_rt_sigqueueinfo:
4326 siginfo_t uinfo;
4327 if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
4328 goto efault;
4329 target_to_host_siginfo(&uinfo, p);
4330 unlock_user(p, arg1, 0);
4331 ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
4333 break;
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);
4338 break;
4339 #endif
4340 case TARGET_NR_rt_sigreturn:
4341 /* NOTE: ret is eax, so not transcoding must be done */
4342 ret = do_rt_sigreturn(cpu_env);
4343 break;
4344 case TARGET_NR_sethostname:
4345 if (!(p = lock_user_string(arg1)))
4346 goto efault;
4347 ret = get_errno(sethostname(p, arg2));
4348 unlock_user(p, arg1, 0);
4349 break;
4350 case TARGET_NR_setrlimit:
4352 /* XXX: convert resource ? */
4353 int resource = arg1;
4354 struct target_rlimit *target_rlim;
4355 struct rlimit rlim;
4356 if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
4357 goto efault;
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));
4363 break;
4364 case TARGET_NR_getrlimit:
4366 /* XXX: convert resource ? */
4367 int resource = arg1;
4368 struct target_rlimit *target_rlim;
4369 struct rlimit rlim;
4371 ret = get_errno(getrlimit(resource, &rlim));
4372 if (!is_error(ret)) {
4373 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
4374 goto efault;
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);
4380 break;
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);
4389 break;
4390 case TARGET_NR_gettimeofday:
4392 struct timeval tv;
4393 ret = get_errno(gettimeofday(&tv, NULL));
4394 if (!is_error(ret)) {
4395 if (copy_to_user_timeval(arg1, &tv))
4396 goto efault;
4399 break;
4400 case TARGET_NR_settimeofday:
4402 struct timeval tv;
4403 if (copy_from_user_timeval(&tv, arg1))
4404 goto efault;
4405 ret = get_errno(settimeofday(&tv, NULL));
4407 break;
4408 #ifdef TARGET_NR_select
4409 case TARGET_NR_select:
4411 struct target_sel_arg_struct *sel;
4412 abi_ulong inp, outp, exp, tvp;
4413 long nsel;
4415 if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
4416 goto efault;
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);
4425 break;
4426 #endif
4427 case TARGET_NR_symlink:
4429 void *p2;
4430 p = lock_user_string(arg1);
4431 p2 = lock_user_string(arg2);
4432 if (!p || !p2)
4433 ret = -TARGET_EFAULT;
4434 else
4435 ret = get_errno(symlink(p, p2));
4436 unlock_user(p2, arg2, 0);
4437 unlock_user(p, arg1, 0);
4439 break;
4440 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
4441 case TARGET_NR_symlinkat:
4443 void *p2;
4444 p = lock_user_string(arg1);
4445 p2 = lock_user_string(arg3);
4446 if (!p || !p2)
4447 ret = -TARGET_EFAULT;
4448 else
4449 ret = get_errno(sys_symlinkat(p, arg2, p2));
4450 unlock_user(p2, arg3, 0);
4451 unlock_user(p, arg1, 0);
4453 break;
4454 #endif
4455 #ifdef TARGET_NR_oldlstat
4456 case TARGET_NR_oldlstat:
4457 goto unimplemented;
4458 #endif
4459 case TARGET_NR_readlink:
4461 void *p2, *temp;
4462 p = lock_user_string(arg1);
4463 p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
4464 if (!p || !p2)
4465 ret = -TARGET_EFAULT;
4466 else {
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);
4473 else
4474 ret = get_errno(readlink(path(p), p2, arg3));
4476 unlock_user(p2, arg2, ret);
4477 unlock_user(p, arg1, 0);
4479 break;
4480 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
4481 case TARGET_NR_readlinkat:
4483 void *p2;
4484 p = lock_user_string(arg2);
4485 p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
4486 if (!p || !p2)
4487 ret = -TARGET_EFAULT;
4488 else
4489 ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
4490 unlock_user(p2, arg3, ret);
4491 unlock_user(p, arg2, 0);
4493 break;
4494 #endif
4495 #ifdef TARGET_NR_uselib
4496 case TARGET_NR_uselib:
4497 goto unimplemented;
4498 #endif
4499 #ifdef TARGET_NR_swapon
4500 case TARGET_NR_swapon:
4501 if (!(p = lock_user_string(arg1)))
4502 goto efault;
4503 ret = get_errno(swapon(p, arg2));
4504 unlock_user(p, arg1, 0);
4505 break;
4506 #endif
4507 case TARGET_NR_reboot:
4508 goto unimplemented;
4509 #ifdef TARGET_NR_readdir
4510 case TARGET_NR_readdir:
4511 goto unimplemented;
4512 #endif
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)
4517 abi_ulong *v;
4518 abi_ulong v1, v2, v3, v4, v5, v6;
4519 if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
4520 goto efault;
4521 v1 = tswapl(v[0]);
4522 v2 = tswapl(v[1]);
4523 v3 = tswapl(v[2]);
4524 v4 = tswapl(v[3]);
4525 v5 = tswapl(v[4]);
4526 v6 = tswapl(v[5]);
4527 unlock_user(v, arg1, 0);
4528 ret = get_errno(target_mmap(v1, v2, v3,
4529 target_to_host_bitmask(v4, mmap_flags_tbl),
4530 v5, v6));
4532 #else
4533 ret = get_errno(target_mmap(arg1, arg2, arg3,
4534 target_to_host_bitmask(arg4, mmap_flags_tbl),
4535 arg5,
4536 arg6));
4537 #endif
4538 break;
4539 #endif
4540 #ifdef TARGET_NR_mmap2
4541 case TARGET_NR_mmap2:
4542 #ifndef MMAP_SHIFT
4543 #define MMAP_SHIFT 12
4544 #endif
4545 ret = get_errno(target_mmap(arg1, arg2, arg3,
4546 target_to_host_bitmask(arg4, mmap_flags_tbl),
4547 arg5,
4548 arg6 << MMAP_SHIFT));
4549 break;
4550 #endif
4551 case TARGET_NR_munmap:
4552 ret = get_errno(target_munmap(arg1, arg2));
4553 break;
4554 case TARGET_NR_mprotect:
4555 ret = get_errno(target_mprotect(arg1, arg2, arg3));
4556 break;
4557 #ifdef TARGET_NR_mremap
4558 case TARGET_NR_mremap:
4559 ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
4560 break;
4561 #endif
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));
4566 break;
4567 #endif
4568 #ifdef TARGET_NR_mlock
4569 case TARGET_NR_mlock:
4570 ret = get_errno(mlock(g2h(arg1), arg2));
4571 break;
4572 #endif
4573 #ifdef TARGET_NR_munlock
4574 case TARGET_NR_munlock:
4575 ret = get_errno(munlock(g2h(arg1), arg2));
4576 break;
4577 #endif
4578 #ifdef TARGET_NR_mlockall
4579 case TARGET_NR_mlockall:
4580 ret = get_errno(mlockall(arg1));
4581 break;
4582 #endif
4583 #ifdef TARGET_NR_munlockall
4584 case TARGET_NR_munlockall:
4585 ret = get_errno(munlockall());
4586 break;
4587 #endif
4588 case TARGET_NR_truncate:
4589 if (!(p = lock_user_string(arg1)))
4590 goto efault;
4591 ret = get_errno(truncate(p, arg2));
4592 unlock_user(p, arg1, 0);
4593 break;
4594 case TARGET_NR_ftruncate:
4595 ret = get_errno(ftruncate(arg1, arg2));
4596 break;
4597 case TARGET_NR_fchmod:
4598 ret = get_errno(fchmod(arg1, arg2));
4599 break;
4600 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
4601 case TARGET_NR_fchmodat:
4602 if (!(p = lock_user_string(arg2)))
4603 goto efault;
4604 ret = get_errno(sys_fchmodat(arg1, p, arg3, arg4));
4605 unlock_user(p, arg2, 0);
4606 break;
4607 #endif
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);
4613 break;
4614 case TARGET_NR_setpriority:
4615 ret = get_errno(setpriority(arg1, arg2, arg3));
4616 break;
4617 #ifdef TARGET_NR_profil
4618 case TARGET_NR_profil:
4619 goto unimplemented;
4620 #endif
4621 case TARGET_NR_statfs:
4622 if (!(p = lock_user_string(arg1)))
4623 goto efault;
4624 ret = get_errno(statfs(path(p), &stfs));
4625 unlock_user(p, arg1, 0);
4626 convert_statfs:
4627 if (!is_error(ret)) {
4628 struct target_statfs *target_stfs;
4630 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
4631 goto efault;
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);
4644 break;
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)))
4651 goto efault;
4652 ret = get_errno(statfs(path(p), &stfs));
4653 unlock_user(p, arg1, 0);
4654 convert_statfs64:
4655 if (!is_error(ret)) {
4656 struct target_statfs64 *target_stfs;
4658 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
4659 goto efault;
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);
4672 break;
4673 case TARGET_NR_fstatfs64:
4674 ret = get_errno(fstatfs(arg1, &stfs));
4675 goto convert_statfs64;
4676 #endif
4677 #ifdef TARGET_NR_ioperm
4678 case TARGET_NR_ioperm:
4679 goto unimplemented;
4680 #endif
4681 #ifdef TARGET_NR_socketcall
4682 case TARGET_NR_socketcall:
4683 ret = do_socketcall(arg1, arg2);
4684 break;
4685 #endif
4686 #ifdef TARGET_NR_accept
4687 case TARGET_NR_accept:
4688 ret = do_accept(arg1, arg2, arg3);
4689 break;
4690 #endif
4691 #ifdef TARGET_NR_bind
4692 case TARGET_NR_bind:
4693 ret = do_bind(arg1, arg2, arg3);
4694 break;
4695 #endif
4696 #ifdef TARGET_NR_connect
4697 case TARGET_NR_connect:
4698 ret = do_connect(arg1, arg2, arg3);
4699 break;
4700 #endif
4701 #ifdef TARGET_NR_getpeername
4702 case TARGET_NR_getpeername:
4703 ret = do_getpeername(arg1, arg2, arg3);
4704 break;
4705 #endif
4706 #ifdef TARGET_NR_getsockname
4707 case TARGET_NR_getsockname:
4708 ret = do_getsockname(arg1, arg2, arg3);
4709 break;
4710 #endif
4711 #ifdef TARGET_NR_getsockopt
4712 case TARGET_NR_getsockopt:
4713 ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
4714 break;
4715 #endif
4716 #ifdef TARGET_NR_listen
4717 case TARGET_NR_listen:
4718 ret = get_errno(listen(arg1, arg2));
4719 break;
4720 #endif
4721 #ifdef TARGET_NR_recv
4722 case TARGET_NR_recv:
4723 ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
4724 break;
4725 #endif
4726 #ifdef TARGET_NR_recvfrom
4727 case TARGET_NR_recvfrom:
4728 ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
4729 break;
4730 #endif
4731 #ifdef TARGET_NR_recvmsg
4732 case TARGET_NR_recvmsg:
4733 ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
4734 break;
4735 #endif
4736 #ifdef TARGET_NR_send
4737 case TARGET_NR_send:
4738 ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
4739 break;
4740 #endif
4741 #ifdef TARGET_NR_sendmsg
4742 case TARGET_NR_sendmsg:
4743 ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
4744 break;
4745 #endif
4746 #ifdef TARGET_NR_sendto
4747 case TARGET_NR_sendto:
4748 ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
4749 break;
4750 #endif
4751 #ifdef TARGET_NR_shutdown
4752 case TARGET_NR_shutdown:
4753 ret = get_errno(shutdown(arg1, arg2));
4754 break;
4755 #endif
4756 #ifdef TARGET_NR_socket
4757 case TARGET_NR_socket:
4758 ret = do_socket(arg1, arg2, arg3);
4759 break;
4760 #endif
4761 #ifdef TARGET_NR_socketpair
4762 case TARGET_NR_socketpair:
4763 ret = do_socketpair(arg1, arg2, arg3, arg4);
4764 break;
4765 #endif
4766 #ifdef TARGET_NR_setsockopt
4767 case TARGET_NR_setsockopt:
4768 ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
4769 break;
4770 #endif
4772 case TARGET_NR_syslog:
4773 if (!(p = lock_user_string(arg2)))
4774 goto efault;
4775 ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
4776 unlock_user(p, arg2, 0);
4777 break;
4779 case TARGET_NR_setitimer:
4781 struct itimerval value, ovalue, *pvalue;
4783 if (arg2) {
4784 pvalue = &value;
4785 if (copy_from_user_timeval(&pvalue->it_interval, arg2)
4786 || copy_from_user_timeval(&pvalue->it_value,
4787 arg2 + sizeof(struct target_timeval)))
4788 goto efault;
4789 } else {
4790 pvalue = NULL;
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),
4797 &ovalue.it_value))
4798 goto efault;
4801 break;
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,
4809 &value.it_interval)
4810 || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
4811 &value.it_value))
4812 goto efault;
4815 break;
4816 case TARGET_NR_stat:
4817 if (!(p = lock_user_string(arg1)))
4818 goto efault;
4819 ret = get_errno(stat(path(p), &st));
4820 unlock_user(p, arg1, 0);
4821 goto do_stat;
4822 case TARGET_NR_lstat:
4823 if (!(p = lock_user_string(arg1)))
4824 goto efault;
4825 ret = get_errno(lstat(path(p), &st));
4826 unlock_user(p, arg1, 0);
4827 goto do_stat;
4828 case TARGET_NR_fstat:
4830 ret = get_errno(fstat(arg1, &st));
4831 do_stat:
4832 if (!is_error(ret)) {
4833 struct target_stat *target_st;
4835 if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
4836 goto efault;
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);
4853 break;
4854 #ifdef TARGET_NR_olduname
4855 case TARGET_NR_olduname:
4856 goto unimplemented;
4857 #endif
4858 #ifdef TARGET_NR_iopl
4859 case TARGET_NR_iopl:
4860 goto unimplemented;
4861 #endif
4862 case TARGET_NR_vhangup:
4863 ret = get_errno(vhangup());
4864 break;
4865 #ifdef TARGET_NR_idle
4866 case TARGET_NR_idle:
4867 goto unimplemented;
4868 #endif
4869 #ifdef TARGET_NR_syscall
4870 case TARGET_NR_syscall:
4871 ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
4872 break;
4873 #endif
4874 case TARGET_NR_wait4:
4876 int status;
4877 abi_long status_ptr = arg2;
4878 struct rusage rusage, *rusage_ptr;
4879 abi_ulong target_rusage = arg4;
4880 if (target_rusage)
4881 rusage_ptr = &rusage;
4882 else
4883 rusage_ptr = NULL;
4884 ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
4885 if (!is_error(ret)) {
4886 if (status_ptr) {
4887 if (put_user_s32(status, status_ptr))
4888 goto efault;
4890 if (target_rusage)
4891 host_to_target_rusage(target_rusage, &rusage);
4894 break;
4895 #ifdef TARGET_NR_swapoff
4896 case TARGET_NR_swapoff:
4897 if (!(p = lock_user_string(arg1)))
4898 goto efault;
4899 ret = get_errno(swapoff(p));
4900 unlock_user(p, arg1, 0);
4901 break;
4902 #endif
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))
4911 goto efault;
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);
4929 break;
4930 #ifdef TARGET_NR_ipc
4931 case TARGET_NR_ipc:
4932 ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
4933 break;
4934 #endif
4936 #ifdef TARGET_NR_msgctl
4937 case TARGET_NR_msgctl:
4938 ret = do_msgctl(arg1, arg2, arg3);
4939 break;
4940 #endif
4941 #ifdef TARGET_NR_msgget
4942 case TARGET_NR_msgget:
4943 ret = get_errno(msgget(arg1, arg2));
4944 break;
4945 #endif
4946 #ifdef TARGET_NR_msgrcv
4947 case TARGET_NR_msgrcv:
4948 ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
4949 break;
4950 #endif
4951 #ifdef TARGET_NR_msgsnd
4952 case TARGET_NR_msgsnd:
4953 ret = do_msgsnd(arg1, arg2, arg3, arg4);
4954 break;
4955 #endif
4956 case TARGET_NR_fsync:
4957 ret = get_errno(fsync(arg1));
4958 break;
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));
4964 #else
4965 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
4966 #endif
4967 break;
4968 #ifdef __NR_exit_group
4969 /* new thread calls */
4970 case TARGET_NR_exit_group:
4971 #ifdef HAVE_GPROF
4972 _mcleanup();
4973 #endif
4974 gdb_exit(cpu_env, arg1);
4975 ret = get_errno(exit_group(arg1));
4976 break;
4977 #endif
4978 case TARGET_NR_setdomainname:
4979 if (!(p = lock_user_string(arg1)))
4980 goto efault;
4981 ret = get_errno(setdomainname(p, arg2));
4982 unlock_user(p, arg1, 0);
4983 break;
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))
4990 goto efault;
4991 ret = get_errno(sys_uname(buf));
4992 if (!is_error(ret)) {
4993 /* Overrite the native machine name with whatever is being
4994 emulated. */
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);
5002 break;
5003 #ifdef TARGET_I386
5004 case TARGET_NR_modify_ldt:
5005 ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
5006 break;
5007 #if !defined(TARGET_X86_64)
5008 case TARGET_NR_vm86old:
5009 goto unimplemented;
5010 case TARGET_NR_vm86:
5011 ret = do_vm86(cpu_env, arg1, arg2);
5012 break;
5013 #endif
5014 #endif
5015 case TARGET_NR_adjtimex:
5016 goto unimplemented;
5017 #ifdef TARGET_NR_create_module
5018 case TARGET_NR_create_module:
5019 #endif
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:
5024 #endif
5025 goto unimplemented;
5026 case TARGET_NR_quotactl:
5027 goto unimplemented;
5028 case TARGET_NR_getpgid:
5029 ret = get_errno(getpgid(arg1));
5030 break;
5031 case TARGET_NR_fchdir:
5032 ret = get_errno(fchdir(arg1));
5033 break;
5034 #ifdef TARGET_NR_bdflush /* not on x86_64 */
5035 case TARGET_NR_bdflush:
5036 goto unimplemented;
5037 #endif
5038 #ifdef TARGET_NR_sysfs
5039 case TARGET_NR_sysfs:
5040 goto unimplemented;
5041 #endif
5042 case TARGET_NR_personality:
5043 ret = get_errno(personality(arg1));
5044 break;
5045 #ifdef TARGET_NR_afs_syscall
5046 case TARGET_NR_afs_syscall:
5047 goto unimplemented;
5048 #endif
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))
5055 goto efault;
5056 #else
5057 int64_t res;
5058 ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
5059 if (put_user_s64(res, arg4))
5060 goto efault;
5061 #endif
5063 break;
5064 #endif
5065 case TARGET_NR_getdents:
5066 #if TARGET_ABI_BITS != 32
5067 goto unimplemented;
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);
5075 if (!dirp) {
5076 ret = -TARGET_ENOMEM;
5077 goto fail;
5080 ret = get_errno(sys_getdents(arg1, dirp, count));
5081 if (!is_error(ret)) {
5082 struct linux_dirent *de;
5083 struct target_dirent *tde;
5084 int len = ret;
5085 int reclen, treclen;
5086 int count1, tnamelen;
5088 count1 = 0;
5089 de = dirp;
5090 if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5091 goto efault;
5092 tde = target_dirp;
5093 while (len > 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);
5100 if (tnamelen > 256)
5101 tnamelen = 256;
5102 /* XXX: may not be correct */
5103 pstrcpy(tde->d_name, tnamelen, de->d_name);
5104 de = (struct linux_dirent *)((char *)de + reclen);
5105 len -= reclen;
5106 tde = (struct target_dirent *)((char *)tde + treclen);
5107 count1 += treclen;
5109 ret = count1;
5110 unlock_user(target_dirp, arg2, ret);
5112 free(dirp);
5114 #else
5116 struct linux_dirent *dirp;
5117 abi_long count = arg3;
5119 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5120 goto efault;
5121 ret = get_errno(sys_getdents(arg1, dirp, count));
5122 if (!is_error(ret)) {
5123 struct linux_dirent *de;
5124 int len = ret;
5125 int reclen;
5126 de = dirp;
5127 while (len > 0) {
5128 reclen = de->d_reclen;
5129 if (reclen > len)
5130 break;
5131 de->d_reclen = tswap16(reclen);
5132 tswapls(&de->d_ino);
5133 tswapls(&de->d_off);
5134 de = (struct linux_dirent *)((char *)de + reclen);
5135 len -= reclen;
5138 unlock_user(dirp, arg2, ret);
5140 #endif
5141 break;
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)))
5148 goto efault;
5149 ret = get_errno(sys_getdents64(arg1, dirp, count));
5150 if (!is_error(ret)) {
5151 struct linux_dirent64 *de;
5152 int len = ret;
5153 int reclen;
5154 de = dirp;
5155 while (len > 0) {
5156 reclen = de->d_reclen;
5157 if (reclen > len)
5158 break;
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);
5163 len -= reclen;
5166 unlock_user(dirp, arg2, ret);
5168 break;
5169 #endif /* TARGET_NR_getdents64 */
5170 #ifdef TARGET_NR__newselect
5171 case TARGET_NR__newselect:
5172 ret = do_select(arg1, arg2, arg3, arg4, arg5);
5173 break;
5174 #endif
5175 #ifdef TARGET_NR_poll
5176 case TARGET_NR_poll:
5178 struct target_pollfd *target_pfd;
5179 unsigned int nfds = arg2;
5180 int timeout = arg3;
5181 struct pollfd *pfd;
5182 unsigned int i;
5184 target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
5185 if (!target_pfd)
5186 goto efault;
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);
5202 break;
5203 #endif
5204 case TARGET_NR_flock:
5205 /* NOTE: the flock constant seems to be the same for every
5206 Linux platform */
5207 ret = get_errno(flock(arg1, arg2));
5208 break;
5209 case TARGET_NR_readv:
5211 int count = arg3;
5212 struct iovec *vec;
5214 vec = alloca(count * sizeof(struct iovec));
5215 if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
5216 goto efault;
5217 ret = get_errno(readv(arg1, vec, count));
5218 unlock_iovec(vec, arg2, count, 1);
5220 break;
5221 case TARGET_NR_writev:
5223 int count = arg3;
5224 struct iovec *vec;
5226 vec = alloca(count * sizeof(struct iovec));
5227 if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
5228 goto efault;
5229 ret = get_errno(writev(arg1, vec, count));
5230 unlock_iovec(vec, arg2, count, 0);
5232 break;
5233 case TARGET_NR_getsid:
5234 ret = get_errno(getsid(arg1));
5235 break;
5236 #if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
5237 case TARGET_NR_fdatasync:
5238 ret = get_errno(fdatasync(arg1));
5239 break;
5240 #endif
5241 case TARGET_NR__sysctl:
5242 /* We don't implement this, but ENOTDIR is always a safe
5243 return value. */
5244 ret = -TARGET_ENOTDIR;
5245 break;
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))
5252 goto efault;
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));
5257 break;
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))
5265 goto efault;
5266 target_schp->sched_priority = tswap32(schp.sched_priority);
5267 unlock_user_struct(target_schp, arg2, 1);
5270 break;
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))
5276 goto efault;
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));
5281 break;
5282 case TARGET_NR_sched_getscheduler:
5283 ret = get_errno(sched_getscheduler(arg1));
5284 break;
5285 case TARGET_NR_sched_yield:
5286 ret = get_errno(sched_yield());
5287 break;
5288 case TARGET_NR_sched_get_priority_max:
5289 ret = get_errno(sched_get_priority_max(arg1));
5290 break;
5291 case TARGET_NR_sched_get_priority_min:
5292 ret = get_errno(sched_get_priority_min(arg1));
5293 break;
5294 case TARGET_NR_sched_rr_get_interval:
5296 struct timespec ts;
5297 ret = get_errno(sched_rr_get_interval(arg1, &ts));
5298 if (!is_error(ret)) {
5299 host_to_target_timespec(arg2, &ts);
5302 break;
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);
5312 break;
5313 #ifdef TARGET_NR_query_module
5314 case TARGET_NR_query_module:
5315 goto unimplemented;
5316 #endif
5317 #ifdef TARGET_NR_nfsservctl
5318 case TARGET_NR_nfsservctl:
5319 goto unimplemented;
5320 #endif
5321 case TARGET_NR_prctl:
5322 switch (arg1)
5324 case PR_GET_PDEATHSIG:
5326 int deathsig;
5327 ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
5328 if (!is_error(ret) && arg2
5329 && put_user_ual(deathsig, arg2))
5330 goto efault;
5332 break;
5333 default:
5334 ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
5335 break;
5337 break;
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);
5342 break;
5343 #else
5344 goto unimplemented;
5345 #endif
5346 #endif
5347 #ifdef TARGET_NR_pread
5348 case TARGET_NR_pread:
5349 #ifdef TARGET_ARM
5350 if (((CPUARMState *)cpu_env)->eabi)
5351 arg4 = arg5;
5352 #endif
5353 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5354 goto efault;
5355 ret = get_errno(pread(arg1, p, arg3, arg4));
5356 unlock_user(p, arg2, ret);
5357 break;
5358 case TARGET_NR_pwrite:
5359 #ifdef TARGET_ARM
5360 if (((CPUARMState *)cpu_env)->eabi)
5361 arg4 = arg5;
5362 #endif
5363 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5364 goto efault;
5365 ret = get_errno(pwrite(arg1, p, arg3, arg4));
5366 unlock_user(p, arg2, 0);
5367 break;
5368 #endif
5369 #ifdef TARGET_NR_pread64
5370 case TARGET_NR_pread64:
5371 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5372 goto efault;
5373 ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
5374 unlock_user(p, arg2, ret);
5375 break;
5376 case TARGET_NR_pwrite64:
5377 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5378 goto efault;
5379 ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
5380 unlock_user(p, arg2, 0);
5381 break;
5382 #endif
5383 case TARGET_NR_getcwd:
5384 if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
5385 goto efault;
5386 ret = get_errno(sys_getcwd1(p, arg2));
5387 unlock_user(p, arg1, ret);
5388 break;
5389 case TARGET_NR_capget:
5390 goto unimplemented;
5391 case TARGET_NR_capset:
5392 goto unimplemented;
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));
5397 break;
5398 #else
5399 goto unimplemented;
5400 #endif
5401 case TARGET_NR_sendfile:
5402 goto unimplemented;
5403 #ifdef TARGET_NR_getpmsg
5404 case TARGET_NR_getpmsg:
5405 goto unimplemented;
5406 #endif
5407 #ifdef TARGET_NR_putpmsg
5408 case TARGET_NR_putpmsg:
5409 goto unimplemented;
5410 #endif
5411 #ifdef TARGET_NR_vfork
5412 case TARGET_NR_vfork:
5413 ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
5414 0, 0, 0, 0));
5415 break;
5416 #endif
5417 #ifdef TARGET_NR_ugetrlimit
5418 case TARGET_NR_ugetrlimit:
5420 struct rlimit rlim;
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))
5425 goto efault;
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);
5430 break;
5432 #endif
5433 #ifdef TARGET_NR_truncate64
5434 case TARGET_NR_truncate64:
5435 if (!(p = lock_user_string(arg1)))
5436 goto efault;
5437 ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
5438 unlock_user(p, arg1, 0);
5439 break;
5440 #endif
5441 #ifdef TARGET_NR_ftruncate64
5442 case TARGET_NR_ftruncate64:
5443 ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
5444 break;
5445 #endif
5446 #ifdef TARGET_NR_stat64
5447 case TARGET_NR_stat64:
5448 if (!(p = lock_user_string(arg1)))
5449 goto efault;
5450 ret = get_errno(stat(path(p), &st));
5451 unlock_user(p, arg1, 0);
5452 if (!is_error(ret))
5453 ret = host_to_target_stat64(cpu_env, arg2, &st);
5454 break;
5455 #endif
5456 #ifdef TARGET_NR_lstat64
5457 case TARGET_NR_lstat64:
5458 if (!(p = lock_user_string(arg1)))
5459 goto efault;
5460 ret = get_errno(lstat(path(p), &st));
5461 unlock_user(p, arg1, 0);
5462 if (!is_error(ret))
5463 ret = host_to_target_stat64(cpu_env, arg2, &st);
5464 break;
5465 #endif
5466 #ifdef TARGET_NR_fstat64
5467 case TARGET_NR_fstat64:
5468 ret = get_errno(fstat(arg1, &st));
5469 if (!is_error(ret))
5470 ret = host_to_target_stat64(cpu_env, arg2, &st);
5471 break;
5472 #endif
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:
5477 #endif
5478 #ifdef TARGET_NR_newfstatat
5479 case TARGET_NR_newfstatat:
5480 #endif
5481 if (!(p = lock_user_string(arg2)))
5482 goto efault;
5483 #ifdef __NR_fstatat64
5484 ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
5485 #else
5486 ret = get_errno(sys_newfstatat(arg1, path(p), &st, arg4));
5487 #endif
5488 if (!is_error(ret))
5489 ret = host_to_target_stat64(cpu_env, arg3, &st);
5490 break;
5491 #endif
5492 #ifdef USE_UID16
5493 case TARGET_NR_lchown:
5494 if (!(p = lock_user_string(arg1)))
5495 goto efault;
5496 ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
5497 unlock_user(p, arg1, 0);
5498 break;
5499 case TARGET_NR_getuid:
5500 ret = get_errno(high2lowuid(getuid()));
5501 break;
5502 case TARGET_NR_getgid:
5503 ret = get_errno(high2lowgid(getgid()));
5504 break;
5505 case TARGET_NR_geteuid:
5506 ret = get_errno(high2lowuid(geteuid()));
5507 break;
5508 case TARGET_NR_getegid:
5509 ret = get_errno(high2lowgid(getegid()));
5510 break;
5511 case TARGET_NR_setreuid:
5512 ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
5513 break;
5514 case TARGET_NR_setregid:
5515 ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
5516 break;
5517 case TARGET_NR_getgroups:
5519 int gidsetsize = arg1;
5520 uint16_t *target_grouplist;
5521 gid_t *grouplist;
5522 int i;
5524 grouplist = alloca(gidsetsize * sizeof(gid_t));
5525 ret = get_errno(getgroups(gidsetsize, grouplist));
5526 if (gidsetsize == 0)
5527 break;
5528 if (!is_error(ret)) {
5529 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
5530 if (!target_grouplist)
5531 goto efault;
5532 for(i = 0;i < ret; i++)
5533 target_grouplist[i] = tswap16(grouplist[i]);
5534 unlock_user(target_grouplist, arg2, gidsetsize * 2);
5537 break;
5538 case TARGET_NR_setgroups:
5540 int gidsetsize = arg1;
5541 uint16_t *target_grouplist;
5542 gid_t *grouplist;
5543 int i;
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;
5549 goto fail;
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));
5556 break;
5557 case TARGET_NR_fchown:
5558 ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
5559 break;
5560 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
5561 case TARGET_NR_fchownat:
5562 if (!(p = lock_user_string(arg2)))
5563 goto efault;
5564 ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
5565 unlock_user(p, arg2, 0);
5566 break;
5567 #endif
5568 #ifdef TARGET_NR_setresuid
5569 case TARGET_NR_setresuid:
5570 ret = get_errno(setresuid(low2highuid(arg1),
5571 low2highuid(arg2),
5572 low2highuid(arg3)));
5573 break;
5574 #endif
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))
5584 goto efault;
5587 break;
5588 #endif
5589 #ifdef TARGET_NR_getresgid
5590 case TARGET_NR_setresgid:
5591 ret = get_errno(setresgid(low2highgid(arg1),
5592 low2highgid(arg2),
5593 low2highgid(arg3)));
5594 break;
5595 #endif
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))
5605 goto efault;
5608 break;
5609 #endif
5610 case TARGET_NR_chown:
5611 if (!(p = lock_user_string(arg1)))
5612 goto efault;
5613 ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
5614 unlock_user(p, arg1, 0);
5615 break;
5616 case TARGET_NR_setuid:
5617 ret = get_errno(setuid(low2highuid(arg1)));
5618 break;
5619 case TARGET_NR_setgid:
5620 ret = get_errno(setgid(low2highgid(arg1)));
5621 break;
5622 case TARGET_NR_setfsuid:
5623 ret = get_errno(setfsuid(arg1));
5624 break;
5625 case TARGET_NR_setfsgid:
5626 ret = get_errno(setfsgid(arg1));
5627 break;
5628 #endif /* USE_UID16 */
5630 #ifdef TARGET_NR_lchown32
5631 case TARGET_NR_lchown32:
5632 if (!(p = lock_user_string(arg1)))
5633 goto efault;
5634 ret = get_errno(lchown(p, arg2, arg3));
5635 unlock_user(p, arg1, 0);
5636 break;
5637 #endif
5638 #ifdef TARGET_NR_getuid32
5639 case TARGET_NR_getuid32:
5640 ret = get_errno(getuid());
5641 break;
5642 #endif
5644 #if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
5645 /* Alpha specific */
5646 case TARGET_NR_getxuid:
5648 uid_t euid;
5649 euid=geteuid();
5650 ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
5652 ret = get_errno(getuid());
5653 break;
5654 #endif
5655 #if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
5656 /* Alpha specific */
5657 case TARGET_NR_getxgid:
5659 uid_t egid;
5660 egid=getegid();
5661 ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
5663 ret = get_errno(getgid());
5664 break;
5665 #endif
5667 #ifdef TARGET_NR_getgid32
5668 case TARGET_NR_getgid32:
5669 ret = get_errno(getgid());
5670 break;
5671 #endif
5672 #ifdef TARGET_NR_geteuid32
5673 case TARGET_NR_geteuid32:
5674 ret = get_errno(geteuid());
5675 break;
5676 #endif
5677 #ifdef TARGET_NR_getegid32
5678 case TARGET_NR_getegid32:
5679 ret = get_errno(getegid());
5680 break;
5681 #endif
5682 #ifdef TARGET_NR_setreuid32
5683 case TARGET_NR_setreuid32:
5684 ret = get_errno(setreuid(arg1, arg2));
5685 break;
5686 #endif
5687 #ifdef TARGET_NR_setregid32
5688 case TARGET_NR_setregid32:
5689 ret = get_errno(setregid(arg1, arg2));
5690 break;
5691 #endif
5692 #ifdef TARGET_NR_getgroups32
5693 case TARGET_NR_getgroups32:
5695 int gidsetsize = arg1;
5696 uint32_t *target_grouplist;
5697 gid_t *grouplist;
5698 int i;
5700 grouplist = alloca(gidsetsize * sizeof(gid_t));
5701 ret = get_errno(getgroups(gidsetsize, grouplist));
5702 if (gidsetsize == 0)
5703 break;
5704 if (!is_error(ret)) {
5705 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
5706 if (!target_grouplist) {
5707 ret = -TARGET_EFAULT;
5708 goto fail;
5710 for(i = 0;i < ret; i++)
5711 target_grouplist[i] = tswap32(grouplist[i]);
5712 unlock_user(target_grouplist, arg2, gidsetsize * 4);
5715 break;
5716 #endif
5717 #ifdef TARGET_NR_setgroups32
5718 case TARGET_NR_setgroups32:
5720 int gidsetsize = arg1;
5721 uint32_t *target_grouplist;
5722 gid_t *grouplist;
5723 int i;
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;
5729 goto fail;
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));
5736 break;
5737 #endif
5738 #ifdef TARGET_NR_fchown32
5739 case TARGET_NR_fchown32:
5740 ret = get_errno(fchown(arg1, arg2, arg3));
5741 break;
5742 #endif
5743 #ifdef TARGET_NR_setresuid32
5744 case TARGET_NR_setresuid32:
5745 ret = get_errno(setresuid(arg1, arg2, arg3));
5746 break;
5747 #endif
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))
5757 goto efault;
5760 break;
5761 #endif
5762 #ifdef TARGET_NR_setresgid32
5763 case TARGET_NR_setresgid32:
5764 ret = get_errno(setresgid(arg1, arg2, arg3));
5765 break;
5766 #endif
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))
5776 goto efault;
5779 break;
5780 #endif
5781 #ifdef TARGET_NR_chown32
5782 case TARGET_NR_chown32:
5783 if (!(p = lock_user_string(arg1)))
5784 goto efault;
5785 ret = get_errno(chown(p, arg2, arg3));
5786 unlock_user(p, arg1, 0);
5787 break;
5788 #endif
5789 #ifdef TARGET_NR_setuid32
5790 case TARGET_NR_setuid32:
5791 ret = get_errno(setuid(arg1));
5792 break;
5793 #endif
5794 #ifdef TARGET_NR_setgid32
5795 case TARGET_NR_setgid32:
5796 ret = get_errno(setgid(arg1));
5797 break;
5798 #endif
5799 #ifdef TARGET_NR_setfsuid32
5800 case TARGET_NR_setfsuid32:
5801 ret = get_errno(setfsuid(arg1));
5802 break;
5803 #endif
5804 #ifdef TARGET_NR_setfsgid32
5805 case TARGET_NR_setfsgid32:
5806 ret = get_errno(setfsgid(arg1));
5807 break;
5808 #endif
5810 case TARGET_NR_pivot_root:
5811 goto unimplemented;
5812 #ifdef TARGET_NR_mincore
5813 case TARGET_NR_mincore:
5815 void *a;
5816 ret = -TARGET_EFAULT;
5817 if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
5818 goto efault;
5819 if (!(p = lock_user_string(arg3)))
5820 goto mincore_fail;
5821 ret = get_errno(mincore(a, arg2, p));
5822 unlock_user(p, arg3, ret);
5823 mincore_fail:
5824 unlock_user(a, arg1, 0);
5826 break;
5827 #endif
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
5835 abi_long temp;
5836 temp = arg3;
5837 arg3 = arg4;
5838 arg4 = temp;
5840 #endif
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:
5844 #endif
5845 /* This is a hint, so ignoring and returning success is ok. */
5846 ret = get_errno(0);
5847 break;
5848 #endif
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. */
5855 ret = get_errno(0);
5856 break;
5857 #endif
5858 #if TARGET_ABI_BITS == 32
5859 case TARGET_NR_fcntl64:
5861 int cmd;
5862 struct flock64 fl;
5863 struct target_flock64 *target_fl;
5864 #ifdef TARGET_ARM
5865 struct target_eabi_flock64 *target_efl;
5866 #endif
5868 switch(arg2){
5869 case TARGET_F_GETLK64:
5870 cmd = F_GETLK64;
5871 break;
5872 case TARGET_F_SETLK64:
5873 cmd = F_SETLK64;
5874 break;
5875 case TARGET_F_SETLKW64:
5876 cmd = F_SETLK64;
5877 break;
5878 default:
5879 cmd = arg2;
5880 break;
5883 switch(arg2) {
5884 case TARGET_F_GETLK64:
5885 #ifdef TARGET_ARM
5886 if (((CPUARMState *)cpu_env)->eabi) {
5887 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1))
5888 goto efault;
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);
5895 } else
5896 #endif
5898 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1))
5899 goto efault;
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));
5908 if (ret == 0) {
5909 #ifdef TARGET_ARM
5910 if (((CPUARMState *)cpu_env)->eabi) {
5911 if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0))
5912 goto efault;
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);
5919 } else
5920 #endif
5922 if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0))
5923 goto efault;
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);
5932 break;
5934 case TARGET_F_SETLK64:
5935 case TARGET_F_SETLKW64:
5936 #ifdef TARGET_ARM
5937 if (((CPUARMState *)cpu_env)->eabi) {
5938 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1))
5939 goto efault;
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);
5946 } else
5947 #endif
5949 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1))
5950 goto efault;
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));
5959 break;
5960 default:
5961 ret = do_fcntl(arg1, cmd, arg3);
5962 break;
5964 break;
5966 #endif
5967 #ifdef TARGET_NR_cacheflush
5968 case TARGET_NR_cacheflush:
5969 /* self-modifying code is handled automatically, so nothing needed */
5970 ret = 0;
5971 break;
5972 #endif
5973 #ifdef TARGET_NR_security
5974 case TARGET_NR_security:
5975 goto unimplemented;
5976 #endif
5977 #ifdef TARGET_NR_getpagesize
5978 case TARGET_NR_getpagesize:
5979 ret = TARGET_PAGE_SIZE;
5980 break;
5981 #endif
5982 case TARGET_NR_gettid:
5983 ret = get_errno(gettid());
5984 break;
5985 #ifdef TARGET_NR_readahead
5986 case TARGET_NR_readahead:
5987 #if TARGET_ABI_BITS == 32
5988 #ifdef TARGET_ARM
5989 if (((CPUARMState *)cpu_env)->eabi)
5991 arg2 = arg3;
5992 arg3 = arg4;
5993 arg4 = arg5;
5995 #endif
5996 ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
5997 #else
5998 ret = get_errno(readahead(arg1, arg2, arg3));
5999 #endif
6000 break;
6001 #endif
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;
6016 #endif
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;
6021 ret = 0;
6022 break;
6023 #elif defined(TARGET_CRIS)
6024 if (arg1 & 0xff)
6025 ret = -TARGET_EINVAL;
6026 else {
6027 ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
6028 ret = 0;
6030 break;
6031 #elif defined(TARGET_I386) && defined(TARGET_ABI32)
6032 ret = do_set_thread_area(cpu_env, arg1);
6033 break;
6034 #else
6035 goto unimplemented_nowarn;
6036 #endif
6037 #endif
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);
6042 #else
6043 goto unimplemented_nowarn;
6044 #endif
6045 #endif
6046 #ifdef TARGET_NR_getdomainname
6047 case TARGET_NR_getdomainname:
6048 goto unimplemented_nowarn;
6049 #endif
6051 #ifdef TARGET_NR_clock_gettime
6052 case TARGET_NR_clock_gettime:
6054 struct timespec ts;
6055 ret = get_errno(clock_gettime(arg1, &ts));
6056 if (!is_error(ret)) {
6057 host_to_target_timespec(arg2, &ts);
6059 break;
6061 #endif
6062 #ifdef TARGET_NR_clock_getres
6063 case TARGET_NR_clock_getres:
6065 struct timespec ts;
6066 ret = get_errno(clock_getres(arg1, &ts));
6067 if (!is_error(ret)) {
6068 host_to_target_timespec(arg2, &ts);
6070 break;
6072 #endif
6073 #ifdef TARGET_NR_clock_nanosleep
6074 case TARGET_NR_clock_nanosleep:
6076 struct timespec ts;
6077 target_to_host_timespec(&ts, arg3);
6078 ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
6079 if (arg4)
6080 host_to_target_timespec(arg4, &ts);
6081 break;
6083 #endif
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)));
6088 break;
6089 #endif
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)));
6094 break;
6095 #endif
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)));
6101 break;
6102 #endif
6104 #ifdef TARGET_NR_set_robust_list
6105 case TARGET_NR_set_robust_list:
6106 goto unimplemented_nowarn;
6107 #endif
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));
6115 if (!arg2)
6116 ret = get_errno(sys_utimensat(arg1, NULL, ts, arg4));
6117 else {
6118 if (!(p = lock_user_string(arg2))) {
6119 ret = -TARGET_EFAULT;
6120 goto fail;
6122 ret = get_errno(sys_utimensat(arg1, path(p), ts, arg4));
6123 unlock_user(p, arg2, 0);
6126 break;
6127 #endif
6128 #if defined(USE_NPTL)
6129 case TARGET_NR_futex:
6130 ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
6131 break;
6132 #endif
6133 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
6134 case TARGET_NR_inotify_init:
6135 ret = get_errno(sys_inotify_init());
6136 break;
6137 #endif
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);
6143 break;
6144 #endif
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));
6148 break;
6149 #endif
6151 default:
6152 unimplemented:
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:
6156 #endif
6157 ret = -TARGET_ENOSYS;
6158 break;
6160 fail:
6161 #ifdef DEBUG
6162 gemu_log(" = %ld\n", ret);
6163 #endif
6164 if(do_strace)
6165 print_syscall_ret(num, ret);
6166 return ret;
6167 efault:
6168 ret = -TARGET_EFAULT;
6169 goto fail;