[MINI2440] Clean the demo start script
[qemu/mini2440.git] / linux-user / syscall.c
blob226ee6ca6e6b9f96086b2f98c7411948c82d7071
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_openat __NR_openat
173 #define __NR_sys_readlinkat __NR_readlinkat
174 #define __NR_sys_renameat __NR_renameat
175 #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
176 #define __NR_sys_symlinkat __NR_symlinkat
177 #define __NR_sys_syslog __NR_syslog
178 #define __NR_sys_tgkill __NR_tgkill
179 #define __NR_sys_tkill __NR_tkill
180 #define __NR_sys_unlinkat __NR_unlinkat
181 #define __NR_sys_utimensat __NR_utimensat
182 #define __NR_sys_futex __NR_futex
183 #define __NR_sys_inotify_init __NR_inotify_init
184 #define __NR_sys_inotify_add_watch __NR_inotify_add_watch
185 #define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
187 #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
188 #define __NR__llseek __NR_lseek
189 #endif
191 #ifdef __NR_gettid
192 _syscall0(int, gettid)
193 #else
194 /* This is a replacement for the host gettid() and must return a host
195 errno. */
196 static int gettid(void) {
197 return -ENOSYS;
199 #endif
200 _syscall1(int,sys_uname,struct new_utsname *,buf)
201 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
202 _syscall4(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode,int,flags)
203 #endif
204 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
205 _syscall4(int,sys_fchmodat,int,dirfd,const char *,pathname,
206 mode_t,mode,int,flags)
207 #endif
208 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) && defined(USE_UID16)
209 _syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
210 uid_t,owner,gid_t,group,int,flags)
211 #endif
212 #if defined(TARGET_NR_fstatat64) && defined(__NR_fstatat64)
213 _syscall4(int,sys_fstatat64,int,dirfd,const char *,pathname,
214 struct stat *,buf,int,flags)
215 #endif
216 #if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
217 _syscall3(int,sys_futimesat,int,dirfd,const char *,pathname,
218 const struct timeval *,times)
219 #endif
220 _syscall2(int,sys_getcwd1,char *,buf,size_t,size)
221 #if TARGET_ABI_BITS == 32
222 _syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
223 #endif
224 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
225 _syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
226 #endif
227 _syscall2(int, sys_getpriority, int, which, int, who);
228 #if !defined (__x86_64__)
229 _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo,
230 loff_t *, res, uint, wh);
231 #endif
232 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
233 _syscall5(int,sys_linkat,int,olddirfd,const char *,oldpath,
234 int,newdirfd,const char *,newpath,int,flags)
235 #endif
236 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
237 _syscall3(int,sys_mkdirat,int,dirfd,const char *,pathname,mode_t,mode)
238 #endif
239 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
240 _syscall4(int,sys_mknodat,int,dirfd,const char *,pathname,
241 mode_t,mode,dev_t,dev)
242 #endif
243 #if defined(TARGET_NR_openat) && defined(__NR_openat)
244 _syscall4(int,sys_openat,int,dirfd,const char *,pathname,int,flags,mode_t,mode)
245 #endif
246 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
247 _syscall4(int,sys_readlinkat,int,dirfd,const char *,pathname,
248 char *,buf,size_t,bufsize)
249 #endif
250 #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
251 _syscall4(int,sys_renameat,int,olddirfd,const char *,oldpath,
252 int,newdirfd,const char *,newpath)
253 #endif
254 _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
255 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
256 _syscall3(int,sys_symlinkat,const char *,oldpath,
257 int,newdirfd,const char *,newpath)
258 #endif
259 _syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
260 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
261 _syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
262 #endif
263 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
264 _syscall2(int,sys_tkill,int,tid,int,sig)
265 #endif
266 #ifdef __NR_exit_group
267 _syscall1(int,exit_group,int,error_code)
268 #endif
269 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
270 _syscall1(int,set_tid_address,int *,tidptr)
271 #endif
272 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
273 _syscall3(int,sys_unlinkat,int,dirfd,const char *,pathname,int,flags)
274 #endif
275 #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
276 _syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
277 const struct timespec *,tsp,int,flags)
278 #endif
279 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
280 _syscall0(int,sys_inotify_init)
281 #endif
282 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
283 _syscall3(int,sys_inotify_add_watch,int,fd,const char *,pathname,uint32_t,mask)
284 #endif
285 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
286 _syscall2(int,sys_inotify_rm_watch,int,fd,uint32_t,wd)
287 #endif
288 #if defined(USE_NPTL)
289 #if defined(TARGET_NR_futex) && defined(__NR_futex)
290 _syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
291 const struct timespec *,timeout,int *,uaddr2,int,val3)
292 #endif
293 #endif
295 extern int personality(int);
296 extern int flock(int, int);
297 extern int setfsuid(int);
298 extern int setfsgid(int);
299 extern int setgroups(int, gid_t *);
301 #define ERRNO_TABLE_SIZE 1200
303 /* target_to_host_errno_table[] is initialized from
304 * host_to_target_errno_table[] in syscall_init(). */
305 static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
309 * This list is the union of errno values overridden in asm-<arch>/errno.h
310 * minus the errnos that are not actually generic to all archs.
312 static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
313 [EIDRM] = TARGET_EIDRM,
314 [ECHRNG] = TARGET_ECHRNG,
315 [EL2NSYNC] = TARGET_EL2NSYNC,
316 [EL3HLT] = TARGET_EL3HLT,
317 [EL3RST] = TARGET_EL3RST,
318 [ELNRNG] = TARGET_ELNRNG,
319 [EUNATCH] = TARGET_EUNATCH,
320 [ENOCSI] = TARGET_ENOCSI,
321 [EL2HLT] = TARGET_EL2HLT,
322 [EDEADLK] = TARGET_EDEADLK,
323 [ENOLCK] = TARGET_ENOLCK,
324 [EBADE] = TARGET_EBADE,
325 [EBADR] = TARGET_EBADR,
326 [EXFULL] = TARGET_EXFULL,
327 [ENOANO] = TARGET_ENOANO,
328 [EBADRQC] = TARGET_EBADRQC,
329 [EBADSLT] = TARGET_EBADSLT,
330 [EBFONT] = TARGET_EBFONT,
331 [ENOSTR] = TARGET_ENOSTR,
332 [ENODATA] = TARGET_ENODATA,
333 [ETIME] = TARGET_ETIME,
334 [ENOSR] = TARGET_ENOSR,
335 [ENONET] = TARGET_ENONET,
336 [ENOPKG] = TARGET_ENOPKG,
337 [EREMOTE] = TARGET_EREMOTE,
338 [ENOLINK] = TARGET_ENOLINK,
339 [EADV] = TARGET_EADV,
340 [ESRMNT] = TARGET_ESRMNT,
341 [ECOMM] = TARGET_ECOMM,
342 [EPROTO] = TARGET_EPROTO,
343 [EDOTDOT] = TARGET_EDOTDOT,
344 [EMULTIHOP] = TARGET_EMULTIHOP,
345 [EBADMSG] = TARGET_EBADMSG,
346 [ENAMETOOLONG] = TARGET_ENAMETOOLONG,
347 [EOVERFLOW] = TARGET_EOVERFLOW,
348 [ENOTUNIQ] = TARGET_ENOTUNIQ,
349 [EBADFD] = TARGET_EBADFD,
350 [EREMCHG] = TARGET_EREMCHG,
351 [ELIBACC] = TARGET_ELIBACC,
352 [ELIBBAD] = TARGET_ELIBBAD,
353 [ELIBSCN] = TARGET_ELIBSCN,
354 [ELIBMAX] = TARGET_ELIBMAX,
355 [ELIBEXEC] = TARGET_ELIBEXEC,
356 [EILSEQ] = TARGET_EILSEQ,
357 [ENOSYS] = TARGET_ENOSYS,
358 [ELOOP] = TARGET_ELOOP,
359 [ERESTART] = TARGET_ERESTART,
360 [ESTRPIPE] = TARGET_ESTRPIPE,
361 [ENOTEMPTY] = TARGET_ENOTEMPTY,
362 [EUSERS] = TARGET_EUSERS,
363 [ENOTSOCK] = TARGET_ENOTSOCK,
364 [EDESTADDRREQ] = TARGET_EDESTADDRREQ,
365 [EMSGSIZE] = TARGET_EMSGSIZE,
366 [EPROTOTYPE] = TARGET_EPROTOTYPE,
367 [ENOPROTOOPT] = TARGET_ENOPROTOOPT,
368 [EPROTONOSUPPORT] = TARGET_EPROTONOSUPPORT,
369 [ESOCKTNOSUPPORT] = TARGET_ESOCKTNOSUPPORT,
370 [EOPNOTSUPP] = TARGET_EOPNOTSUPP,
371 [EPFNOSUPPORT] = TARGET_EPFNOSUPPORT,
372 [EAFNOSUPPORT] = TARGET_EAFNOSUPPORT,
373 [EADDRINUSE] = TARGET_EADDRINUSE,
374 [EADDRNOTAVAIL] = TARGET_EADDRNOTAVAIL,
375 [ENETDOWN] = TARGET_ENETDOWN,
376 [ENETUNREACH] = TARGET_ENETUNREACH,
377 [ENETRESET] = TARGET_ENETRESET,
378 [ECONNABORTED] = TARGET_ECONNABORTED,
379 [ECONNRESET] = TARGET_ECONNRESET,
380 [ENOBUFS] = TARGET_ENOBUFS,
381 [EISCONN] = TARGET_EISCONN,
382 [ENOTCONN] = TARGET_ENOTCONN,
383 [EUCLEAN] = TARGET_EUCLEAN,
384 [ENOTNAM] = TARGET_ENOTNAM,
385 [ENAVAIL] = TARGET_ENAVAIL,
386 [EISNAM] = TARGET_EISNAM,
387 [EREMOTEIO] = TARGET_EREMOTEIO,
388 [ESHUTDOWN] = TARGET_ESHUTDOWN,
389 [ETOOMANYREFS] = TARGET_ETOOMANYREFS,
390 [ETIMEDOUT] = TARGET_ETIMEDOUT,
391 [ECONNREFUSED] = TARGET_ECONNREFUSED,
392 [EHOSTDOWN] = TARGET_EHOSTDOWN,
393 [EHOSTUNREACH] = TARGET_EHOSTUNREACH,
394 [EALREADY] = TARGET_EALREADY,
395 [EINPROGRESS] = TARGET_EINPROGRESS,
396 [ESTALE] = TARGET_ESTALE,
397 [ECANCELED] = TARGET_ECANCELED,
398 [ENOMEDIUM] = TARGET_ENOMEDIUM,
399 [EMEDIUMTYPE] = TARGET_EMEDIUMTYPE,
400 #ifdef ENOKEY
401 [ENOKEY] = TARGET_ENOKEY,
402 #endif
403 #ifdef EKEYEXPIRED
404 [EKEYEXPIRED] = TARGET_EKEYEXPIRED,
405 #endif
406 #ifdef EKEYREVOKED
407 [EKEYREVOKED] = TARGET_EKEYREVOKED,
408 #endif
409 #ifdef EKEYREJECTED
410 [EKEYREJECTED] = TARGET_EKEYREJECTED,
411 #endif
412 #ifdef EOWNERDEAD
413 [EOWNERDEAD] = TARGET_EOWNERDEAD,
414 #endif
415 #ifdef ENOTRECOVERABLE
416 [ENOTRECOVERABLE] = TARGET_ENOTRECOVERABLE,
417 #endif
420 static inline int host_to_target_errno(int err)
422 if(host_to_target_errno_table[err])
423 return host_to_target_errno_table[err];
424 return err;
427 static inline int target_to_host_errno(int err)
429 if (target_to_host_errno_table[err])
430 return target_to_host_errno_table[err];
431 return err;
434 static inline abi_long get_errno(abi_long ret)
436 if (ret == -1)
437 return -host_to_target_errno(errno);
438 else
439 return ret;
442 static inline int is_error(abi_long ret)
444 return (abi_ulong)ret >= (abi_ulong)(-4096);
447 char *target_strerror(int err)
449 return strerror(target_to_host_errno(err));
452 static abi_ulong target_brk;
453 static abi_ulong target_original_brk;
455 void target_set_brk(abi_ulong new_brk)
457 target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
460 /* do_brk() must return target values and target errnos. */
461 abi_long do_brk(abi_ulong new_brk)
463 abi_ulong brk_page;
464 abi_long mapped_addr;
465 int new_alloc_size;
467 if (!new_brk)
468 return target_brk;
469 if (new_brk < target_original_brk)
470 return target_brk;
472 brk_page = HOST_PAGE_ALIGN(target_brk);
474 /* If the new brk is less than this, set it and we're done... */
475 if (new_brk < brk_page) {
476 target_brk = new_brk;
477 return target_brk;
480 /* We need to allocate more memory after the brk... */
481 new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
482 mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
483 PROT_READ|PROT_WRITE,
484 MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
486 if (!is_error(mapped_addr))
487 target_brk = new_brk;
489 return target_brk;
492 static inline abi_long copy_from_user_fdset(fd_set *fds,
493 abi_ulong target_fds_addr,
494 int n)
496 int i, nw, j, k;
497 abi_ulong b, *target_fds;
499 nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
500 if (!(target_fds = lock_user(VERIFY_READ,
501 target_fds_addr,
502 sizeof(abi_ulong) * nw,
503 1)))
504 return -TARGET_EFAULT;
506 FD_ZERO(fds);
507 k = 0;
508 for (i = 0; i < nw; i++) {
509 /* grab the abi_ulong */
510 __get_user(b, &target_fds[i]);
511 for (j = 0; j < TARGET_ABI_BITS; j++) {
512 /* check the bit inside the abi_ulong */
513 if ((b >> j) & 1)
514 FD_SET(k, fds);
515 k++;
519 unlock_user(target_fds, target_fds_addr, 0);
521 return 0;
524 static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
525 const fd_set *fds,
526 int n)
528 int i, nw, j, k;
529 abi_long v;
530 abi_ulong *target_fds;
532 nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
533 if (!(target_fds = lock_user(VERIFY_WRITE,
534 target_fds_addr,
535 sizeof(abi_ulong) * nw,
536 0)))
537 return -TARGET_EFAULT;
539 k = 0;
540 for (i = 0; i < nw; i++) {
541 v = 0;
542 for (j = 0; j < TARGET_ABI_BITS; j++) {
543 v |= ((FD_ISSET(k, fds) != 0) << j);
544 k++;
546 __put_user(v, &target_fds[i]);
549 unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
551 return 0;
554 #if defined(__alpha__)
555 #define HOST_HZ 1024
556 #else
557 #define HOST_HZ 100
558 #endif
560 static inline abi_long host_to_target_clock_t(long ticks)
562 #if HOST_HZ == TARGET_HZ
563 return ticks;
564 #else
565 return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
566 #endif
569 static inline abi_long host_to_target_rusage(abi_ulong target_addr,
570 const struct rusage *rusage)
572 struct target_rusage *target_rusage;
574 if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
575 return -TARGET_EFAULT;
576 target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
577 target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
578 target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
579 target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec);
580 target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss);
581 target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss);
582 target_rusage->ru_idrss = tswapl(rusage->ru_idrss);
583 target_rusage->ru_isrss = tswapl(rusage->ru_isrss);
584 target_rusage->ru_minflt = tswapl(rusage->ru_minflt);
585 target_rusage->ru_majflt = tswapl(rusage->ru_majflt);
586 target_rusage->ru_nswap = tswapl(rusage->ru_nswap);
587 target_rusage->ru_inblock = tswapl(rusage->ru_inblock);
588 target_rusage->ru_oublock = tswapl(rusage->ru_oublock);
589 target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd);
590 target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv);
591 target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);
592 target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
593 target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
594 unlock_user_struct(target_rusage, target_addr, 1);
596 return 0;
599 static inline abi_long copy_from_user_timeval(struct timeval *tv,
600 abi_ulong target_tv_addr)
602 struct target_timeval *target_tv;
604 if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
605 return -TARGET_EFAULT;
607 __get_user(tv->tv_sec, &target_tv->tv_sec);
608 __get_user(tv->tv_usec, &target_tv->tv_usec);
610 unlock_user_struct(target_tv, target_tv_addr, 0);
612 return 0;
615 static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
616 const struct timeval *tv)
618 struct target_timeval *target_tv;
620 if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
621 return -TARGET_EFAULT;
623 __put_user(tv->tv_sec, &target_tv->tv_sec);
624 __put_user(tv->tv_usec, &target_tv->tv_usec);
626 unlock_user_struct(target_tv, target_tv_addr, 1);
628 return 0;
632 /* do_select() must return target values and target errnos. */
633 static abi_long do_select(int n,
634 abi_ulong rfd_addr, abi_ulong wfd_addr,
635 abi_ulong efd_addr, abi_ulong target_tv_addr)
637 fd_set rfds, wfds, efds;
638 fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
639 struct timeval tv, *tv_ptr;
640 abi_long ret;
642 if (rfd_addr) {
643 if (copy_from_user_fdset(&rfds, rfd_addr, n))
644 return -TARGET_EFAULT;
645 rfds_ptr = &rfds;
646 } else {
647 rfds_ptr = NULL;
649 if (wfd_addr) {
650 if (copy_from_user_fdset(&wfds, wfd_addr, n))
651 return -TARGET_EFAULT;
652 wfds_ptr = &wfds;
653 } else {
654 wfds_ptr = NULL;
656 if (efd_addr) {
657 if (copy_from_user_fdset(&efds, efd_addr, n))
658 return -TARGET_EFAULT;
659 efds_ptr = &efds;
660 } else {
661 efds_ptr = NULL;
664 if (target_tv_addr) {
665 if (copy_from_user_timeval(&tv, target_tv_addr))
666 return -TARGET_EFAULT;
667 tv_ptr = &tv;
668 } else {
669 tv_ptr = NULL;
672 ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
674 if (!is_error(ret)) {
675 if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
676 return -TARGET_EFAULT;
677 if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
678 return -TARGET_EFAULT;
679 if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
680 return -TARGET_EFAULT;
682 if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
683 return -TARGET_EFAULT;
686 return ret;
689 static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
690 abi_ulong target_addr,
691 socklen_t len)
693 struct target_sockaddr *target_saddr;
695 target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
696 if (!target_saddr)
697 return -TARGET_EFAULT;
698 memcpy(addr, target_saddr, len);
699 addr->sa_family = tswap16(target_saddr->sa_family);
700 unlock_user(target_saddr, target_addr, 0);
702 return 0;
705 static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
706 struct sockaddr *addr,
707 socklen_t len)
709 struct target_sockaddr *target_saddr;
711 target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
712 if (!target_saddr)
713 return -TARGET_EFAULT;
714 memcpy(target_saddr, addr, len);
715 target_saddr->sa_family = tswap16(addr->sa_family);
716 unlock_user(target_saddr, target_addr, len);
718 return 0;
721 /* ??? Should this also swap msgh->name? */
722 static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
723 struct target_msghdr *target_msgh)
725 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
726 abi_long msg_controllen;
727 abi_ulong target_cmsg_addr;
728 struct target_cmsghdr *target_cmsg;
729 socklen_t space = 0;
731 msg_controllen = tswapl(target_msgh->msg_controllen);
732 if (msg_controllen < sizeof (struct target_cmsghdr))
733 goto the_end;
734 target_cmsg_addr = tswapl(target_msgh->msg_control);
735 target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
736 if (!target_cmsg)
737 return -TARGET_EFAULT;
739 while (cmsg && target_cmsg) {
740 void *data = CMSG_DATA(cmsg);
741 void *target_data = TARGET_CMSG_DATA(target_cmsg);
743 int len = tswapl(target_cmsg->cmsg_len)
744 - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
746 space += CMSG_SPACE(len);
747 if (space > msgh->msg_controllen) {
748 space -= CMSG_SPACE(len);
749 gemu_log("Host cmsg overflow\n");
750 break;
753 cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
754 cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
755 cmsg->cmsg_len = CMSG_LEN(len);
757 if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
758 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
759 memcpy(data, target_data, len);
760 } else {
761 int *fd = (int *)data;
762 int *target_fd = (int *)target_data;
763 int i, numfds = len / sizeof(int);
765 for (i = 0; i < numfds; i++)
766 fd[i] = tswap32(target_fd[i]);
769 cmsg = CMSG_NXTHDR(msgh, cmsg);
770 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
772 unlock_user(target_cmsg, target_cmsg_addr, 0);
773 the_end:
774 msgh->msg_controllen = space;
775 return 0;
778 /* ??? Should this also swap msgh->name? */
779 static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
780 struct msghdr *msgh)
782 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
783 abi_long msg_controllen;
784 abi_ulong target_cmsg_addr;
785 struct target_cmsghdr *target_cmsg;
786 socklen_t space = 0;
788 msg_controllen = tswapl(target_msgh->msg_controllen);
789 if (msg_controllen < sizeof (struct target_cmsghdr))
790 goto the_end;
791 target_cmsg_addr = tswapl(target_msgh->msg_control);
792 target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
793 if (!target_cmsg)
794 return -TARGET_EFAULT;
796 while (cmsg && target_cmsg) {
797 void *data = CMSG_DATA(cmsg);
798 void *target_data = TARGET_CMSG_DATA(target_cmsg);
800 int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
802 space += TARGET_CMSG_SPACE(len);
803 if (space > msg_controllen) {
804 space -= TARGET_CMSG_SPACE(len);
805 gemu_log("Target cmsg overflow\n");
806 break;
809 target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
810 target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
811 target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
813 if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
814 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
815 memcpy(target_data, data, len);
816 } else {
817 int *fd = (int *)data;
818 int *target_fd = (int *)target_data;
819 int i, numfds = len / sizeof(int);
821 for (i = 0; i < numfds; i++)
822 target_fd[i] = tswap32(fd[i]);
825 cmsg = CMSG_NXTHDR(msgh, cmsg);
826 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
828 unlock_user(target_cmsg, target_cmsg_addr, space);
829 the_end:
830 target_msgh->msg_controllen = tswapl(space);
831 return 0;
834 /* do_setsockopt() Must return target values and target errnos. */
835 static abi_long do_setsockopt(int sockfd, int level, int optname,
836 abi_ulong optval_addr, socklen_t optlen)
838 abi_long ret;
839 int val;
841 switch(level) {
842 case SOL_TCP:
843 /* TCP options all take an 'int' value. */
844 if (optlen < sizeof(uint32_t))
845 return -TARGET_EINVAL;
847 if (get_user_u32(val, optval_addr))
848 return -TARGET_EFAULT;
849 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
850 break;
851 case SOL_IP:
852 switch(optname) {
853 case IP_TOS:
854 case IP_TTL:
855 case IP_HDRINCL:
856 case IP_ROUTER_ALERT:
857 case IP_RECVOPTS:
858 case IP_RETOPTS:
859 case IP_PKTINFO:
860 case IP_MTU_DISCOVER:
861 case IP_RECVERR:
862 case IP_RECVTOS:
863 #ifdef IP_FREEBIND
864 case IP_FREEBIND:
865 #endif
866 case IP_MULTICAST_TTL:
867 case IP_MULTICAST_LOOP:
868 val = 0;
869 if (optlen >= sizeof(uint32_t)) {
870 if (get_user_u32(val, optval_addr))
871 return -TARGET_EFAULT;
872 } else if (optlen >= 1) {
873 if (get_user_u8(val, optval_addr))
874 return -TARGET_EFAULT;
876 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
877 break;
878 default:
879 goto unimplemented;
881 break;
882 case TARGET_SOL_SOCKET:
883 switch (optname) {
884 /* Options with 'int' argument. */
885 case TARGET_SO_DEBUG:
886 optname = SO_DEBUG;
887 break;
888 case TARGET_SO_REUSEADDR:
889 optname = SO_REUSEADDR;
890 break;
891 case TARGET_SO_TYPE:
892 optname = SO_TYPE;
893 break;
894 case TARGET_SO_ERROR:
895 optname = SO_ERROR;
896 break;
897 case TARGET_SO_DONTROUTE:
898 optname = SO_DONTROUTE;
899 break;
900 case TARGET_SO_BROADCAST:
901 optname = SO_BROADCAST;
902 break;
903 case TARGET_SO_SNDBUF:
904 optname = SO_SNDBUF;
905 break;
906 case TARGET_SO_RCVBUF:
907 optname = SO_RCVBUF;
908 break;
909 case TARGET_SO_KEEPALIVE:
910 optname = SO_KEEPALIVE;
911 break;
912 case TARGET_SO_OOBINLINE:
913 optname = SO_OOBINLINE;
914 break;
915 case TARGET_SO_NO_CHECK:
916 optname = SO_NO_CHECK;
917 break;
918 case TARGET_SO_PRIORITY:
919 optname = SO_PRIORITY;
920 break;
921 #ifdef SO_BSDCOMPAT
922 case TARGET_SO_BSDCOMPAT:
923 optname = SO_BSDCOMPAT;
924 break;
925 #endif
926 case TARGET_SO_PASSCRED:
927 optname = SO_PASSCRED;
928 break;
929 case TARGET_SO_TIMESTAMP:
930 optname = SO_TIMESTAMP;
931 break;
932 case TARGET_SO_RCVLOWAT:
933 optname = SO_RCVLOWAT;
934 break;
935 case TARGET_SO_RCVTIMEO:
936 optname = SO_RCVTIMEO;
937 break;
938 case TARGET_SO_SNDTIMEO:
939 optname = SO_SNDTIMEO;
940 break;
941 break;
942 default:
943 goto unimplemented;
945 if (optlen < sizeof(uint32_t))
946 return -TARGET_EINVAL;
948 if (get_user_u32(val, optval_addr))
949 return -TARGET_EFAULT;
950 ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
951 break;
952 default:
953 unimplemented:
954 gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
955 ret = -TARGET_ENOPROTOOPT;
957 return ret;
960 /* do_getsockopt() Must return target values and target errnos. */
961 static abi_long do_getsockopt(int sockfd, int level, int optname,
962 abi_ulong optval_addr, abi_ulong optlen)
964 abi_long ret;
965 int len, val;
966 socklen_t lv;
968 switch(level) {
969 case TARGET_SOL_SOCKET:
970 level = SOL_SOCKET;
971 switch (optname) {
972 case TARGET_SO_LINGER:
973 case TARGET_SO_RCVTIMEO:
974 case TARGET_SO_SNDTIMEO:
975 case TARGET_SO_PEERCRED:
976 case TARGET_SO_PEERNAME:
977 /* These don't just return a single integer */
978 goto unimplemented;
979 default:
980 goto int_case;
982 break;
983 case SOL_TCP:
984 /* TCP options all take an 'int' value. */
985 int_case:
986 if (get_user_u32(len, optlen))
987 return -TARGET_EFAULT;
988 if (len < 0)
989 return -TARGET_EINVAL;
990 lv = sizeof(int);
991 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
992 if (ret < 0)
993 return ret;
994 val = tswap32(val);
995 if (len > lv)
996 len = lv;
997 if (len == 4) {
998 if (put_user_u32(val, optval_addr))
999 return -TARGET_EFAULT;
1000 } else {
1001 if (put_user_u8(val, optval_addr))
1002 return -TARGET_EFAULT;
1004 if (put_user_u32(len, optlen))
1005 return -TARGET_EFAULT;
1006 break;
1007 case SOL_IP:
1008 switch(optname) {
1009 case IP_TOS:
1010 case IP_TTL:
1011 case IP_HDRINCL:
1012 case IP_ROUTER_ALERT:
1013 case IP_RECVOPTS:
1014 case IP_RETOPTS:
1015 case IP_PKTINFO:
1016 case IP_MTU_DISCOVER:
1017 case IP_RECVERR:
1018 case IP_RECVTOS:
1019 #ifdef IP_FREEBIND
1020 case IP_FREEBIND:
1021 #endif
1022 case IP_MULTICAST_TTL:
1023 case IP_MULTICAST_LOOP:
1024 if (get_user_u32(len, optlen))
1025 return -TARGET_EFAULT;
1026 if (len < 0)
1027 return -TARGET_EINVAL;
1028 lv = sizeof(int);
1029 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1030 if (ret < 0)
1031 return ret;
1032 if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
1033 len = 1;
1034 if (put_user_u32(len, optlen)
1035 || put_user_u8(val, optval_addr))
1036 return -TARGET_EFAULT;
1037 } else {
1038 if (len > sizeof(int))
1039 len = sizeof(int);
1040 if (put_user_u32(len, optlen)
1041 || put_user_u32(val, optval_addr))
1042 return -TARGET_EFAULT;
1044 break;
1045 default:
1046 ret = -TARGET_ENOPROTOOPT;
1047 break;
1049 break;
1050 default:
1051 unimplemented:
1052 gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1053 level, optname);
1054 ret = -TARGET_EOPNOTSUPP;
1055 break;
1057 return ret;
1060 /* FIXME
1061 * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1062 * other lock functions have a return code of 0 for failure.
1064 static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1065 int count, int copy)
1067 struct target_iovec *target_vec;
1068 abi_ulong base;
1069 int i;
1071 target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1072 if (!target_vec)
1073 return -TARGET_EFAULT;
1074 for(i = 0;i < count; i++) {
1075 base = tswapl(target_vec[i].iov_base);
1076 vec[i].iov_len = tswapl(target_vec[i].iov_len);
1077 if (vec[i].iov_len != 0) {
1078 vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
1079 /* Don't check lock_user return value. We must call writev even
1080 if a element has invalid base address. */
1081 } else {
1082 /* zero length pointer is ignored */
1083 vec[i].iov_base = NULL;
1086 unlock_user (target_vec, target_addr, 0);
1087 return 0;
1090 static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1091 int count, int copy)
1093 struct target_iovec *target_vec;
1094 abi_ulong base;
1095 int i;
1097 target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1098 if (!target_vec)
1099 return -TARGET_EFAULT;
1100 for(i = 0;i < count; i++) {
1101 if (target_vec[i].iov_base) {
1102 base = tswapl(target_vec[i].iov_base);
1103 unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1106 unlock_user (target_vec, target_addr, 0);
1108 return 0;
1111 /* do_socket() Must return target values and target errnos. */
1112 static abi_long do_socket(int domain, int type, int protocol)
1114 #if defined(TARGET_MIPS)
1115 switch(type) {
1116 case TARGET_SOCK_DGRAM:
1117 type = SOCK_DGRAM;
1118 break;
1119 case TARGET_SOCK_STREAM:
1120 type = SOCK_STREAM;
1121 break;
1122 case TARGET_SOCK_RAW:
1123 type = SOCK_RAW;
1124 break;
1125 case TARGET_SOCK_RDM:
1126 type = SOCK_RDM;
1127 break;
1128 case TARGET_SOCK_SEQPACKET:
1129 type = SOCK_SEQPACKET;
1130 break;
1131 case TARGET_SOCK_PACKET:
1132 type = SOCK_PACKET;
1133 break;
1135 #endif
1136 if (domain == PF_NETLINK)
1137 return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1138 return get_errno(socket(domain, type, protocol));
1141 /* MAX_SOCK_ADDR from linux/net/socket.c */
1142 #define MAX_SOCK_ADDR 128
1144 /* do_bind() Must return target values and target errnos. */
1145 static abi_long do_bind(int sockfd, abi_ulong target_addr,
1146 socklen_t addrlen)
1148 void *addr;
1150 if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
1151 return -TARGET_EINVAL;
1153 addr = alloca(addrlen);
1155 target_to_host_sockaddr(addr, target_addr, addrlen);
1156 return get_errno(bind(sockfd, addr, addrlen));
1159 /* do_connect() Must return target values and target errnos. */
1160 static abi_long do_connect(int sockfd, abi_ulong target_addr,
1161 socklen_t addrlen)
1163 void *addr;
1165 if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
1166 return -TARGET_EINVAL;
1168 addr = alloca(addrlen);
1170 target_to_host_sockaddr(addr, target_addr, addrlen);
1171 return get_errno(connect(sockfd, addr, addrlen));
1174 /* do_sendrecvmsg() Must return target values and target errnos. */
1175 static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1176 int flags, int send)
1178 abi_long ret, len;
1179 struct target_msghdr *msgp;
1180 struct msghdr msg;
1181 int count;
1182 struct iovec *vec;
1183 abi_ulong target_vec;
1185 /* FIXME */
1186 if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1187 msgp,
1188 target_msg,
1189 send ? 1 : 0))
1190 return -TARGET_EFAULT;
1191 if (msgp->msg_name) {
1192 msg.msg_namelen = tswap32(msgp->msg_namelen);
1193 msg.msg_name = alloca(msg.msg_namelen);
1194 target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
1195 msg.msg_namelen);
1196 } else {
1197 msg.msg_name = NULL;
1198 msg.msg_namelen = 0;
1200 msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
1201 msg.msg_control = alloca(msg.msg_controllen);
1202 msg.msg_flags = tswap32(msgp->msg_flags);
1204 count = tswapl(msgp->msg_iovlen);
1205 vec = alloca(count * sizeof(struct iovec));
1206 target_vec = tswapl(msgp->msg_iov);
1207 lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1208 msg.msg_iovlen = count;
1209 msg.msg_iov = vec;
1211 if (send) {
1212 ret = target_to_host_cmsg(&msg, msgp);
1213 if (ret == 0)
1214 ret = get_errno(sendmsg(fd, &msg, flags));
1215 } else {
1216 ret = get_errno(recvmsg(fd, &msg, flags));
1217 if (!is_error(ret)) {
1218 len = ret;
1219 ret = host_to_target_cmsg(msgp, &msg);
1220 if (!is_error(ret))
1221 ret = len;
1224 unlock_iovec(vec, target_vec, count, !send);
1225 unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1226 return ret;
1229 /* do_accept() Must return target values and target errnos. */
1230 static abi_long do_accept(int fd, abi_ulong target_addr,
1231 abi_ulong target_addrlen_addr)
1233 socklen_t addrlen;
1234 void *addr;
1235 abi_long ret;
1237 if (get_user_u32(addrlen, target_addrlen_addr))
1238 return -TARGET_EFAULT;
1240 if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
1241 return -TARGET_EINVAL;
1243 addr = alloca(addrlen);
1245 ret = get_errno(accept(fd, addr, &addrlen));
1246 if (!is_error(ret)) {
1247 host_to_target_sockaddr(target_addr, addr, addrlen);
1248 if (put_user_u32(addrlen, target_addrlen_addr))
1249 ret = -TARGET_EFAULT;
1251 return ret;
1254 /* do_getpeername() Must return target values and target errnos. */
1255 static abi_long do_getpeername(int fd, abi_ulong target_addr,
1256 abi_ulong target_addrlen_addr)
1258 socklen_t addrlen;
1259 void *addr;
1260 abi_long ret;
1262 if (get_user_u32(addrlen, target_addrlen_addr))
1263 return -TARGET_EFAULT;
1265 if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
1266 return -TARGET_EINVAL;
1268 addr = alloca(addrlen);
1270 ret = get_errno(getpeername(fd, addr, &addrlen));
1271 if (!is_error(ret)) {
1272 host_to_target_sockaddr(target_addr, addr, addrlen);
1273 if (put_user_u32(addrlen, target_addrlen_addr))
1274 ret = -TARGET_EFAULT;
1276 return ret;
1279 /* do_getsockname() Must return target values and target errnos. */
1280 static abi_long do_getsockname(int fd, abi_ulong target_addr,
1281 abi_ulong target_addrlen_addr)
1283 socklen_t addrlen;
1284 void *addr;
1285 abi_long ret;
1287 if (target_addr == 0)
1288 return get_errno(accept(fd, NULL, NULL));
1290 if (get_user_u32(addrlen, target_addrlen_addr))
1291 return -TARGET_EFAULT;
1293 if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
1294 return -TARGET_EINVAL;
1296 addr = alloca(addrlen);
1298 ret = get_errno(getsockname(fd, addr, &addrlen));
1299 if (!is_error(ret)) {
1300 host_to_target_sockaddr(target_addr, addr, addrlen);
1301 if (put_user_u32(addrlen, target_addrlen_addr))
1302 ret = -TARGET_EFAULT;
1304 return ret;
1307 /* do_socketpair() Must return target values and target errnos. */
1308 static abi_long do_socketpair(int domain, int type, int protocol,
1309 abi_ulong target_tab_addr)
1311 int tab[2];
1312 abi_long ret;
1314 ret = get_errno(socketpair(domain, type, protocol, tab));
1315 if (!is_error(ret)) {
1316 if (put_user_s32(tab[0], target_tab_addr)
1317 || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1318 ret = -TARGET_EFAULT;
1320 return ret;
1323 /* do_sendto() Must return target values and target errnos. */
1324 static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
1325 abi_ulong target_addr, socklen_t addrlen)
1327 void *addr;
1328 void *host_msg;
1329 abi_long ret;
1331 if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
1332 return -TARGET_EINVAL;
1334 host_msg = lock_user(VERIFY_READ, msg, len, 1);
1335 if (!host_msg)
1336 return -TARGET_EFAULT;
1337 if (target_addr) {
1338 addr = alloca(addrlen);
1339 target_to_host_sockaddr(addr, target_addr, addrlen);
1340 ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
1341 } else {
1342 ret = get_errno(send(fd, host_msg, len, flags));
1344 unlock_user(host_msg, msg, 0);
1345 return ret;
1348 /* do_recvfrom() Must return target values and target errnos. */
1349 static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
1350 abi_ulong target_addr,
1351 abi_ulong target_addrlen)
1353 socklen_t addrlen;
1354 void *addr;
1355 void *host_msg;
1356 abi_long ret;
1358 host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
1359 if (!host_msg)
1360 return -TARGET_EFAULT;
1361 if (target_addr) {
1362 if (get_user_u32(addrlen, target_addrlen)) {
1363 ret = -TARGET_EFAULT;
1364 goto fail;
1366 if (addrlen < 0 || addrlen > MAX_SOCK_ADDR) {
1367 ret = -TARGET_EINVAL;
1368 goto fail;
1370 addr = alloca(addrlen);
1371 ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
1372 } else {
1373 addr = NULL; /* To keep compiler quiet. */
1374 ret = get_errno(recv(fd, host_msg, len, flags));
1376 if (!is_error(ret)) {
1377 if (target_addr) {
1378 host_to_target_sockaddr(target_addr, addr, addrlen);
1379 if (put_user_u32(addrlen, target_addrlen)) {
1380 ret = -TARGET_EFAULT;
1381 goto fail;
1384 unlock_user(host_msg, msg, len);
1385 } else {
1386 fail:
1387 unlock_user(host_msg, msg, 0);
1389 return ret;
1392 #ifdef TARGET_NR_socketcall
1393 /* do_socketcall() Must return target values and target errnos. */
1394 static abi_long do_socketcall(int num, abi_ulong vptr)
1396 abi_long ret;
1397 const int n = sizeof(abi_ulong);
1399 switch(num) {
1400 case SOCKOP_socket:
1402 int domain, type, protocol;
1404 if (get_user_s32(domain, vptr)
1405 || get_user_s32(type, vptr + n)
1406 || get_user_s32(protocol, vptr + 2 * n))
1407 return -TARGET_EFAULT;
1409 ret = do_socket(domain, type, protocol);
1411 break;
1412 case SOCKOP_bind:
1414 int sockfd;
1415 abi_ulong target_addr;
1416 socklen_t addrlen;
1418 if (get_user_s32(sockfd, vptr)
1419 || get_user_ual(target_addr, vptr + n)
1420 || get_user_u32(addrlen, vptr + 2 * n))
1421 return -TARGET_EFAULT;
1423 ret = do_bind(sockfd, target_addr, addrlen);
1425 break;
1426 case SOCKOP_connect:
1428 int sockfd;
1429 abi_ulong target_addr;
1430 socklen_t addrlen;
1432 if (get_user_s32(sockfd, vptr)
1433 || get_user_ual(target_addr, vptr + n)
1434 || get_user_u32(addrlen, vptr + 2 * n))
1435 return -TARGET_EFAULT;
1437 ret = do_connect(sockfd, target_addr, addrlen);
1439 break;
1440 case SOCKOP_listen:
1442 int sockfd, backlog;
1444 if (get_user_s32(sockfd, vptr)
1445 || get_user_s32(backlog, vptr + n))
1446 return -TARGET_EFAULT;
1448 ret = get_errno(listen(sockfd, backlog));
1450 break;
1451 case SOCKOP_accept:
1453 int sockfd;
1454 abi_ulong target_addr, target_addrlen;
1456 if (get_user_s32(sockfd, vptr)
1457 || get_user_ual(target_addr, vptr + n)
1458 || get_user_u32(target_addrlen, vptr + 2 * n))
1459 return -TARGET_EFAULT;
1461 ret = do_accept(sockfd, target_addr, target_addrlen);
1463 break;
1464 case SOCKOP_getsockname:
1466 int sockfd;
1467 abi_ulong target_addr, target_addrlen;
1469 if (get_user_s32(sockfd, vptr)
1470 || get_user_ual(target_addr, vptr + n)
1471 || get_user_u32(target_addrlen, vptr + 2 * n))
1472 return -TARGET_EFAULT;
1474 ret = do_getsockname(sockfd, target_addr, target_addrlen);
1476 break;
1477 case SOCKOP_getpeername:
1479 int sockfd;
1480 abi_ulong target_addr, target_addrlen;
1482 if (get_user_s32(sockfd, vptr)
1483 || get_user_ual(target_addr, vptr + n)
1484 || get_user_u32(target_addrlen, vptr + 2 * n))
1485 return -TARGET_EFAULT;
1487 ret = do_getpeername(sockfd, target_addr, target_addrlen);
1489 break;
1490 case SOCKOP_socketpair:
1492 int domain, type, protocol;
1493 abi_ulong tab;
1495 if (get_user_s32(domain, vptr)
1496 || get_user_s32(type, vptr + n)
1497 || get_user_s32(protocol, vptr + 2 * n)
1498 || get_user_ual(tab, vptr + 3 * n))
1499 return -TARGET_EFAULT;
1501 ret = do_socketpair(domain, type, protocol, tab);
1503 break;
1504 case SOCKOP_send:
1506 int sockfd;
1507 abi_ulong msg;
1508 size_t len;
1509 int flags;
1511 if (get_user_s32(sockfd, vptr)
1512 || get_user_ual(msg, vptr + n)
1513 || get_user_ual(len, vptr + 2 * n)
1514 || get_user_s32(flags, vptr + 3 * n))
1515 return -TARGET_EFAULT;
1517 ret = do_sendto(sockfd, msg, len, flags, 0, 0);
1519 break;
1520 case SOCKOP_recv:
1522 int sockfd;
1523 abi_ulong msg;
1524 size_t len;
1525 int flags;
1527 if (get_user_s32(sockfd, vptr)
1528 || get_user_ual(msg, vptr + n)
1529 || get_user_ual(len, vptr + 2 * n)
1530 || get_user_s32(flags, vptr + 3 * n))
1531 return -TARGET_EFAULT;
1533 ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
1535 break;
1536 case SOCKOP_sendto:
1538 int sockfd;
1539 abi_ulong msg;
1540 size_t len;
1541 int flags;
1542 abi_ulong addr;
1543 socklen_t addrlen;
1545 if (get_user_s32(sockfd, vptr)
1546 || get_user_ual(msg, vptr + n)
1547 || get_user_ual(len, vptr + 2 * n)
1548 || get_user_s32(flags, vptr + 3 * n)
1549 || get_user_ual(addr, vptr + 4 * n)
1550 || get_user_u32(addrlen, vptr + 5 * n))
1551 return -TARGET_EFAULT;
1553 ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
1555 break;
1556 case SOCKOP_recvfrom:
1558 int sockfd;
1559 abi_ulong msg;
1560 size_t len;
1561 int flags;
1562 abi_ulong addr;
1563 socklen_t addrlen;
1565 if (get_user_s32(sockfd, vptr)
1566 || get_user_ual(msg, vptr + n)
1567 || get_user_ual(len, vptr + 2 * n)
1568 || get_user_s32(flags, vptr + 3 * n)
1569 || get_user_ual(addr, vptr + 4 * n)
1570 || get_user_u32(addrlen, vptr + 5 * n))
1571 return -TARGET_EFAULT;
1573 ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
1575 break;
1576 case SOCKOP_shutdown:
1578 int sockfd, how;
1580 if (get_user_s32(sockfd, vptr)
1581 || get_user_s32(how, vptr + n))
1582 return -TARGET_EFAULT;
1584 ret = get_errno(shutdown(sockfd, how));
1586 break;
1587 case SOCKOP_sendmsg:
1588 case SOCKOP_recvmsg:
1590 int fd;
1591 abi_ulong target_msg;
1592 int flags;
1594 if (get_user_s32(fd, vptr)
1595 || get_user_ual(target_msg, vptr + n)
1596 || get_user_s32(flags, vptr + 2 * n))
1597 return -TARGET_EFAULT;
1599 ret = do_sendrecvmsg(fd, target_msg, flags,
1600 (num == SOCKOP_sendmsg));
1602 break;
1603 case SOCKOP_setsockopt:
1605 int sockfd;
1606 int level;
1607 int optname;
1608 abi_ulong optval;
1609 socklen_t optlen;
1611 if (get_user_s32(sockfd, vptr)
1612 || get_user_s32(level, vptr + n)
1613 || get_user_s32(optname, vptr + 2 * n)
1614 || get_user_ual(optval, vptr + 3 * n)
1615 || get_user_u32(optlen, vptr + 4 * n))
1616 return -TARGET_EFAULT;
1618 ret = do_setsockopt(sockfd, level, optname, optval, optlen);
1620 break;
1621 case SOCKOP_getsockopt:
1623 int sockfd;
1624 int level;
1625 int optname;
1626 abi_ulong optval;
1627 socklen_t optlen;
1629 if (get_user_s32(sockfd, vptr)
1630 || get_user_s32(level, vptr + n)
1631 || get_user_s32(optname, vptr + 2 * n)
1632 || get_user_ual(optval, vptr + 3 * n)
1633 || get_user_u32(optlen, vptr + 4 * n))
1634 return -TARGET_EFAULT;
1636 ret = do_getsockopt(sockfd, level, optname, optval, optlen);
1638 break;
1639 default:
1640 gemu_log("Unsupported socketcall: %d\n", num);
1641 ret = -TARGET_ENOSYS;
1642 break;
1644 return ret;
1646 #endif
1648 #ifdef TARGET_NR_ipc
1649 #define N_SHM_REGIONS 32
1651 static struct shm_region {
1652 abi_ulong start;
1653 abi_ulong size;
1654 } shm_regions[N_SHM_REGIONS];
1655 #endif
1657 struct target_ipc_perm
1659 abi_long __key;
1660 abi_ulong uid;
1661 abi_ulong gid;
1662 abi_ulong cuid;
1663 abi_ulong cgid;
1664 unsigned short int mode;
1665 unsigned short int __pad1;
1666 unsigned short int __seq;
1667 unsigned short int __pad2;
1668 abi_ulong __unused1;
1669 abi_ulong __unused2;
1672 struct target_semid_ds
1674 struct target_ipc_perm sem_perm;
1675 abi_ulong sem_otime;
1676 abi_ulong __unused1;
1677 abi_ulong sem_ctime;
1678 abi_ulong __unused2;
1679 abi_ulong sem_nsems;
1680 abi_ulong __unused3;
1681 abi_ulong __unused4;
1684 static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
1685 abi_ulong target_addr)
1687 struct target_ipc_perm *target_ip;
1688 struct target_semid_ds *target_sd;
1690 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
1691 return -TARGET_EFAULT;
1692 target_ip=&(target_sd->sem_perm);
1693 host_ip->__key = tswapl(target_ip->__key);
1694 host_ip->uid = tswapl(target_ip->uid);
1695 host_ip->gid = tswapl(target_ip->gid);
1696 host_ip->cuid = tswapl(target_ip->cuid);
1697 host_ip->cgid = tswapl(target_ip->cgid);
1698 host_ip->mode = tswapl(target_ip->mode);
1699 unlock_user_struct(target_sd, target_addr, 0);
1700 return 0;
1703 static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
1704 struct ipc_perm *host_ip)
1706 struct target_ipc_perm *target_ip;
1707 struct target_semid_ds *target_sd;
1709 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
1710 return -TARGET_EFAULT;
1711 target_ip = &(target_sd->sem_perm);
1712 target_ip->__key = tswapl(host_ip->__key);
1713 target_ip->uid = tswapl(host_ip->uid);
1714 target_ip->gid = tswapl(host_ip->gid);
1715 target_ip->cuid = tswapl(host_ip->cuid);
1716 target_ip->cgid = tswapl(host_ip->cgid);
1717 target_ip->mode = tswapl(host_ip->mode);
1718 unlock_user_struct(target_sd, target_addr, 1);
1719 return 0;
1722 static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
1723 abi_ulong target_addr)
1725 struct target_semid_ds *target_sd;
1727 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
1728 return -TARGET_EFAULT;
1729 target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr);
1730 host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
1731 host_sd->sem_otime = tswapl(target_sd->sem_otime);
1732 host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
1733 unlock_user_struct(target_sd, target_addr, 0);
1734 return 0;
1737 static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
1738 struct semid_ds *host_sd)
1740 struct target_semid_ds *target_sd;
1742 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
1743 return -TARGET_EFAULT;
1744 host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm));
1745 target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
1746 target_sd->sem_otime = tswapl(host_sd->sem_otime);
1747 target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
1748 unlock_user_struct(target_sd, target_addr, 1);
1749 return 0;
1752 union semun {
1753 int val;
1754 struct semid_ds *buf;
1755 unsigned short *array;
1758 union target_semun {
1759 int val;
1760 abi_long buf;
1761 unsigned short int *array;
1764 static inline abi_long target_to_host_semun(int cmd,
1765 union semun *host_su,
1766 abi_ulong target_addr,
1767 struct semid_ds *ds)
1769 union target_semun *target_su;
1771 switch( cmd ) {
1772 case IPC_STAT:
1773 case IPC_SET:
1774 if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1775 return -TARGET_EFAULT;
1776 target_to_host_semid_ds(ds,target_su->buf);
1777 host_su->buf = ds;
1778 unlock_user_struct(target_su, target_addr, 0);
1779 break;
1780 case GETVAL:
1781 case SETVAL:
1782 if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1783 return -TARGET_EFAULT;
1784 host_su->val = tswapl(target_su->val);
1785 unlock_user_struct(target_su, target_addr, 0);
1786 break;
1787 case GETALL:
1788 case SETALL:
1789 if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1790 return -TARGET_EFAULT;
1791 *host_su->array = tswap16(*target_su->array);
1792 unlock_user_struct(target_su, target_addr, 0);
1793 break;
1794 default:
1795 gemu_log("semun operation not fully supported: %d\n", (int)cmd);
1797 return 0;
1800 static inline abi_long host_to_target_semun(int cmd,
1801 abi_ulong target_addr,
1802 union semun *host_su,
1803 struct semid_ds *ds)
1805 union target_semun *target_su;
1807 switch( cmd ) {
1808 case IPC_STAT:
1809 case IPC_SET:
1810 if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1811 return -TARGET_EFAULT;
1812 host_to_target_semid_ds(target_su->buf,ds);
1813 unlock_user_struct(target_su, target_addr, 1);
1814 break;
1815 case GETVAL:
1816 case SETVAL:
1817 if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1818 return -TARGET_EFAULT;
1819 target_su->val = tswapl(host_su->val);
1820 unlock_user_struct(target_su, target_addr, 1);
1821 break;
1822 case GETALL:
1823 case SETALL:
1824 if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1825 return -TARGET_EFAULT;
1826 *target_su->array = tswap16(*host_su->array);
1827 unlock_user_struct(target_su, target_addr, 1);
1828 break;
1829 default:
1830 gemu_log("semun operation not fully supported: %d\n", (int)cmd);
1832 return 0;
1835 static inline abi_long do_semctl(int first, int second, int third,
1836 abi_long ptr)
1838 union semun arg;
1839 struct semid_ds dsarg;
1840 int cmd = third&0xff;
1841 abi_long ret = 0;
1843 switch( cmd ) {
1844 case GETVAL:
1845 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1846 ret = get_errno(semctl(first, second, cmd, arg));
1847 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1848 break;
1849 case SETVAL:
1850 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1851 ret = get_errno(semctl(first, second, cmd, arg));
1852 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1853 break;
1854 case GETALL:
1855 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1856 ret = get_errno(semctl(first, second, cmd, arg));
1857 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1858 break;
1859 case SETALL:
1860 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1861 ret = get_errno(semctl(first, second, cmd, arg));
1862 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1863 break;
1864 case IPC_STAT:
1865 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1866 ret = get_errno(semctl(first, second, cmd, arg));
1867 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1868 break;
1869 case IPC_SET:
1870 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1871 ret = get_errno(semctl(first, second, cmd, arg));
1872 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1873 break;
1874 default:
1875 ret = get_errno(semctl(first, second, cmd, arg));
1878 return ret;
1881 struct target_msqid_ds
1883 struct target_ipc_perm msg_perm;
1884 abi_ulong msg_stime;
1885 #if TARGET_ABI_BITS == 32
1886 abi_ulong __unused1;
1887 #endif
1888 abi_ulong msg_rtime;
1889 #if TARGET_ABI_BITS == 32
1890 abi_ulong __unused2;
1891 #endif
1892 abi_ulong msg_ctime;
1893 #if TARGET_ABI_BITS == 32
1894 abi_ulong __unused3;
1895 #endif
1896 abi_ulong __msg_cbytes;
1897 abi_ulong msg_qnum;
1898 abi_ulong msg_qbytes;
1899 abi_ulong msg_lspid;
1900 abi_ulong msg_lrpid;
1901 abi_ulong __unused4;
1902 abi_ulong __unused5;
1905 static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
1906 abi_ulong target_addr)
1908 struct target_msqid_ds *target_md;
1910 if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
1911 return -TARGET_EFAULT;
1912 if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
1913 return -TARGET_EFAULT;
1914 host_md->msg_stime = tswapl(target_md->msg_stime);
1915 host_md->msg_rtime = tswapl(target_md->msg_rtime);
1916 host_md->msg_ctime = tswapl(target_md->msg_ctime);
1917 host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
1918 host_md->msg_qnum = tswapl(target_md->msg_qnum);
1919 host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
1920 host_md->msg_lspid = tswapl(target_md->msg_lspid);
1921 host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
1922 unlock_user_struct(target_md, target_addr, 0);
1923 return 0;
1926 static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
1927 struct msqid_ds *host_md)
1929 struct target_msqid_ds *target_md;
1931 if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
1932 return -TARGET_EFAULT;
1933 if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
1934 return -TARGET_EFAULT;
1935 target_md->msg_stime = tswapl(host_md->msg_stime);
1936 target_md->msg_rtime = tswapl(host_md->msg_rtime);
1937 target_md->msg_ctime = tswapl(host_md->msg_ctime);
1938 target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
1939 target_md->msg_qnum = tswapl(host_md->msg_qnum);
1940 target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
1941 target_md->msg_lspid = tswapl(host_md->msg_lspid);
1942 target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
1943 unlock_user_struct(target_md, target_addr, 1);
1944 return 0;
1947 struct target_msginfo {
1948 int msgpool;
1949 int msgmap;
1950 int msgmax;
1951 int msgmnb;
1952 int msgmni;
1953 int msgssz;
1954 int msgtql;
1955 unsigned short int msgseg;
1958 static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
1959 struct msginfo *host_msginfo)
1961 struct target_msginfo *target_msginfo;
1962 if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
1963 return -TARGET_EFAULT;
1964 __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
1965 __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
1966 __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
1967 __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
1968 __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
1969 __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
1970 __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
1971 __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
1972 unlock_user_struct(target_msginfo, target_addr, 1);
1973 return 0;
1976 static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
1978 struct msqid_ds dsarg;
1979 struct msginfo msginfo;
1980 abi_long ret = -TARGET_EINVAL;
1982 cmd &= 0xff;
1984 switch (cmd) {
1985 case IPC_STAT:
1986 case IPC_SET:
1987 case MSG_STAT:
1988 if (target_to_host_msqid_ds(&dsarg,ptr))
1989 return -TARGET_EFAULT;
1990 ret = get_errno(msgctl(msgid, cmd, &dsarg));
1991 if (host_to_target_msqid_ds(ptr,&dsarg))
1992 return -TARGET_EFAULT;
1993 break;
1994 case IPC_RMID:
1995 ret = get_errno(msgctl(msgid, cmd, NULL));
1996 break;
1997 case IPC_INFO:
1998 case MSG_INFO:
1999 ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
2000 if (host_to_target_msginfo(ptr, &msginfo))
2001 return -TARGET_EFAULT;
2002 break;
2005 return ret;
2008 struct target_msgbuf {
2009 abi_long mtype;
2010 char mtext[1];
2013 static inline abi_long do_msgsnd(int msqid, abi_long msgp,
2014 unsigned int msgsz, int msgflg)
2016 struct target_msgbuf *target_mb;
2017 struct msgbuf *host_mb;
2018 abi_long ret = 0;
2020 if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
2021 return -TARGET_EFAULT;
2022 host_mb = malloc(msgsz+sizeof(long));
2023 host_mb->mtype = (abi_long) tswapl(target_mb->mtype);
2024 memcpy(host_mb->mtext, target_mb->mtext, msgsz);
2025 ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
2026 free(host_mb);
2027 unlock_user_struct(target_mb, msgp, 0);
2029 return ret;
2032 static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2033 unsigned int msgsz, abi_long msgtyp,
2034 int msgflg)
2036 struct target_msgbuf *target_mb;
2037 char *target_mtext;
2038 struct msgbuf *host_mb;
2039 abi_long ret = 0;
2041 if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2042 return -TARGET_EFAULT;
2044 host_mb = malloc(msgsz+sizeof(long));
2045 ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapl(msgtyp), msgflg));
2047 if (ret > 0) {
2048 abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2049 target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2050 if (!target_mtext) {
2051 ret = -TARGET_EFAULT;
2052 goto end;
2054 memcpy(target_mb->mtext, host_mb->mtext, ret);
2055 unlock_user(target_mtext, target_mtext_addr, ret);
2058 target_mb->mtype = tswapl(host_mb->mtype);
2059 free(host_mb);
2061 end:
2062 if (target_mb)
2063 unlock_user_struct(target_mb, msgp, 1);
2064 return ret;
2067 #ifdef TARGET_NR_ipc
2068 /* ??? This only works with linear mappings. */
2069 /* do_ipc() must return target values and target errnos. */
2070 static abi_long do_ipc(unsigned int call, int first,
2071 int second, int third,
2072 abi_long ptr, abi_long fifth)
2074 int version;
2075 abi_long ret = 0;
2076 struct shmid_ds shm_info;
2077 int i;
2079 version = call >> 16;
2080 call &= 0xffff;
2082 switch (call) {
2083 case IPCOP_semop:
2084 ret = get_errno(semop(first,(struct sembuf *)g2h(ptr), second));
2085 break;
2087 case IPCOP_semget:
2088 ret = get_errno(semget(first, second, third));
2089 break;
2091 case IPCOP_semctl:
2092 ret = do_semctl(first, second, third, ptr);
2093 break;
2095 case IPCOP_semtimedop:
2096 gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2097 ret = -TARGET_ENOSYS;
2098 break;
2100 case IPCOP_msgget:
2101 ret = get_errno(msgget(first, second));
2102 break;
2104 case IPCOP_msgsnd:
2105 ret = do_msgsnd(first, ptr, second, third);
2106 break;
2108 case IPCOP_msgctl:
2109 ret = do_msgctl(first, second, ptr);
2110 break;
2112 case IPCOP_msgrcv:
2113 switch (version) {
2114 case 0:
2116 struct target_ipc_kludge {
2117 abi_long msgp;
2118 abi_long msgtyp;
2119 } *tmp;
2121 if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
2122 ret = -TARGET_EFAULT;
2123 break;
2126 ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
2128 unlock_user_struct(tmp, ptr, 0);
2129 break;
2131 default:
2132 ret = do_msgrcv(first, ptr, second, fifth, third);
2134 break;
2136 case IPCOP_shmat:
2138 abi_ulong raddr;
2139 void *host_addr;
2140 /* SHM_* flags are the same on all linux platforms */
2141 host_addr = shmat(first, (void *)g2h(ptr), second);
2142 if (host_addr == (void *)-1) {
2143 ret = get_errno((long)host_addr);
2144 break;
2146 raddr = h2g((unsigned long)host_addr);
2147 /* find out the length of the shared memory segment */
2149 ret = get_errno(shmctl(first, IPC_STAT, &shm_info));
2150 if (is_error(ret)) {
2151 /* can't get length, bail out */
2152 shmdt(host_addr);
2153 break;
2155 page_set_flags(raddr, raddr + shm_info.shm_segsz,
2156 PAGE_VALID | PAGE_READ |
2157 ((second & SHM_RDONLY)? 0: PAGE_WRITE));
2158 for (i = 0; i < N_SHM_REGIONS; ++i) {
2159 if (shm_regions[i].start == 0) {
2160 shm_regions[i].start = raddr;
2161 shm_regions[i].size = shm_info.shm_segsz;
2162 break;
2165 if (put_user_ual(raddr, third))
2166 return -TARGET_EFAULT;
2167 ret = 0;
2169 break;
2170 case IPCOP_shmdt:
2171 for (i = 0; i < N_SHM_REGIONS; ++i) {
2172 if (shm_regions[i].start == ptr) {
2173 shm_regions[i].start = 0;
2174 page_set_flags(ptr, shm_regions[i].size, 0);
2175 break;
2178 ret = get_errno(shmdt((void *)g2h(ptr)));
2179 break;
2181 case IPCOP_shmget:
2182 /* IPC_* flag values are the same on all linux platforms */
2183 ret = get_errno(shmget(first, second, third));
2184 break;
2186 /* IPC_* and SHM_* command values are the same on all linux platforms */
2187 case IPCOP_shmctl:
2188 switch(second) {
2189 case IPC_RMID:
2190 case SHM_LOCK:
2191 case SHM_UNLOCK:
2192 ret = get_errno(shmctl(first, second, NULL));
2193 break;
2194 default:
2195 goto unimplemented;
2197 break;
2198 default:
2199 unimplemented:
2200 gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2201 ret = -TARGET_ENOSYS;
2202 break;
2204 return ret;
2206 #endif
2208 /* kernel structure types definitions */
2209 #define IFNAMSIZ 16
2211 #define STRUCT(name, list...) STRUCT_ ## name,
2212 #define STRUCT_SPECIAL(name) STRUCT_ ## name,
2213 enum {
2214 #include "syscall_types.h"
2216 #undef STRUCT
2217 #undef STRUCT_SPECIAL
2219 #define STRUCT(name, list...) static const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };
2220 #define STRUCT_SPECIAL(name)
2221 #include "syscall_types.h"
2222 #undef STRUCT
2223 #undef STRUCT_SPECIAL
2225 typedef struct IOCTLEntry {
2226 unsigned int target_cmd;
2227 unsigned int host_cmd;
2228 const char *name;
2229 int access;
2230 const argtype arg_type[5];
2231 } IOCTLEntry;
2233 #define IOC_R 0x0001
2234 #define IOC_W 0x0002
2235 #define IOC_RW (IOC_R | IOC_W)
2237 #define MAX_STRUCT_SIZE 4096
2239 static IOCTLEntry ioctl_entries[] = {
2240 #define IOCTL(cmd, access, types...) \
2241 { TARGET_ ## cmd, cmd, #cmd, access, { types } },
2242 #include "ioctls.h"
2243 { 0, 0, },
2246 /* ??? Implement proper locking for ioctls. */
2247 /* do_ioctl() Must return target values and target errnos. */
2248 static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
2250 const IOCTLEntry *ie;
2251 const argtype *arg_type;
2252 abi_long ret;
2253 uint8_t buf_temp[MAX_STRUCT_SIZE];
2254 int target_size;
2255 void *argptr;
2257 ie = ioctl_entries;
2258 for(;;) {
2259 if (ie->target_cmd == 0) {
2260 gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
2261 return -TARGET_ENOSYS;
2263 if (ie->target_cmd == cmd)
2264 break;
2265 ie++;
2267 arg_type = ie->arg_type;
2268 #if defined(DEBUG)
2269 gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
2270 #endif
2271 switch(arg_type[0]) {
2272 case TYPE_NULL:
2273 /* no argument */
2274 ret = get_errno(ioctl(fd, ie->host_cmd));
2275 break;
2276 case TYPE_PTRVOID:
2277 case TYPE_INT:
2278 /* int argment */
2279 ret = get_errno(ioctl(fd, ie->host_cmd, arg));
2280 break;
2281 case TYPE_PTR:
2282 arg_type++;
2283 target_size = thunk_type_size(arg_type, 0);
2284 switch(ie->access) {
2285 case IOC_R:
2286 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2287 if (!is_error(ret)) {
2288 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2289 if (!argptr)
2290 return -TARGET_EFAULT;
2291 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2292 unlock_user(argptr, arg, target_size);
2294 break;
2295 case IOC_W:
2296 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2297 if (!argptr)
2298 return -TARGET_EFAULT;
2299 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2300 unlock_user(argptr, arg, 0);
2301 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2302 break;
2303 default:
2304 case IOC_RW:
2305 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2306 if (!argptr)
2307 return -TARGET_EFAULT;
2308 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2309 unlock_user(argptr, arg, 0);
2310 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2311 if (!is_error(ret)) {
2312 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2313 if (!argptr)
2314 return -TARGET_EFAULT;
2315 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2316 unlock_user(argptr, arg, target_size);
2318 break;
2320 break;
2321 default:
2322 gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
2323 (long)cmd, arg_type[0]);
2324 ret = -TARGET_ENOSYS;
2325 break;
2327 return ret;
2330 static const bitmask_transtbl iflag_tbl[] = {
2331 { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
2332 { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
2333 { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
2334 { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
2335 { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
2336 { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
2337 { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
2338 { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
2339 { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
2340 { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
2341 { TARGET_IXON, TARGET_IXON, IXON, IXON },
2342 { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
2343 { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
2344 { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
2345 { 0, 0, 0, 0 }
2348 static const bitmask_transtbl oflag_tbl[] = {
2349 { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
2350 { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
2351 { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
2352 { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
2353 { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
2354 { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
2355 { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
2356 { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
2357 { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
2358 { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
2359 { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
2360 { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
2361 { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
2362 { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
2363 { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
2364 { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
2365 { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
2366 { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
2367 { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
2368 { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
2369 { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
2370 { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
2371 { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
2372 { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
2373 { 0, 0, 0, 0 }
2376 static const bitmask_transtbl cflag_tbl[] = {
2377 { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
2378 { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
2379 { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
2380 { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
2381 { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
2382 { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
2383 { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
2384 { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
2385 { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
2386 { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
2387 { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
2388 { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
2389 { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
2390 { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
2391 { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
2392 { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
2393 { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
2394 { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
2395 { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
2396 { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
2397 { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
2398 { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
2399 { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
2400 { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
2401 { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
2402 { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
2403 { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
2404 { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
2405 { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
2406 { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
2407 { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
2408 { 0, 0, 0, 0 }
2411 static const bitmask_transtbl lflag_tbl[] = {
2412 { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
2413 { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
2414 { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
2415 { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
2416 { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
2417 { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
2418 { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
2419 { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
2420 { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
2421 { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
2422 { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
2423 { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
2424 { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
2425 { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
2426 { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
2427 { 0, 0, 0, 0 }
2430 static void target_to_host_termios (void *dst, const void *src)
2432 struct host_termios *host = dst;
2433 const struct target_termios *target = src;
2435 host->c_iflag =
2436 target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
2437 host->c_oflag =
2438 target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
2439 host->c_cflag =
2440 target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
2441 host->c_lflag =
2442 target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
2443 host->c_line = target->c_line;
2445 host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
2446 host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
2447 host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
2448 host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
2449 host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
2450 host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
2451 host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
2452 host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
2453 host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
2454 host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
2455 host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
2456 host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
2457 host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
2458 host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
2459 host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
2460 host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
2461 host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
2464 static void host_to_target_termios (void *dst, const void *src)
2466 struct target_termios *target = dst;
2467 const struct host_termios *host = src;
2469 target->c_iflag =
2470 tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
2471 target->c_oflag =
2472 tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
2473 target->c_cflag =
2474 tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
2475 target->c_lflag =
2476 tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
2477 target->c_line = host->c_line;
2479 target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
2480 target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
2481 target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
2482 target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
2483 target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
2484 target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
2485 target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
2486 target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
2487 target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
2488 target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
2489 target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
2490 target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
2491 target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
2492 target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
2493 target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
2494 target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
2495 target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
2498 static const StructEntry struct_termios_def = {
2499 .convert = { host_to_target_termios, target_to_host_termios },
2500 .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
2501 .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
2504 static bitmask_transtbl mmap_flags_tbl[] = {
2505 { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
2506 { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
2507 { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
2508 { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
2509 { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
2510 { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
2511 { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
2512 { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
2513 { 0, 0, 0, 0 }
2516 static bitmask_transtbl fcntl_flags_tbl[] = {
2517 { TARGET_O_ACCMODE, TARGET_O_WRONLY, O_ACCMODE, O_WRONLY, },
2518 { TARGET_O_ACCMODE, TARGET_O_RDWR, O_ACCMODE, O_RDWR, },
2519 { TARGET_O_CREAT, TARGET_O_CREAT, O_CREAT, O_CREAT, },
2520 { TARGET_O_EXCL, TARGET_O_EXCL, O_EXCL, O_EXCL, },
2521 { TARGET_O_NOCTTY, TARGET_O_NOCTTY, O_NOCTTY, O_NOCTTY, },
2522 { TARGET_O_TRUNC, TARGET_O_TRUNC, O_TRUNC, O_TRUNC, },
2523 { TARGET_O_APPEND, TARGET_O_APPEND, O_APPEND, O_APPEND, },
2524 { TARGET_O_NONBLOCK, TARGET_O_NONBLOCK, O_NONBLOCK, O_NONBLOCK, },
2525 { TARGET_O_SYNC, TARGET_O_SYNC, O_SYNC, O_SYNC, },
2526 { TARGET_FASYNC, TARGET_FASYNC, FASYNC, FASYNC, },
2527 { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
2528 { TARGET_O_NOFOLLOW, TARGET_O_NOFOLLOW, O_NOFOLLOW, O_NOFOLLOW, },
2529 { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
2530 #if defined(O_DIRECT)
2531 { TARGET_O_DIRECT, TARGET_O_DIRECT, O_DIRECT, O_DIRECT, },
2532 #endif
2533 { 0, 0, 0, 0 }
2536 #if defined(TARGET_I386)
2538 /* NOTE: there is really one LDT for all the threads */
2539 static uint8_t *ldt_table;
2541 static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
2543 int size;
2544 void *p;
2546 if (!ldt_table)
2547 return 0;
2548 size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
2549 if (size > bytecount)
2550 size = bytecount;
2551 p = lock_user(VERIFY_WRITE, ptr, size, 0);
2552 if (!p)
2553 return -TARGET_EFAULT;
2554 /* ??? Should this by byteswapped? */
2555 memcpy(p, ldt_table, size);
2556 unlock_user(p, ptr, size);
2557 return size;
2560 /* XXX: add locking support */
2561 static abi_long write_ldt(CPUX86State *env,
2562 abi_ulong ptr, unsigned long bytecount, int oldmode)
2564 struct target_modify_ldt_ldt_s ldt_info;
2565 struct target_modify_ldt_ldt_s *target_ldt_info;
2566 int seg_32bit, contents, read_exec_only, limit_in_pages;
2567 int seg_not_present, useable, lm;
2568 uint32_t *lp, entry_1, entry_2;
2570 if (bytecount != sizeof(ldt_info))
2571 return -TARGET_EINVAL;
2572 if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
2573 return -TARGET_EFAULT;
2574 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2575 ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2576 ldt_info.limit = tswap32(target_ldt_info->limit);
2577 ldt_info.flags = tswap32(target_ldt_info->flags);
2578 unlock_user_struct(target_ldt_info, ptr, 0);
2580 if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
2581 return -TARGET_EINVAL;
2582 seg_32bit = ldt_info.flags & 1;
2583 contents = (ldt_info.flags >> 1) & 3;
2584 read_exec_only = (ldt_info.flags >> 3) & 1;
2585 limit_in_pages = (ldt_info.flags >> 4) & 1;
2586 seg_not_present = (ldt_info.flags >> 5) & 1;
2587 useable = (ldt_info.flags >> 6) & 1;
2588 #ifdef TARGET_ABI32
2589 lm = 0;
2590 #else
2591 lm = (ldt_info.flags >> 7) & 1;
2592 #endif
2593 if (contents == 3) {
2594 if (oldmode)
2595 return -TARGET_EINVAL;
2596 if (seg_not_present == 0)
2597 return -TARGET_EINVAL;
2599 /* allocate the LDT */
2600 if (!ldt_table) {
2601 env->ldt.base = target_mmap(0,
2602 TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
2603 PROT_READ|PROT_WRITE,
2604 MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
2605 if (env->ldt.base == -1)
2606 return -TARGET_ENOMEM;
2607 memset(g2h(env->ldt.base), 0,
2608 TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
2609 env->ldt.limit = 0xffff;
2610 ldt_table = g2h(env->ldt.base);
2613 /* NOTE: same code as Linux kernel */
2614 /* Allow LDTs to be cleared by the user. */
2615 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2616 if (oldmode ||
2617 (contents == 0 &&
2618 read_exec_only == 1 &&
2619 seg_32bit == 0 &&
2620 limit_in_pages == 0 &&
2621 seg_not_present == 1 &&
2622 useable == 0 )) {
2623 entry_1 = 0;
2624 entry_2 = 0;
2625 goto install;
2629 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2630 (ldt_info.limit & 0x0ffff);
2631 entry_2 = (ldt_info.base_addr & 0xff000000) |
2632 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2633 (ldt_info.limit & 0xf0000) |
2634 ((read_exec_only ^ 1) << 9) |
2635 (contents << 10) |
2636 ((seg_not_present ^ 1) << 15) |
2637 (seg_32bit << 22) |
2638 (limit_in_pages << 23) |
2639 (lm << 21) |
2640 0x7000;
2641 if (!oldmode)
2642 entry_2 |= (useable << 20);
2644 /* Install the new entry ... */
2645 install:
2646 lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
2647 lp[0] = tswap32(entry_1);
2648 lp[1] = tswap32(entry_2);
2649 return 0;
2652 /* specific and weird i386 syscalls */
2653 static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
2654 unsigned long bytecount)
2656 abi_long ret;
2658 switch (func) {
2659 case 0:
2660 ret = read_ldt(ptr, bytecount);
2661 break;
2662 case 1:
2663 ret = write_ldt(env, ptr, bytecount, 1);
2664 break;
2665 case 0x11:
2666 ret = write_ldt(env, ptr, bytecount, 0);
2667 break;
2668 default:
2669 ret = -TARGET_ENOSYS;
2670 break;
2672 return ret;
2675 #if defined(TARGET_I386) && defined(TARGET_ABI32)
2676 static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
2678 uint64_t *gdt_table = g2h(env->gdt.base);
2679 struct target_modify_ldt_ldt_s ldt_info;
2680 struct target_modify_ldt_ldt_s *target_ldt_info;
2681 int seg_32bit, contents, read_exec_only, limit_in_pages;
2682 int seg_not_present, useable, lm;
2683 uint32_t *lp, entry_1, entry_2;
2684 int i;
2686 lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
2687 if (!target_ldt_info)
2688 return -TARGET_EFAULT;
2689 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2690 ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2691 ldt_info.limit = tswap32(target_ldt_info->limit);
2692 ldt_info.flags = tswap32(target_ldt_info->flags);
2693 if (ldt_info.entry_number == -1) {
2694 for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
2695 if (gdt_table[i] == 0) {
2696 ldt_info.entry_number = i;
2697 target_ldt_info->entry_number = tswap32(i);
2698 break;
2702 unlock_user_struct(target_ldt_info, ptr, 1);
2704 if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN ||
2705 ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
2706 return -TARGET_EINVAL;
2707 seg_32bit = ldt_info.flags & 1;
2708 contents = (ldt_info.flags >> 1) & 3;
2709 read_exec_only = (ldt_info.flags >> 3) & 1;
2710 limit_in_pages = (ldt_info.flags >> 4) & 1;
2711 seg_not_present = (ldt_info.flags >> 5) & 1;
2712 useable = (ldt_info.flags >> 6) & 1;
2713 #ifdef TARGET_ABI32
2714 lm = 0;
2715 #else
2716 lm = (ldt_info.flags >> 7) & 1;
2717 #endif
2719 if (contents == 3) {
2720 if (seg_not_present == 0)
2721 return -TARGET_EINVAL;
2724 /* NOTE: same code as Linux kernel */
2725 /* Allow LDTs to be cleared by the user. */
2726 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2727 if ((contents == 0 &&
2728 read_exec_only == 1 &&
2729 seg_32bit == 0 &&
2730 limit_in_pages == 0 &&
2731 seg_not_present == 1 &&
2732 useable == 0 )) {
2733 entry_1 = 0;
2734 entry_2 = 0;
2735 goto install;
2739 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2740 (ldt_info.limit & 0x0ffff);
2741 entry_2 = (ldt_info.base_addr & 0xff000000) |
2742 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2743 (ldt_info.limit & 0xf0000) |
2744 ((read_exec_only ^ 1) << 9) |
2745 (contents << 10) |
2746 ((seg_not_present ^ 1) << 15) |
2747 (seg_32bit << 22) |
2748 (limit_in_pages << 23) |
2749 (useable << 20) |
2750 (lm << 21) |
2751 0x7000;
2753 /* Install the new entry ... */
2754 install:
2755 lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
2756 lp[0] = tswap32(entry_1);
2757 lp[1] = tswap32(entry_2);
2758 return 0;
2761 static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
2763 struct target_modify_ldt_ldt_s *target_ldt_info;
2764 uint64_t *gdt_table = g2h(env->gdt.base);
2765 uint32_t base_addr, limit, flags;
2766 int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
2767 int seg_not_present, useable, lm;
2768 uint32_t *lp, entry_1, entry_2;
2770 lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
2771 if (!target_ldt_info)
2772 return -TARGET_EFAULT;
2773 idx = tswap32(target_ldt_info->entry_number);
2774 if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
2775 idx > TARGET_GDT_ENTRY_TLS_MAX) {
2776 unlock_user_struct(target_ldt_info, ptr, 1);
2777 return -TARGET_EINVAL;
2779 lp = (uint32_t *)(gdt_table + idx);
2780 entry_1 = tswap32(lp[0]);
2781 entry_2 = tswap32(lp[1]);
2783 read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
2784 contents = (entry_2 >> 10) & 3;
2785 seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
2786 seg_32bit = (entry_2 >> 22) & 1;
2787 limit_in_pages = (entry_2 >> 23) & 1;
2788 useable = (entry_2 >> 20) & 1;
2789 #ifdef TARGET_ABI32
2790 lm = 0;
2791 #else
2792 lm = (entry_2 >> 21) & 1;
2793 #endif
2794 flags = (seg_32bit << 0) | (contents << 1) |
2795 (read_exec_only << 3) | (limit_in_pages << 4) |
2796 (seg_not_present << 5) | (useable << 6) | (lm << 7);
2797 limit = (entry_1 & 0xffff) | (entry_2 & 0xf0000);
2798 base_addr = (entry_1 >> 16) |
2799 (entry_2 & 0xff000000) |
2800 ((entry_2 & 0xff) << 16);
2801 target_ldt_info->base_addr = tswapl(base_addr);
2802 target_ldt_info->limit = tswap32(limit);
2803 target_ldt_info->flags = tswap32(flags);
2804 unlock_user_struct(target_ldt_info, ptr, 1);
2805 return 0;
2807 #endif /* TARGET_I386 && TARGET_ABI32 */
2809 #ifndef TARGET_ABI32
2810 static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
2812 abi_long ret;
2813 abi_ulong val;
2814 int idx;
2816 switch(code) {
2817 case TARGET_ARCH_SET_GS:
2818 case TARGET_ARCH_SET_FS:
2819 if (code == TARGET_ARCH_SET_GS)
2820 idx = R_GS;
2821 else
2822 idx = R_FS;
2823 cpu_x86_load_seg(env, idx, 0);
2824 env->segs[idx].base = addr;
2825 break;
2826 case TARGET_ARCH_GET_GS:
2827 case TARGET_ARCH_GET_FS:
2828 if (code == TARGET_ARCH_GET_GS)
2829 idx = R_GS;
2830 else
2831 idx = R_FS;
2832 val = env->segs[idx].base;
2833 if (put_user(val, addr, abi_ulong))
2834 return -TARGET_EFAULT;
2835 break;
2836 default:
2837 ret = -TARGET_EINVAL;
2838 break;
2840 return 0;
2842 #endif
2844 #endif /* defined(TARGET_I386) */
2846 #if defined(USE_NPTL)
2848 #define NEW_STACK_SIZE PTHREAD_STACK_MIN
2850 static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
2851 typedef struct {
2852 CPUState *env;
2853 pthread_mutex_t mutex;
2854 pthread_cond_t cond;
2855 pthread_t thread;
2856 uint32_t tid;
2857 abi_ulong child_tidptr;
2858 abi_ulong parent_tidptr;
2859 sigset_t sigmask;
2860 } new_thread_info;
2862 static void *clone_func(void *arg)
2864 new_thread_info *info = arg;
2865 CPUState *env;
2867 env = info->env;
2868 thread_env = env;
2869 info->tid = gettid();
2870 if (info->child_tidptr)
2871 put_user_u32(info->tid, info->child_tidptr);
2872 if (info->parent_tidptr)
2873 put_user_u32(info->tid, info->parent_tidptr);
2874 /* Enable signals. */
2875 sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
2876 /* Signal to the parent that we're ready. */
2877 pthread_mutex_lock(&info->mutex);
2878 pthread_cond_broadcast(&info->cond);
2879 pthread_mutex_unlock(&info->mutex);
2880 /* Wait until the parent has finshed initializing the tls state. */
2881 pthread_mutex_lock(&clone_lock);
2882 pthread_mutex_unlock(&clone_lock);
2883 cpu_loop(env);
2884 /* never exits */
2885 return NULL;
2887 #else
2888 /* this stack is the equivalent of the kernel stack associated with a
2889 thread/process */
2890 #define NEW_STACK_SIZE 8192
2892 static int clone_func(void *arg)
2894 CPUState *env = arg;
2895 cpu_loop(env);
2896 /* never exits */
2897 return 0;
2899 #endif
2901 /* do_fork() Must return host values and target errnos (unlike most
2902 do_*() functions). */
2903 static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
2904 abi_ulong parent_tidptr, target_ulong newtls,
2905 abi_ulong child_tidptr)
2907 int ret;
2908 TaskState *ts;
2909 uint8_t *new_stack;
2910 CPUState *new_env;
2911 #if defined(USE_NPTL)
2912 unsigned int nptl_flags;
2913 sigset_t sigmask;
2914 #endif
2916 /* Emulate vfork() with fork() */
2917 if (flags & CLONE_VFORK)
2918 flags &= ~(CLONE_VFORK | CLONE_VM);
2920 if (flags & CLONE_VM) {
2921 #if defined(USE_NPTL)
2922 new_thread_info info;
2923 pthread_attr_t attr;
2924 #endif
2925 ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
2926 init_task_state(ts);
2927 new_stack = ts->stack;
2928 /* we create a new CPU instance. */
2929 new_env = cpu_copy(env);
2930 /* Init regs that differ from the parent. */
2931 cpu_clone_regs(new_env, newsp);
2932 new_env->opaque = ts;
2933 #if defined(USE_NPTL)
2934 nptl_flags = flags;
2935 flags &= ~CLONE_NPTL_FLAGS2;
2937 if (nptl_flags & CLONE_CHILD_CLEARTID) {
2938 ts->child_tidptr = child_tidptr;
2941 if (nptl_flags & CLONE_SETTLS)
2942 cpu_set_tls (new_env, newtls);
2944 /* Grab a mutex so that thread setup appears atomic. */
2945 pthread_mutex_lock(&clone_lock);
2947 memset(&info, 0, sizeof(info));
2948 pthread_mutex_init(&info.mutex, NULL);
2949 pthread_mutex_lock(&info.mutex);
2950 pthread_cond_init(&info.cond, NULL);
2951 info.env = new_env;
2952 if (nptl_flags & CLONE_CHILD_SETTID)
2953 info.child_tidptr = child_tidptr;
2954 if (nptl_flags & CLONE_PARENT_SETTID)
2955 info.parent_tidptr = parent_tidptr;
2957 ret = pthread_attr_init(&attr);
2958 ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE);
2959 /* It is not safe to deliver signals until the child has finished
2960 initializing, so temporarily block all signals. */
2961 sigfillset(&sigmask);
2962 sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
2964 ret = pthread_create(&info.thread, &attr, clone_func, &info);
2965 /* TODO: Free new CPU state if thread creation failed. */
2967 sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
2968 pthread_attr_destroy(&attr);
2969 if (ret == 0) {
2970 /* Wait for the child to initialize. */
2971 pthread_cond_wait(&info.cond, &info.mutex);
2972 ret = info.tid;
2973 if (flags & CLONE_PARENT_SETTID)
2974 put_user_u32(ret, parent_tidptr);
2975 } else {
2976 ret = -1;
2978 pthread_mutex_unlock(&info.mutex);
2979 pthread_cond_destroy(&info.cond);
2980 pthread_mutex_destroy(&info.mutex);
2981 pthread_mutex_unlock(&clone_lock);
2982 #else
2983 if (flags & CLONE_NPTL_FLAGS2)
2984 return -EINVAL;
2985 /* This is probably going to die very quickly, but do it anyway. */
2986 #ifdef __ia64__
2987 ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
2988 #else
2989 ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
2990 #endif
2991 #endif
2992 } else {
2993 /* if no CLONE_VM, we consider it is a fork */
2994 if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
2995 return -EINVAL;
2996 fork_start();
2997 ret = fork();
2998 if (ret == 0) {
2999 /* Child Process. */
3000 cpu_clone_regs(env, newsp);
3001 fork_end(1);
3002 #if defined(USE_NPTL)
3003 /* There is a race condition here. The parent process could
3004 theoretically read the TID in the child process before the child
3005 tid is set. This would require using either ptrace
3006 (not implemented) or having *_tidptr to point at a shared memory
3007 mapping. We can't repeat the spinlock hack used above because
3008 the child process gets its own copy of the lock. */
3009 if (flags & CLONE_CHILD_SETTID)
3010 put_user_u32(gettid(), child_tidptr);
3011 if (flags & CLONE_PARENT_SETTID)
3012 put_user_u32(gettid(), parent_tidptr);
3013 ts = (TaskState *)env->opaque;
3014 if (flags & CLONE_SETTLS)
3015 cpu_set_tls (env, newtls);
3016 if (flags & CLONE_CHILD_CLEARTID)
3017 ts->child_tidptr = child_tidptr;
3018 #endif
3019 } else {
3020 fork_end(0);
3023 return ret;
3026 static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
3028 struct flock fl;
3029 struct target_flock *target_fl;
3030 struct flock64 fl64;
3031 struct target_flock64 *target_fl64;
3032 abi_long ret;
3034 switch(cmd) {
3035 case TARGET_F_GETLK:
3036 if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3037 return -TARGET_EFAULT;
3038 fl.l_type = tswap16(target_fl->l_type);
3039 fl.l_whence = tswap16(target_fl->l_whence);
3040 fl.l_start = tswapl(target_fl->l_start);
3041 fl.l_len = tswapl(target_fl->l_len);
3042 fl.l_pid = tswapl(target_fl->l_pid);
3043 unlock_user_struct(target_fl, arg, 0);
3044 ret = get_errno(fcntl(fd, cmd, &fl));
3045 if (ret == 0) {
3046 if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
3047 return -TARGET_EFAULT;
3048 target_fl->l_type = tswap16(fl.l_type);
3049 target_fl->l_whence = tswap16(fl.l_whence);
3050 target_fl->l_start = tswapl(fl.l_start);
3051 target_fl->l_len = tswapl(fl.l_len);
3052 target_fl->l_pid = tswapl(fl.l_pid);
3053 unlock_user_struct(target_fl, arg, 1);
3055 break;
3057 case TARGET_F_SETLK:
3058 case TARGET_F_SETLKW:
3059 if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3060 return -TARGET_EFAULT;
3061 fl.l_type = tswap16(target_fl->l_type);
3062 fl.l_whence = tswap16(target_fl->l_whence);
3063 fl.l_start = tswapl(target_fl->l_start);
3064 fl.l_len = tswapl(target_fl->l_len);
3065 fl.l_pid = tswapl(target_fl->l_pid);
3066 unlock_user_struct(target_fl, arg, 0);
3067 ret = get_errno(fcntl(fd, cmd, &fl));
3068 break;
3070 case TARGET_F_GETLK64:
3071 if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3072 return -TARGET_EFAULT;
3073 fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3074 fl64.l_whence = tswap16(target_fl64->l_whence);
3075 fl64.l_start = tswapl(target_fl64->l_start);
3076 fl64.l_len = tswapl(target_fl64->l_len);
3077 fl64.l_pid = tswap16(target_fl64->l_pid);
3078 unlock_user_struct(target_fl64, arg, 0);
3079 ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
3080 if (ret == 0) {
3081 if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
3082 return -TARGET_EFAULT;
3083 target_fl64->l_type = tswap16(fl64.l_type) >> 1;
3084 target_fl64->l_whence = tswap16(fl64.l_whence);
3085 target_fl64->l_start = tswapl(fl64.l_start);
3086 target_fl64->l_len = tswapl(fl64.l_len);
3087 target_fl64->l_pid = tswapl(fl64.l_pid);
3088 unlock_user_struct(target_fl64, arg, 1);
3090 break;
3091 case TARGET_F_SETLK64:
3092 case TARGET_F_SETLKW64:
3093 if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3094 return -TARGET_EFAULT;
3095 fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3096 fl64.l_whence = tswap16(target_fl64->l_whence);
3097 fl64.l_start = tswapl(target_fl64->l_start);
3098 fl64.l_len = tswapl(target_fl64->l_len);
3099 fl64.l_pid = tswap16(target_fl64->l_pid);
3100 unlock_user_struct(target_fl64, arg, 0);
3101 ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
3102 break;
3104 case F_GETFL:
3105 ret = get_errno(fcntl(fd, cmd, arg));
3106 if (ret >= 0) {
3107 ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
3109 break;
3111 case F_SETFL:
3112 ret = get_errno(fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
3113 break;
3115 default:
3116 ret = get_errno(fcntl(fd, cmd, arg));
3117 break;
3119 return ret;
3122 #ifdef USE_UID16
3124 static inline int high2lowuid(int uid)
3126 if (uid > 65535)
3127 return 65534;
3128 else
3129 return uid;
3132 static inline int high2lowgid(int gid)
3134 if (gid > 65535)
3135 return 65534;
3136 else
3137 return gid;
3140 static inline int low2highuid(int uid)
3142 if ((int16_t)uid == -1)
3143 return -1;
3144 else
3145 return uid;
3148 static inline int low2highgid(int gid)
3150 if ((int16_t)gid == -1)
3151 return -1;
3152 else
3153 return gid;
3156 #endif /* USE_UID16 */
3158 void syscall_init(void)
3160 IOCTLEntry *ie;
3161 const argtype *arg_type;
3162 int size;
3163 int i;
3165 #define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3166 #define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3167 #include "syscall_types.h"
3168 #undef STRUCT
3169 #undef STRUCT_SPECIAL
3171 /* we patch the ioctl size if necessary. We rely on the fact that
3172 no ioctl has all the bits at '1' in the size field */
3173 ie = ioctl_entries;
3174 while (ie->target_cmd != 0) {
3175 if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
3176 TARGET_IOC_SIZEMASK) {
3177 arg_type = ie->arg_type;
3178 if (arg_type[0] != TYPE_PTR) {
3179 fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
3180 ie->target_cmd);
3181 exit(1);
3183 arg_type++;
3184 size = thunk_type_size(arg_type, 0);
3185 ie->target_cmd = (ie->target_cmd &
3186 ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
3187 (size << TARGET_IOC_SIZESHIFT);
3190 /* Build target_to_host_errno_table[] table from
3191 * host_to_target_errno_table[]. */
3192 for (i=0; i < ERRNO_TABLE_SIZE; i++)
3193 target_to_host_errno_table[host_to_target_errno_table[i]] = i;
3195 /* automatic consistency check if same arch */
3196 #if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
3197 (defined(__x86_64__) && defined(TARGET_X86_64))
3198 if (unlikely(ie->target_cmd != ie->host_cmd)) {
3199 fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
3200 ie->name, ie->target_cmd, ie->host_cmd);
3202 #endif
3203 ie++;
3207 #if TARGET_ABI_BITS == 32
3208 static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
3210 #ifdef TARGET_WORDS_BIGENDIAN
3211 return ((uint64_t)word0 << 32) | word1;
3212 #else
3213 return ((uint64_t)word1 << 32) | word0;
3214 #endif
3216 #else /* TARGET_ABI_BITS == 32 */
3217 static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
3219 return word0;
3221 #endif /* TARGET_ABI_BITS != 32 */
3223 #ifdef TARGET_NR_truncate64
3224 static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
3225 abi_long arg2,
3226 abi_long arg3,
3227 abi_long arg4)
3229 #ifdef TARGET_ARM
3230 if (((CPUARMState *)cpu_env)->eabi)
3232 arg2 = arg3;
3233 arg3 = arg4;
3235 #endif
3236 return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
3238 #endif
3240 #ifdef TARGET_NR_ftruncate64
3241 static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
3242 abi_long arg2,
3243 abi_long arg3,
3244 abi_long arg4)
3246 #ifdef TARGET_ARM
3247 if (((CPUARMState *)cpu_env)->eabi)
3249 arg2 = arg3;
3250 arg3 = arg4;
3252 #endif
3253 return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
3255 #endif
3257 static inline abi_long target_to_host_timespec(struct timespec *host_ts,
3258 abi_ulong target_addr)
3260 struct target_timespec *target_ts;
3262 if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
3263 return -TARGET_EFAULT;
3264 host_ts->tv_sec = tswapl(target_ts->tv_sec);
3265 host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
3266 unlock_user_struct(target_ts, target_addr, 0);
3267 return 0;
3270 static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3271 struct timespec *host_ts)
3273 struct target_timespec *target_ts;
3275 if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
3276 return -TARGET_EFAULT;
3277 target_ts->tv_sec = tswapl(host_ts->tv_sec);
3278 target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
3279 unlock_user_struct(target_ts, target_addr, 1);
3280 return 0;
3283 #ifdef TARGET_NR_stat64
3284 static inline abi_long host_to_target_stat64(void *cpu_env,
3285 abi_ulong target_addr,
3286 struct stat *host_st)
3288 #ifdef TARGET_ARM
3289 if (((CPUARMState *)cpu_env)->eabi) {
3290 struct target_eabi_stat64 *target_st;
3292 if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3293 return -TARGET_EFAULT;
3294 memset(target_st, 0, sizeof(struct target_eabi_stat64));
3295 __put_user(host_st->st_dev, &target_st->st_dev);
3296 __put_user(host_st->st_ino, &target_st->st_ino);
3297 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3298 __put_user(host_st->st_ino, &target_st->__st_ino);
3299 #endif
3300 __put_user(host_st->st_mode, &target_st->st_mode);
3301 __put_user(host_st->st_nlink, &target_st->st_nlink);
3302 __put_user(host_st->st_uid, &target_st->st_uid);
3303 __put_user(host_st->st_gid, &target_st->st_gid);
3304 __put_user(host_st->st_rdev, &target_st->st_rdev);
3305 __put_user(host_st->st_size, &target_st->st_size);
3306 __put_user(host_st->st_blksize, &target_st->st_blksize);
3307 __put_user(host_st->st_blocks, &target_st->st_blocks);
3308 __put_user(host_st->st_atime, &target_st->target_st_atime);
3309 __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3310 __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3311 unlock_user_struct(target_st, target_addr, 1);
3312 } else
3313 #endif
3315 struct target_stat64 *target_st;
3317 if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3318 return -TARGET_EFAULT;
3319 memset(target_st, 0, sizeof(struct target_stat64));
3320 __put_user(host_st->st_dev, &target_st->st_dev);
3321 __put_user(host_st->st_ino, &target_st->st_ino);
3322 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3323 __put_user(host_st->st_ino, &target_st->__st_ino);
3324 #endif
3325 __put_user(host_st->st_mode, &target_st->st_mode);
3326 __put_user(host_st->st_nlink, &target_st->st_nlink);
3327 __put_user(host_st->st_uid, &target_st->st_uid);
3328 __put_user(host_st->st_gid, &target_st->st_gid);
3329 __put_user(host_st->st_rdev, &target_st->st_rdev);
3330 /* XXX: better use of kernel struct */
3331 __put_user(host_st->st_size, &target_st->st_size);
3332 __put_user(host_st->st_blksize, &target_st->st_blksize);
3333 __put_user(host_st->st_blocks, &target_st->st_blocks);
3334 __put_user(host_st->st_atime, &target_st->target_st_atime);
3335 __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3336 __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3337 unlock_user_struct(target_st, target_addr, 1);
3340 return 0;
3342 #endif
3344 #if defined(USE_NPTL)
3345 /* ??? Using host futex calls even when target atomic operations
3346 are not really atomic probably breaks things. However implementing
3347 futexes locally would make futexes shared between multiple processes
3348 tricky. However they're probably useless because guest atomic
3349 operations won't work either. */
3350 static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
3351 target_ulong uaddr2, int val3)
3353 struct timespec ts, *pts;
3355 /* ??? We assume FUTEX_* constants are the same on both host
3356 and target. */
3357 switch (op) {
3358 case FUTEX_WAIT:
3359 if (timeout) {
3360 pts = &ts;
3361 target_to_host_timespec(pts, timeout);
3362 } else {
3363 pts = NULL;
3365 return get_errno(sys_futex(g2h(uaddr), FUTEX_WAIT, tswap32(val),
3366 pts, NULL, 0));
3367 case FUTEX_WAKE:
3368 return get_errno(sys_futex(g2h(uaddr), FUTEX_WAKE, val, NULL, NULL, 0));
3369 case FUTEX_FD:
3370 return get_errno(sys_futex(g2h(uaddr), FUTEX_FD, val, NULL, NULL, 0));
3371 case FUTEX_REQUEUE:
3372 return get_errno(sys_futex(g2h(uaddr), FUTEX_REQUEUE, val,
3373 NULL, g2h(uaddr2), 0));
3374 case FUTEX_CMP_REQUEUE:
3375 return get_errno(sys_futex(g2h(uaddr), FUTEX_CMP_REQUEUE, val,
3376 NULL, g2h(uaddr2), tswap32(val3)));
3377 default:
3378 return -TARGET_ENOSYS;
3381 #endif
3383 int get_osversion(void)
3385 static int osversion;
3386 struct new_utsname buf;
3387 const char *s;
3388 int i, n, tmp;
3389 if (osversion)
3390 return osversion;
3391 if (qemu_uname_release && *qemu_uname_release) {
3392 s = qemu_uname_release;
3393 } else {
3394 if (sys_uname(&buf))
3395 return 0;
3396 s = buf.release;
3398 tmp = 0;
3399 for (i = 0; i < 3; i++) {
3400 n = 0;
3401 while (*s >= '0' && *s <= '9') {
3402 n *= 10;
3403 n += *s - '0';
3404 s++;
3406 tmp = (tmp << 8) + n;
3407 if (*s == '.')
3408 s++;
3410 osversion = tmp;
3411 return osversion;
3414 /* do_syscall() should always have a single exit point at the end so
3415 that actions, such as logging of syscall results, can be performed.
3416 All errnos that do_syscall() returns must be -TARGET_<errcode>. */
3417 abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3418 abi_long arg2, abi_long arg3, abi_long arg4,
3419 abi_long arg5, abi_long arg6)
3421 abi_long ret;
3422 struct stat st;
3423 struct statfs stfs;
3424 void *p;
3426 #ifdef DEBUG
3427 gemu_log("syscall %d", num);
3428 #endif
3429 if(do_strace)
3430 print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
3432 switch(num) {
3433 case TARGET_NR_exit:
3434 #ifdef USE_NPTL
3435 /* In old applications this may be used to implement _exit(2).
3436 However in threaded applictions it is used for thread termination,
3437 and _exit_group is used for application termination.
3438 Do thread termination if we have more then one thread. */
3439 /* FIXME: This probably breaks if a signal arrives. We should probably
3440 be disabling signals. */
3441 if (first_cpu->next_cpu) {
3442 CPUState **lastp;
3443 CPUState *p;
3445 cpu_list_lock();
3446 lastp = &first_cpu;
3447 p = first_cpu;
3448 while (p && p != (CPUState *)cpu_env) {
3449 lastp = &p->next_cpu;
3450 p = p->next_cpu;
3452 /* If we didn't find the CPU for this thread then something is
3453 horribly wrong. */
3454 if (!p)
3455 abort();
3456 /* Remove the CPU from the list. */
3457 *lastp = p->next_cpu;
3458 cpu_list_unlock();
3459 TaskState *ts = ((CPUState *)cpu_env)->opaque;
3460 if (ts->child_tidptr) {
3461 put_user_u32(0, ts->child_tidptr);
3462 sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
3463 NULL, NULL, 0);
3465 /* TODO: Free CPU state. */
3466 pthread_exit(NULL);
3468 #endif
3469 #ifdef HAVE_GPROF
3470 _mcleanup();
3471 #endif
3472 gdb_exit(cpu_env, arg1);
3473 _exit(arg1);
3474 ret = 0; /* avoid warning */
3475 break;
3476 case TARGET_NR_read:
3477 if (arg3 == 0)
3478 ret = 0;
3479 else {
3480 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
3481 goto efault;
3482 ret = get_errno(read(arg1, p, arg3));
3483 unlock_user(p, arg2, ret);
3485 break;
3486 case TARGET_NR_write:
3487 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
3488 goto efault;
3489 ret = get_errno(write(arg1, p, arg3));
3490 unlock_user(p, arg2, 0);
3491 break;
3492 case TARGET_NR_open:
3493 if (!(p = lock_user_string(arg1)))
3494 goto efault;
3495 ret = get_errno(open(path(p),
3496 target_to_host_bitmask(arg2, fcntl_flags_tbl),
3497 arg3));
3498 unlock_user(p, arg1, 0);
3499 break;
3500 #if defined(TARGET_NR_openat) && defined(__NR_openat)
3501 case TARGET_NR_openat:
3502 if (!(p = lock_user_string(arg2)))
3503 goto efault;
3504 ret = get_errno(sys_openat(arg1,
3505 path(p),
3506 target_to_host_bitmask(arg3, fcntl_flags_tbl),
3507 arg4));
3508 unlock_user(p, arg2, 0);
3509 break;
3510 #endif
3511 case TARGET_NR_close:
3512 ret = get_errno(close(arg1));
3513 break;
3514 case TARGET_NR_brk:
3515 ret = do_brk(arg1);
3516 break;
3517 case TARGET_NR_fork:
3518 ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
3519 break;
3520 #ifdef TARGET_NR_waitpid
3521 case TARGET_NR_waitpid:
3523 int status;
3524 ret = get_errno(waitpid(arg1, &status, arg3));
3525 if (!is_error(ret) && arg2
3526 && put_user_s32(status, arg2))
3527 goto efault;
3529 break;
3530 #endif
3531 #ifdef TARGET_NR_waitid
3532 case TARGET_NR_waitid:
3534 siginfo_t info;
3535 info.si_pid = 0;
3536 ret = get_errno(waitid(arg1, arg2, &info, arg4));
3537 if (!is_error(ret) && arg3 && info.si_pid != 0) {
3538 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
3539 goto efault;
3540 host_to_target_siginfo(p, &info);
3541 unlock_user(p, arg3, sizeof(target_siginfo_t));
3544 break;
3545 #endif
3546 #ifdef TARGET_NR_creat /* not on alpha */
3547 case TARGET_NR_creat:
3548 if (!(p = lock_user_string(arg1)))
3549 goto efault;
3550 ret = get_errno(creat(p, arg2));
3551 unlock_user(p, arg1, 0);
3552 break;
3553 #endif
3554 case TARGET_NR_link:
3556 void * p2;
3557 p = lock_user_string(arg1);
3558 p2 = lock_user_string(arg2);
3559 if (!p || !p2)
3560 ret = -TARGET_EFAULT;
3561 else
3562 ret = get_errno(link(p, p2));
3563 unlock_user(p2, arg2, 0);
3564 unlock_user(p, arg1, 0);
3566 break;
3567 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
3568 case TARGET_NR_linkat:
3570 void * p2 = NULL;
3571 if (!arg2 || !arg4)
3572 goto efault;
3573 p = lock_user_string(arg2);
3574 p2 = lock_user_string(arg4);
3575 if (!p || !p2)
3576 ret = -TARGET_EFAULT;
3577 else
3578 ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
3579 unlock_user(p, arg2, 0);
3580 unlock_user(p2, arg4, 0);
3582 break;
3583 #endif
3584 case TARGET_NR_unlink:
3585 if (!(p = lock_user_string(arg1)))
3586 goto efault;
3587 ret = get_errno(unlink(p));
3588 unlock_user(p, arg1, 0);
3589 break;
3590 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
3591 case TARGET_NR_unlinkat:
3592 if (!(p = lock_user_string(arg2)))
3593 goto efault;
3594 ret = get_errno(sys_unlinkat(arg1, p, arg3));
3595 unlock_user(p, arg2, 0);
3596 break;
3597 #endif
3598 case TARGET_NR_execve:
3600 char **argp, **envp;
3601 int argc, envc;
3602 abi_ulong gp;
3603 abi_ulong guest_argp;
3604 abi_ulong guest_envp;
3605 abi_ulong addr;
3606 char **q;
3608 argc = 0;
3609 guest_argp = arg2;
3610 for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
3611 if (get_user_ual(addr, gp))
3612 goto efault;
3613 if (!addr)
3614 break;
3615 argc++;
3617 envc = 0;
3618 guest_envp = arg3;
3619 for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
3620 if (get_user_ual(addr, gp))
3621 goto efault;
3622 if (!addr)
3623 break;
3624 envc++;
3627 argp = alloca((argc + 1) * sizeof(void *));
3628 envp = alloca((envc + 1) * sizeof(void *));
3630 for (gp = guest_argp, q = argp; gp;
3631 gp += sizeof(abi_ulong), q++) {
3632 if (get_user_ual(addr, gp))
3633 goto execve_efault;
3634 if (!addr)
3635 break;
3636 if (!(*q = lock_user_string(addr)))
3637 goto execve_efault;
3639 *q = NULL;
3641 for (gp = guest_envp, q = envp; 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 if (!(p = lock_user_string(arg1)))
3653 goto execve_efault;
3654 ret = get_errno(execve(p, argp, envp));
3655 unlock_user(p, arg1, 0);
3657 goto execve_end;
3659 execve_efault:
3660 ret = -TARGET_EFAULT;
3662 execve_end:
3663 for (gp = guest_argp, q = argp; *q;
3664 gp += sizeof(abi_ulong), q++) {
3665 if (get_user_ual(addr, gp)
3666 || !addr)
3667 break;
3668 unlock_user(*q, addr, 0);
3670 for (gp = guest_envp, q = envp; *q;
3671 gp += sizeof(abi_ulong), q++) {
3672 if (get_user_ual(addr, gp)
3673 || !addr)
3674 break;
3675 unlock_user(*q, addr, 0);
3678 break;
3679 case TARGET_NR_chdir:
3680 if (!(p = lock_user_string(arg1)))
3681 goto efault;
3682 ret = get_errno(chdir(p));
3683 unlock_user(p, arg1, 0);
3684 break;
3685 #ifdef TARGET_NR_time
3686 case TARGET_NR_time:
3688 time_t host_time;
3689 ret = get_errno(time(&host_time));
3690 if (!is_error(ret)
3691 && arg1
3692 && put_user_sal(host_time, arg1))
3693 goto efault;
3695 break;
3696 #endif
3697 case TARGET_NR_mknod:
3698 if (!(p = lock_user_string(arg1)))
3699 goto efault;
3700 ret = get_errno(mknod(p, arg2, arg3));
3701 unlock_user(p, arg1, 0);
3702 break;
3703 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
3704 case TARGET_NR_mknodat:
3705 if (!(p = lock_user_string(arg2)))
3706 goto efault;
3707 ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
3708 unlock_user(p, arg2, 0);
3709 break;
3710 #endif
3711 case TARGET_NR_chmod:
3712 if (!(p = lock_user_string(arg1)))
3713 goto efault;
3714 ret = get_errno(chmod(p, arg2));
3715 unlock_user(p, arg1, 0);
3716 break;
3717 #ifdef TARGET_NR_break
3718 case TARGET_NR_break:
3719 goto unimplemented;
3720 #endif
3721 #ifdef TARGET_NR_oldstat
3722 case TARGET_NR_oldstat:
3723 goto unimplemented;
3724 #endif
3725 case TARGET_NR_lseek:
3726 ret = get_errno(lseek(arg1, arg2, arg3));
3727 break;
3728 #ifdef TARGET_NR_getxpid
3729 case TARGET_NR_getxpid:
3730 #else
3731 case TARGET_NR_getpid:
3732 #endif
3733 ret = get_errno(getpid());
3734 break;
3735 case TARGET_NR_mount:
3737 /* need to look at the data field */
3738 void *p2, *p3;
3739 p = lock_user_string(arg1);
3740 p2 = lock_user_string(arg2);
3741 p3 = lock_user_string(arg3);
3742 if (!p || !p2 || !p3)
3743 ret = -TARGET_EFAULT;
3744 else
3745 /* FIXME - arg5 should be locked, but it isn't clear how to
3746 * do that since it's not guaranteed to be a NULL-terminated
3747 * string.
3749 ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
3750 unlock_user(p, arg1, 0);
3751 unlock_user(p2, arg2, 0);
3752 unlock_user(p3, arg3, 0);
3753 break;
3755 #ifdef TARGET_NR_umount
3756 case TARGET_NR_umount:
3757 if (!(p = lock_user_string(arg1)))
3758 goto efault;
3759 ret = get_errno(umount(p));
3760 unlock_user(p, arg1, 0);
3761 break;
3762 #endif
3763 #ifdef TARGET_NR_stime /* not on alpha */
3764 case TARGET_NR_stime:
3766 time_t host_time;
3767 if (get_user_sal(host_time, arg1))
3768 goto efault;
3769 ret = get_errno(stime(&host_time));
3771 break;
3772 #endif
3773 case TARGET_NR_ptrace:
3774 goto unimplemented;
3775 #ifdef TARGET_NR_alarm /* not on alpha */
3776 case TARGET_NR_alarm:
3777 ret = alarm(arg1);
3778 break;
3779 #endif
3780 #ifdef TARGET_NR_oldfstat
3781 case TARGET_NR_oldfstat:
3782 goto unimplemented;
3783 #endif
3784 #ifdef TARGET_NR_pause /* not on alpha */
3785 case TARGET_NR_pause:
3786 ret = get_errno(pause());
3787 break;
3788 #endif
3789 #ifdef TARGET_NR_utime
3790 case TARGET_NR_utime:
3792 struct utimbuf tbuf, *host_tbuf;
3793 struct target_utimbuf *target_tbuf;
3794 if (arg2) {
3795 if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
3796 goto efault;
3797 tbuf.actime = tswapl(target_tbuf->actime);
3798 tbuf.modtime = tswapl(target_tbuf->modtime);
3799 unlock_user_struct(target_tbuf, arg2, 0);
3800 host_tbuf = &tbuf;
3801 } else {
3802 host_tbuf = NULL;
3804 if (!(p = lock_user_string(arg1)))
3805 goto efault;
3806 ret = get_errno(utime(p, host_tbuf));
3807 unlock_user(p, arg1, 0);
3809 break;
3810 #endif
3811 case TARGET_NR_utimes:
3813 struct timeval *tvp, tv[2];
3814 if (arg2) {
3815 if (copy_from_user_timeval(&tv[0], arg2)
3816 || copy_from_user_timeval(&tv[1],
3817 arg2 + sizeof(struct target_timeval)))
3818 goto efault;
3819 tvp = tv;
3820 } else {
3821 tvp = NULL;
3823 if (!(p = lock_user_string(arg1)))
3824 goto efault;
3825 ret = get_errno(utimes(p, tvp));
3826 unlock_user(p, arg1, 0);
3828 break;
3829 #if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
3830 case TARGET_NR_futimesat:
3832 struct timeval *tvp, tv[2];
3833 if (arg3) {
3834 if (copy_from_user_timeval(&tv[0], arg3)
3835 || copy_from_user_timeval(&tv[1],
3836 arg3 + sizeof(struct target_timeval)))
3837 goto efault;
3838 tvp = tv;
3839 } else {
3840 tvp = NULL;
3842 if (!(p = lock_user_string(arg2)))
3843 goto efault;
3844 ret = get_errno(sys_futimesat(arg1, path(p), tvp));
3845 unlock_user(p, arg2, 0);
3847 break;
3848 #endif
3849 #ifdef TARGET_NR_stty
3850 case TARGET_NR_stty:
3851 goto unimplemented;
3852 #endif
3853 #ifdef TARGET_NR_gtty
3854 case TARGET_NR_gtty:
3855 goto unimplemented;
3856 #endif
3857 case TARGET_NR_access:
3858 if (!(p = lock_user_string(arg1)))
3859 goto efault;
3860 ret = get_errno(access(p, arg2));
3861 unlock_user(p, arg1, 0);
3862 break;
3863 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
3864 case TARGET_NR_faccessat:
3865 if (!(p = lock_user_string(arg2)))
3866 goto efault;
3867 ret = get_errno(sys_faccessat(arg1, p, arg3, arg4));
3868 unlock_user(p, arg2, 0);
3869 break;
3870 #endif
3871 #ifdef TARGET_NR_nice /* not on alpha */
3872 case TARGET_NR_nice:
3873 ret = get_errno(nice(arg1));
3874 break;
3875 #endif
3876 #ifdef TARGET_NR_ftime
3877 case TARGET_NR_ftime:
3878 goto unimplemented;
3879 #endif
3880 case TARGET_NR_sync:
3881 sync();
3882 ret = 0;
3883 break;
3884 case TARGET_NR_kill:
3885 ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
3886 break;
3887 case TARGET_NR_rename:
3889 void *p2;
3890 p = lock_user_string(arg1);
3891 p2 = lock_user_string(arg2);
3892 if (!p || !p2)
3893 ret = -TARGET_EFAULT;
3894 else
3895 ret = get_errno(rename(p, p2));
3896 unlock_user(p2, arg2, 0);
3897 unlock_user(p, arg1, 0);
3899 break;
3900 #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
3901 case TARGET_NR_renameat:
3903 void *p2;
3904 p = lock_user_string(arg2);
3905 p2 = lock_user_string(arg4);
3906 if (!p || !p2)
3907 ret = -TARGET_EFAULT;
3908 else
3909 ret = get_errno(sys_renameat(arg1, p, arg3, p2));
3910 unlock_user(p2, arg4, 0);
3911 unlock_user(p, arg2, 0);
3913 break;
3914 #endif
3915 case TARGET_NR_mkdir:
3916 if (!(p = lock_user_string(arg1)))
3917 goto efault;
3918 ret = get_errno(mkdir(p, arg2));
3919 unlock_user(p, arg1, 0);
3920 break;
3921 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
3922 case TARGET_NR_mkdirat:
3923 if (!(p = lock_user_string(arg2)))
3924 goto efault;
3925 ret = get_errno(sys_mkdirat(arg1, p, arg3));
3926 unlock_user(p, arg2, 0);
3927 break;
3928 #endif
3929 case TARGET_NR_rmdir:
3930 if (!(p = lock_user_string(arg1)))
3931 goto efault;
3932 ret = get_errno(rmdir(p));
3933 unlock_user(p, arg1, 0);
3934 break;
3935 case TARGET_NR_dup:
3936 ret = get_errno(dup(arg1));
3937 break;
3938 case TARGET_NR_pipe:
3940 int host_pipe[2];
3941 ret = get_errno(pipe(host_pipe));
3942 if (!is_error(ret)) {
3943 #if defined(TARGET_MIPS)
3944 CPUMIPSState *env = (CPUMIPSState*)cpu_env;
3945 env->active_tc.gpr[3] = host_pipe[1];
3946 ret = host_pipe[0];
3947 #elif defined(TARGET_SH4)
3948 ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
3949 ret = host_pipe[0];
3950 #else
3951 if (put_user_s32(host_pipe[0], arg1)
3952 || put_user_s32(host_pipe[1], arg1 + sizeof(host_pipe[0])))
3953 goto efault;
3954 #endif
3957 break;
3958 case TARGET_NR_times:
3960 struct target_tms *tmsp;
3961 struct tms tms;
3962 ret = get_errno(times(&tms));
3963 if (arg1) {
3964 tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
3965 if (!tmsp)
3966 goto efault;
3967 tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
3968 tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
3969 tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
3970 tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime));
3972 if (!is_error(ret))
3973 ret = host_to_target_clock_t(ret);
3975 break;
3976 #ifdef TARGET_NR_prof
3977 case TARGET_NR_prof:
3978 goto unimplemented;
3979 #endif
3980 #ifdef TARGET_NR_signal
3981 case TARGET_NR_signal:
3982 goto unimplemented;
3983 #endif
3984 case TARGET_NR_acct:
3985 if (arg1 == 0) {
3986 ret = get_errno(acct(NULL));
3987 } else {
3988 if (!(p = lock_user_string(arg1)))
3989 goto efault;
3990 ret = get_errno(acct(path(p)));
3991 unlock_user(p, arg1, 0);
3993 break;
3994 #ifdef TARGET_NR_umount2 /* not on alpha */
3995 case TARGET_NR_umount2:
3996 if (!(p = lock_user_string(arg1)))
3997 goto efault;
3998 ret = get_errno(umount2(p, arg2));
3999 unlock_user(p, arg1, 0);
4000 break;
4001 #endif
4002 #ifdef TARGET_NR_lock
4003 case TARGET_NR_lock:
4004 goto unimplemented;
4005 #endif
4006 case TARGET_NR_ioctl:
4007 ret = do_ioctl(arg1, arg2, arg3);
4008 break;
4009 case TARGET_NR_fcntl:
4010 ret = do_fcntl(arg1, arg2, arg3);
4011 break;
4012 #ifdef TARGET_NR_mpx
4013 case TARGET_NR_mpx:
4014 goto unimplemented;
4015 #endif
4016 case TARGET_NR_setpgid:
4017 ret = get_errno(setpgid(arg1, arg2));
4018 break;
4019 #ifdef TARGET_NR_ulimit
4020 case TARGET_NR_ulimit:
4021 goto unimplemented;
4022 #endif
4023 #ifdef TARGET_NR_oldolduname
4024 case TARGET_NR_oldolduname:
4025 goto unimplemented;
4026 #endif
4027 case TARGET_NR_umask:
4028 ret = get_errno(umask(arg1));
4029 break;
4030 case TARGET_NR_chroot:
4031 if (!(p = lock_user_string(arg1)))
4032 goto efault;
4033 ret = get_errno(chroot(p));
4034 unlock_user(p, arg1, 0);
4035 break;
4036 case TARGET_NR_ustat:
4037 goto unimplemented;
4038 case TARGET_NR_dup2:
4039 ret = get_errno(dup2(arg1, arg2));
4040 break;
4041 #ifdef TARGET_NR_getppid /* not on alpha */
4042 case TARGET_NR_getppid:
4043 ret = get_errno(getppid());
4044 break;
4045 #endif
4046 case TARGET_NR_getpgrp:
4047 ret = get_errno(getpgrp());
4048 break;
4049 case TARGET_NR_setsid:
4050 ret = get_errno(setsid());
4051 break;
4052 #ifdef TARGET_NR_sigaction
4053 case TARGET_NR_sigaction:
4055 #if !defined(TARGET_MIPS)
4056 struct target_old_sigaction *old_act;
4057 struct target_sigaction act, oact, *pact;
4058 if (arg2) {
4059 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4060 goto efault;
4061 act._sa_handler = old_act->_sa_handler;
4062 target_siginitset(&act.sa_mask, old_act->sa_mask);
4063 act.sa_flags = old_act->sa_flags;
4064 act.sa_restorer = old_act->sa_restorer;
4065 unlock_user_struct(old_act, arg2, 0);
4066 pact = &act;
4067 } else {
4068 pact = NULL;
4070 ret = get_errno(do_sigaction(arg1, pact, &oact));
4071 if (!is_error(ret) && arg3) {
4072 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4073 goto efault;
4074 old_act->_sa_handler = oact._sa_handler;
4075 old_act->sa_mask = oact.sa_mask.sig[0];
4076 old_act->sa_flags = oact.sa_flags;
4077 old_act->sa_restorer = oact.sa_restorer;
4078 unlock_user_struct(old_act, arg3, 1);
4080 #else
4081 struct target_sigaction act, oact, *pact, *old_act;
4083 if (arg2) {
4084 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4085 goto efault;
4086 act._sa_handler = old_act->_sa_handler;
4087 target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
4088 act.sa_flags = old_act->sa_flags;
4089 unlock_user_struct(old_act, arg2, 0);
4090 pact = &act;
4091 } else {
4092 pact = NULL;
4095 ret = get_errno(do_sigaction(arg1, pact, &oact));
4097 if (!is_error(ret) && arg3) {
4098 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4099 goto efault;
4100 old_act->_sa_handler = oact._sa_handler;
4101 old_act->sa_flags = oact.sa_flags;
4102 old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
4103 old_act->sa_mask.sig[1] = 0;
4104 old_act->sa_mask.sig[2] = 0;
4105 old_act->sa_mask.sig[3] = 0;
4106 unlock_user_struct(old_act, arg3, 1);
4108 #endif
4110 break;
4111 #endif
4112 case TARGET_NR_rt_sigaction:
4114 struct target_sigaction *act;
4115 struct target_sigaction *oact;
4117 if (arg2) {
4118 if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
4119 goto efault;
4120 } else
4121 act = NULL;
4122 if (arg3) {
4123 if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
4124 ret = -TARGET_EFAULT;
4125 goto rt_sigaction_fail;
4127 } else
4128 oact = NULL;
4129 ret = get_errno(do_sigaction(arg1, act, oact));
4130 rt_sigaction_fail:
4131 if (act)
4132 unlock_user_struct(act, arg2, 0);
4133 if (oact)
4134 unlock_user_struct(oact, arg3, 1);
4136 break;
4137 #ifdef TARGET_NR_sgetmask /* not on alpha */
4138 case TARGET_NR_sgetmask:
4140 sigset_t cur_set;
4141 abi_ulong target_set;
4142 sigprocmask(0, NULL, &cur_set);
4143 host_to_target_old_sigset(&target_set, &cur_set);
4144 ret = target_set;
4146 break;
4147 #endif
4148 #ifdef TARGET_NR_ssetmask /* not on alpha */
4149 case TARGET_NR_ssetmask:
4151 sigset_t set, oset, cur_set;
4152 abi_ulong target_set = arg1;
4153 sigprocmask(0, NULL, &cur_set);
4154 target_to_host_old_sigset(&set, &target_set);
4155 sigorset(&set, &set, &cur_set);
4156 sigprocmask(SIG_SETMASK, &set, &oset);
4157 host_to_target_old_sigset(&target_set, &oset);
4158 ret = target_set;
4160 break;
4161 #endif
4162 #ifdef TARGET_NR_sigprocmask
4163 case TARGET_NR_sigprocmask:
4165 int how = arg1;
4166 sigset_t set, oldset, *set_ptr;
4168 if (arg2) {
4169 switch(how) {
4170 case TARGET_SIG_BLOCK:
4171 how = SIG_BLOCK;
4172 break;
4173 case TARGET_SIG_UNBLOCK:
4174 how = SIG_UNBLOCK;
4175 break;
4176 case TARGET_SIG_SETMASK:
4177 how = SIG_SETMASK;
4178 break;
4179 default:
4180 ret = -TARGET_EINVAL;
4181 goto fail;
4183 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4184 goto efault;
4185 target_to_host_old_sigset(&set, p);
4186 unlock_user(p, arg2, 0);
4187 set_ptr = &set;
4188 } else {
4189 how = 0;
4190 set_ptr = NULL;
4192 ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
4193 if (!is_error(ret) && arg3) {
4194 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4195 goto efault;
4196 host_to_target_old_sigset(p, &oldset);
4197 unlock_user(p, arg3, sizeof(target_sigset_t));
4200 break;
4201 #endif
4202 case TARGET_NR_rt_sigprocmask:
4204 int how = arg1;
4205 sigset_t set, oldset, *set_ptr;
4207 if (arg2) {
4208 switch(how) {
4209 case TARGET_SIG_BLOCK:
4210 how = SIG_BLOCK;
4211 break;
4212 case TARGET_SIG_UNBLOCK:
4213 how = SIG_UNBLOCK;
4214 break;
4215 case TARGET_SIG_SETMASK:
4216 how = SIG_SETMASK;
4217 break;
4218 default:
4219 ret = -TARGET_EINVAL;
4220 goto fail;
4222 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4223 goto efault;
4224 target_to_host_sigset(&set, p);
4225 unlock_user(p, arg2, 0);
4226 set_ptr = &set;
4227 } else {
4228 how = 0;
4229 set_ptr = NULL;
4231 ret = get_errno(sigprocmask(how, set_ptr, &oldset));
4232 if (!is_error(ret) && arg3) {
4233 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4234 goto efault;
4235 host_to_target_sigset(p, &oldset);
4236 unlock_user(p, arg3, sizeof(target_sigset_t));
4239 break;
4240 #ifdef TARGET_NR_sigpending
4241 case TARGET_NR_sigpending:
4243 sigset_t set;
4244 ret = get_errno(sigpending(&set));
4245 if (!is_error(ret)) {
4246 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4247 goto efault;
4248 host_to_target_old_sigset(p, &set);
4249 unlock_user(p, arg1, sizeof(target_sigset_t));
4252 break;
4253 #endif
4254 case TARGET_NR_rt_sigpending:
4256 sigset_t set;
4257 ret = get_errno(sigpending(&set));
4258 if (!is_error(ret)) {
4259 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4260 goto efault;
4261 host_to_target_sigset(p, &set);
4262 unlock_user(p, arg1, sizeof(target_sigset_t));
4265 break;
4266 #ifdef TARGET_NR_sigsuspend
4267 case TARGET_NR_sigsuspend:
4269 sigset_t set;
4270 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4271 goto efault;
4272 target_to_host_old_sigset(&set, p);
4273 unlock_user(p, arg1, 0);
4274 ret = get_errno(sigsuspend(&set));
4276 break;
4277 #endif
4278 case TARGET_NR_rt_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_sigset(&set, p);
4284 unlock_user(p, arg1, 0);
4285 ret = get_errno(sigsuspend(&set));
4287 break;
4288 case TARGET_NR_rt_sigtimedwait:
4290 sigset_t set;
4291 struct timespec uts, *puts;
4292 siginfo_t uinfo;
4294 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4295 goto efault;
4296 target_to_host_sigset(&set, p);
4297 unlock_user(p, arg1, 0);
4298 if (arg3) {
4299 puts = &uts;
4300 target_to_host_timespec(puts, arg3);
4301 } else {
4302 puts = NULL;
4304 ret = get_errno(sigtimedwait(&set, &uinfo, puts));
4305 if (!is_error(ret) && arg2) {
4306 if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
4307 goto efault;
4308 host_to_target_siginfo(p, &uinfo);
4309 unlock_user(p, arg2, sizeof(target_siginfo_t));
4312 break;
4313 case TARGET_NR_rt_sigqueueinfo:
4315 siginfo_t uinfo;
4316 if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
4317 goto efault;
4318 target_to_host_siginfo(&uinfo, p);
4319 unlock_user(p, arg1, 0);
4320 ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
4322 break;
4323 #ifdef TARGET_NR_sigreturn
4324 case TARGET_NR_sigreturn:
4325 /* NOTE: ret is eax, so not transcoding must be done */
4326 ret = do_sigreturn(cpu_env);
4327 break;
4328 #endif
4329 case TARGET_NR_rt_sigreturn:
4330 /* NOTE: ret is eax, so not transcoding must be done */
4331 ret = do_rt_sigreturn(cpu_env);
4332 break;
4333 case TARGET_NR_sethostname:
4334 if (!(p = lock_user_string(arg1)))
4335 goto efault;
4336 ret = get_errno(sethostname(p, arg2));
4337 unlock_user(p, arg1, 0);
4338 break;
4339 case TARGET_NR_setrlimit:
4341 /* XXX: convert resource ? */
4342 int resource = arg1;
4343 struct target_rlimit *target_rlim;
4344 struct rlimit rlim;
4345 if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
4346 goto efault;
4347 rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4348 rlim.rlim_max = tswapl(target_rlim->rlim_max);
4349 unlock_user_struct(target_rlim, arg2, 0);
4350 ret = get_errno(setrlimit(resource, &rlim));
4352 break;
4353 case TARGET_NR_getrlimit:
4355 /* XXX: convert resource ? */
4356 int resource = arg1;
4357 struct target_rlimit *target_rlim;
4358 struct rlimit rlim;
4360 ret = get_errno(getrlimit(resource, &rlim));
4361 if (!is_error(ret)) {
4362 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
4363 goto efault;
4364 rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4365 rlim.rlim_max = tswapl(target_rlim->rlim_max);
4366 unlock_user_struct(target_rlim, arg2, 1);
4369 break;
4370 case TARGET_NR_getrusage:
4372 struct rusage rusage;
4373 ret = get_errno(getrusage(arg1, &rusage));
4374 if (!is_error(ret)) {
4375 host_to_target_rusage(arg2, &rusage);
4378 break;
4379 case TARGET_NR_gettimeofday:
4381 struct timeval tv;
4382 ret = get_errno(gettimeofday(&tv, NULL));
4383 if (!is_error(ret)) {
4384 if (copy_to_user_timeval(arg1, &tv))
4385 goto efault;
4388 break;
4389 case TARGET_NR_settimeofday:
4391 struct timeval tv;
4392 if (copy_from_user_timeval(&tv, arg1))
4393 goto efault;
4394 ret = get_errno(settimeofday(&tv, NULL));
4396 break;
4397 #ifdef TARGET_NR_select
4398 case TARGET_NR_select:
4400 struct target_sel_arg_struct *sel;
4401 abi_ulong inp, outp, exp, tvp;
4402 long nsel;
4404 if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
4405 goto efault;
4406 nsel = tswapl(sel->n);
4407 inp = tswapl(sel->inp);
4408 outp = tswapl(sel->outp);
4409 exp = tswapl(sel->exp);
4410 tvp = tswapl(sel->tvp);
4411 unlock_user_struct(sel, arg1, 0);
4412 ret = do_select(nsel, inp, outp, exp, tvp);
4414 break;
4415 #endif
4416 case TARGET_NR_symlink:
4418 void *p2;
4419 p = lock_user_string(arg1);
4420 p2 = lock_user_string(arg2);
4421 if (!p || !p2)
4422 ret = -TARGET_EFAULT;
4423 else
4424 ret = get_errno(symlink(p, p2));
4425 unlock_user(p2, arg2, 0);
4426 unlock_user(p, arg1, 0);
4428 break;
4429 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
4430 case TARGET_NR_symlinkat:
4432 void *p2;
4433 p = lock_user_string(arg1);
4434 p2 = lock_user_string(arg3);
4435 if (!p || !p2)
4436 ret = -TARGET_EFAULT;
4437 else
4438 ret = get_errno(sys_symlinkat(p, arg2, p2));
4439 unlock_user(p2, arg3, 0);
4440 unlock_user(p, arg1, 0);
4442 break;
4443 #endif
4444 #ifdef TARGET_NR_oldlstat
4445 case TARGET_NR_oldlstat:
4446 goto unimplemented;
4447 #endif
4448 case TARGET_NR_readlink:
4450 void *p2, *temp;
4451 p = lock_user_string(arg1);
4452 p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
4453 if (!p || !p2)
4454 ret = -TARGET_EFAULT;
4455 else {
4456 if (strncmp((const char *)p, "/proc/self/exe", 14) == 0) {
4457 char real[PATH_MAX];
4458 temp = realpath(exec_path,real);
4459 ret = (temp==NULL) ? get_errno(-1) : strlen(real) ;
4460 snprintf((char *)p2, arg3, "%s", real);
4462 else
4463 ret = get_errno(readlink(path(p), p2, arg3));
4465 unlock_user(p2, arg2, ret);
4466 unlock_user(p, arg1, 0);
4468 break;
4469 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
4470 case TARGET_NR_readlinkat:
4472 void *p2;
4473 p = lock_user_string(arg2);
4474 p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
4475 if (!p || !p2)
4476 ret = -TARGET_EFAULT;
4477 else
4478 ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
4479 unlock_user(p2, arg3, ret);
4480 unlock_user(p, arg2, 0);
4482 break;
4483 #endif
4484 #ifdef TARGET_NR_uselib
4485 case TARGET_NR_uselib:
4486 goto unimplemented;
4487 #endif
4488 #ifdef TARGET_NR_swapon
4489 case TARGET_NR_swapon:
4490 if (!(p = lock_user_string(arg1)))
4491 goto efault;
4492 ret = get_errno(swapon(p, arg2));
4493 unlock_user(p, arg1, 0);
4494 break;
4495 #endif
4496 case TARGET_NR_reboot:
4497 goto unimplemented;
4498 #ifdef TARGET_NR_readdir
4499 case TARGET_NR_readdir:
4500 goto unimplemented;
4501 #endif
4502 #ifdef TARGET_NR_mmap
4503 case TARGET_NR_mmap:
4504 #if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS)
4506 abi_ulong *v;
4507 abi_ulong v1, v2, v3, v4, v5, v6;
4508 if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
4509 goto efault;
4510 v1 = tswapl(v[0]);
4511 v2 = tswapl(v[1]);
4512 v3 = tswapl(v[2]);
4513 v4 = tswapl(v[3]);
4514 v5 = tswapl(v[4]);
4515 v6 = tswapl(v[5]);
4516 unlock_user(v, arg1, 0);
4517 ret = get_errno(target_mmap(v1, v2, v3,
4518 target_to_host_bitmask(v4, mmap_flags_tbl),
4519 v5, v6));
4521 #else
4522 ret = get_errno(target_mmap(arg1, arg2, arg3,
4523 target_to_host_bitmask(arg4, mmap_flags_tbl),
4524 arg5,
4525 arg6));
4526 #endif
4527 break;
4528 #endif
4529 #ifdef TARGET_NR_mmap2
4530 case TARGET_NR_mmap2:
4531 #ifndef MMAP_SHIFT
4532 #define MMAP_SHIFT 12
4533 #endif
4534 ret = get_errno(target_mmap(arg1, arg2, arg3,
4535 target_to_host_bitmask(arg4, mmap_flags_tbl),
4536 arg5,
4537 arg6 << MMAP_SHIFT));
4538 break;
4539 #endif
4540 case TARGET_NR_munmap:
4541 ret = get_errno(target_munmap(arg1, arg2));
4542 break;
4543 case TARGET_NR_mprotect:
4544 ret = get_errno(target_mprotect(arg1, arg2, arg3));
4545 break;
4546 #ifdef TARGET_NR_mremap
4547 case TARGET_NR_mremap:
4548 ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
4549 break;
4550 #endif
4551 /* ??? msync/mlock/munlock are broken for softmmu. */
4552 #ifdef TARGET_NR_msync
4553 case TARGET_NR_msync:
4554 ret = get_errno(msync(g2h(arg1), arg2, arg3));
4555 break;
4556 #endif
4557 #ifdef TARGET_NR_mlock
4558 case TARGET_NR_mlock:
4559 ret = get_errno(mlock(g2h(arg1), arg2));
4560 break;
4561 #endif
4562 #ifdef TARGET_NR_munlock
4563 case TARGET_NR_munlock:
4564 ret = get_errno(munlock(g2h(arg1), arg2));
4565 break;
4566 #endif
4567 #ifdef TARGET_NR_mlockall
4568 case TARGET_NR_mlockall:
4569 ret = get_errno(mlockall(arg1));
4570 break;
4571 #endif
4572 #ifdef TARGET_NR_munlockall
4573 case TARGET_NR_munlockall:
4574 ret = get_errno(munlockall());
4575 break;
4576 #endif
4577 case TARGET_NR_truncate:
4578 if (!(p = lock_user_string(arg1)))
4579 goto efault;
4580 ret = get_errno(truncate(p, arg2));
4581 unlock_user(p, arg1, 0);
4582 break;
4583 case TARGET_NR_ftruncate:
4584 ret = get_errno(ftruncate(arg1, arg2));
4585 break;
4586 case TARGET_NR_fchmod:
4587 ret = get_errno(fchmod(arg1, arg2));
4588 break;
4589 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
4590 case TARGET_NR_fchmodat:
4591 if (!(p = lock_user_string(arg2)))
4592 goto efault;
4593 ret = get_errno(sys_fchmodat(arg1, p, arg3, arg4));
4594 unlock_user(p, arg2, 0);
4595 break;
4596 #endif
4597 case TARGET_NR_getpriority:
4598 /* libc does special remapping of the return value of
4599 * sys_getpriority() so it's just easiest to call
4600 * sys_getpriority() directly rather than through libc. */
4601 ret = sys_getpriority(arg1, arg2);
4602 break;
4603 case TARGET_NR_setpriority:
4604 ret = get_errno(setpriority(arg1, arg2, arg3));
4605 break;
4606 #ifdef TARGET_NR_profil
4607 case TARGET_NR_profil:
4608 goto unimplemented;
4609 #endif
4610 case TARGET_NR_statfs:
4611 if (!(p = lock_user_string(arg1)))
4612 goto efault;
4613 ret = get_errno(statfs(path(p), &stfs));
4614 unlock_user(p, arg1, 0);
4615 convert_statfs:
4616 if (!is_error(ret)) {
4617 struct target_statfs *target_stfs;
4619 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
4620 goto efault;
4621 __put_user(stfs.f_type, &target_stfs->f_type);
4622 __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4623 __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4624 __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4625 __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4626 __put_user(stfs.f_files, &target_stfs->f_files);
4627 __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4628 __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4629 __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4630 __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4631 unlock_user_struct(target_stfs, arg2, 1);
4633 break;
4634 case TARGET_NR_fstatfs:
4635 ret = get_errno(fstatfs(arg1, &stfs));
4636 goto convert_statfs;
4637 #ifdef TARGET_NR_statfs64
4638 case TARGET_NR_statfs64:
4639 if (!(p = lock_user_string(arg1)))
4640 goto efault;
4641 ret = get_errno(statfs(path(p), &stfs));
4642 unlock_user(p, arg1, 0);
4643 convert_statfs64:
4644 if (!is_error(ret)) {
4645 struct target_statfs64 *target_stfs;
4647 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
4648 goto efault;
4649 __put_user(stfs.f_type, &target_stfs->f_type);
4650 __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4651 __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4652 __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4653 __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4654 __put_user(stfs.f_files, &target_stfs->f_files);
4655 __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4656 __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4657 __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4658 __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4659 unlock_user_struct(target_stfs, arg3, 1);
4661 break;
4662 case TARGET_NR_fstatfs64:
4663 ret = get_errno(fstatfs(arg1, &stfs));
4664 goto convert_statfs64;
4665 #endif
4666 #ifdef TARGET_NR_ioperm
4667 case TARGET_NR_ioperm:
4668 goto unimplemented;
4669 #endif
4670 #ifdef TARGET_NR_socketcall
4671 case TARGET_NR_socketcall:
4672 ret = do_socketcall(arg1, arg2);
4673 break;
4674 #endif
4675 #ifdef TARGET_NR_accept
4676 case TARGET_NR_accept:
4677 ret = do_accept(arg1, arg2, arg3);
4678 break;
4679 #endif
4680 #ifdef TARGET_NR_bind
4681 case TARGET_NR_bind:
4682 ret = do_bind(arg1, arg2, arg3);
4683 break;
4684 #endif
4685 #ifdef TARGET_NR_connect
4686 case TARGET_NR_connect:
4687 ret = do_connect(arg1, arg2, arg3);
4688 break;
4689 #endif
4690 #ifdef TARGET_NR_getpeername
4691 case TARGET_NR_getpeername:
4692 ret = do_getpeername(arg1, arg2, arg3);
4693 break;
4694 #endif
4695 #ifdef TARGET_NR_getsockname
4696 case TARGET_NR_getsockname:
4697 ret = do_getsockname(arg1, arg2, arg3);
4698 break;
4699 #endif
4700 #ifdef TARGET_NR_getsockopt
4701 case TARGET_NR_getsockopt:
4702 ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
4703 break;
4704 #endif
4705 #ifdef TARGET_NR_listen
4706 case TARGET_NR_listen:
4707 ret = get_errno(listen(arg1, arg2));
4708 break;
4709 #endif
4710 #ifdef TARGET_NR_recv
4711 case TARGET_NR_recv:
4712 ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
4713 break;
4714 #endif
4715 #ifdef TARGET_NR_recvfrom
4716 case TARGET_NR_recvfrom:
4717 ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
4718 break;
4719 #endif
4720 #ifdef TARGET_NR_recvmsg
4721 case TARGET_NR_recvmsg:
4722 ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
4723 break;
4724 #endif
4725 #ifdef TARGET_NR_send
4726 case TARGET_NR_send:
4727 ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
4728 break;
4729 #endif
4730 #ifdef TARGET_NR_sendmsg
4731 case TARGET_NR_sendmsg:
4732 ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
4733 break;
4734 #endif
4735 #ifdef TARGET_NR_sendto
4736 case TARGET_NR_sendto:
4737 ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
4738 break;
4739 #endif
4740 #ifdef TARGET_NR_shutdown
4741 case TARGET_NR_shutdown:
4742 ret = get_errno(shutdown(arg1, arg2));
4743 break;
4744 #endif
4745 #ifdef TARGET_NR_socket
4746 case TARGET_NR_socket:
4747 ret = do_socket(arg1, arg2, arg3);
4748 break;
4749 #endif
4750 #ifdef TARGET_NR_socketpair
4751 case TARGET_NR_socketpair:
4752 ret = do_socketpair(arg1, arg2, arg3, arg4);
4753 break;
4754 #endif
4755 #ifdef TARGET_NR_setsockopt
4756 case TARGET_NR_setsockopt:
4757 ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
4758 break;
4759 #endif
4761 case TARGET_NR_syslog:
4762 if (!(p = lock_user_string(arg2)))
4763 goto efault;
4764 ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
4765 unlock_user(p, arg2, 0);
4766 break;
4768 case TARGET_NR_setitimer:
4770 struct itimerval value, ovalue, *pvalue;
4772 if (arg2) {
4773 pvalue = &value;
4774 if (copy_from_user_timeval(&pvalue->it_interval, arg2)
4775 || copy_from_user_timeval(&pvalue->it_value,
4776 arg2 + sizeof(struct target_timeval)))
4777 goto efault;
4778 } else {
4779 pvalue = NULL;
4781 ret = get_errno(setitimer(arg1, pvalue, &ovalue));
4782 if (!is_error(ret) && arg3) {
4783 if (copy_to_user_timeval(arg3,
4784 &ovalue.it_interval)
4785 || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
4786 &ovalue.it_value))
4787 goto efault;
4790 break;
4791 case TARGET_NR_getitimer:
4793 struct itimerval value;
4795 ret = get_errno(getitimer(arg1, &value));
4796 if (!is_error(ret) && arg2) {
4797 if (copy_to_user_timeval(arg2,
4798 &value.it_interval)
4799 || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
4800 &value.it_value))
4801 goto efault;
4804 break;
4805 case TARGET_NR_stat:
4806 if (!(p = lock_user_string(arg1)))
4807 goto efault;
4808 ret = get_errno(stat(path(p), &st));
4809 unlock_user(p, arg1, 0);
4810 goto do_stat;
4811 case TARGET_NR_lstat:
4812 if (!(p = lock_user_string(arg1)))
4813 goto efault;
4814 ret = get_errno(lstat(path(p), &st));
4815 unlock_user(p, arg1, 0);
4816 goto do_stat;
4817 case TARGET_NR_fstat:
4819 ret = get_errno(fstat(arg1, &st));
4820 do_stat:
4821 if (!is_error(ret)) {
4822 struct target_stat *target_st;
4824 if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
4825 goto efault;
4826 __put_user(st.st_dev, &target_st->st_dev);
4827 __put_user(st.st_ino, &target_st->st_ino);
4828 __put_user(st.st_mode, &target_st->st_mode);
4829 __put_user(st.st_uid, &target_st->st_uid);
4830 __put_user(st.st_gid, &target_st->st_gid);
4831 __put_user(st.st_nlink, &target_st->st_nlink);
4832 __put_user(st.st_rdev, &target_st->st_rdev);
4833 __put_user(st.st_size, &target_st->st_size);
4834 __put_user(st.st_blksize, &target_st->st_blksize);
4835 __put_user(st.st_blocks, &target_st->st_blocks);
4836 __put_user(st.st_atime, &target_st->target_st_atime);
4837 __put_user(st.st_mtime, &target_st->target_st_mtime);
4838 __put_user(st.st_ctime, &target_st->target_st_ctime);
4839 unlock_user_struct(target_st, arg2, 1);
4842 break;
4843 #ifdef TARGET_NR_olduname
4844 case TARGET_NR_olduname:
4845 goto unimplemented;
4846 #endif
4847 #ifdef TARGET_NR_iopl
4848 case TARGET_NR_iopl:
4849 goto unimplemented;
4850 #endif
4851 case TARGET_NR_vhangup:
4852 ret = get_errno(vhangup());
4853 break;
4854 #ifdef TARGET_NR_idle
4855 case TARGET_NR_idle:
4856 goto unimplemented;
4857 #endif
4858 #ifdef TARGET_NR_syscall
4859 case TARGET_NR_syscall:
4860 ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
4861 break;
4862 #endif
4863 case TARGET_NR_wait4:
4865 int status;
4866 abi_long status_ptr = arg2;
4867 struct rusage rusage, *rusage_ptr;
4868 abi_ulong target_rusage = arg4;
4869 if (target_rusage)
4870 rusage_ptr = &rusage;
4871 else
4872 rusage_ptr = NULL;
4873 ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
4874 if (!is_error(ret)) {
4875 if (status_ptr) {
4876 if (put_user_s32(status, status_ptr))
4877 goto efault;
4879 if (target_rusage)
4880 host_to_target_rusage(target_rusage, &rusage);
4883 break;
4884 #ifdef TARGET_NR_swapoff
4885 case TARGET_NR_swapoff:
4886 if (!(p = lock_user_string(arg1)))
4887 goto efault;
4888 ret = get_errno(swapoff(p));
4889 unlock_user(p, arg1, 0);
4890 break;
4891 #endif
4892 case TARGET_NR_sysinfo:
4894 struct target_sysinfo *target_value;
4895 struct sysinfo value;
4896 ret = get_errno(sysinfo(&value));
4897 if (!is_error(ret) && arg1)
4899 if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
4900 goto efault;
4901 __put_user(value.uptime, &target_value->uptime);
4902 __put_user(value.loads[0], &target_value->loads[0]);
4903 __put_user(value.loads[1], &target_value->loads[1]);
4904 __put_user(value.loads[2], &target_value->loads[2]);
4905 __put_user(value.totalram, &target_value->totalram);
4906 __put_user(value.freeram, &target_value->freeram);
4907 __put_user(value.sharedram, &target_value->sharedram);
4908 __put_user(value.bufferram, &target_value->bufferram);
4909 __put_user(value.totalswap, &target_value->totalswap);
4910 __put_user(value.freeswap, &target_value->freeswap);
4911 __put_user(value.procs, &target_value->procs);
4912 __put_user(value.totalhigh, &target_value->totalhigh);
4913 __put_user(value.freehigh, &target_value->freehigh);
4914 __put_user(value.mem_unit, &target_value->mem_unit);
4915 unlock_user_struct(target_value, arg1, 1);
4918 break;
4919 #ifdef TARGET_NR_ipc
4920 case TARGET_NR_ipc:
4921 ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
4922 break;
4923 #endif
4925 #ifdef TARGET_NR_msgctl
4926 case TARGET_NR_msgctl:
4927 ret = do_msgctl(arg1, arg2, arg3);
4928 break;
4929 #endif
4930 #ifdef TARGET_NR_msgget
4931 case TARGET_NR_msgget:
4932 ret = get_errno(msgget(arg1, arg2));
4933 break;
4934 #endif
4935 #ifdef TARGET_NR_msgrcv
4936 case TARGET_NR_msgrcv:
4937 ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
4938 break;
4939 #endif
4940 #ifdef TARGET_NR_msgsnd
4941 case TARGET_NR_msgsnd:
4942 ret = do_msgsnd(arg1, arg2, arg3, arg4);
4943 break;
4944 #endif
4945 case TARGET_NR_fsync:
4946 ret = get_errno(fsync(arg1));
4947 break;
4948 case TARGET_NR_clone:
4949 #if defined(TARGET_SH4)
4950 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
4951 #elif defined(TARGET_CRIS)
4952 ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg4, arg5));
4953 #else
4954 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
4955 #endif
4956 break;
4957 #ifdef __NR_exit_group
4958 /* new thread calls */
4959 case TARGET_NR_exit_group:
4960 #ifdef HAVE_GPROF
4961 _mcleanup();
4962 #endif
4963 gdb_exit(cpu_env, arg1);
4964 ret = get_errno(exit_group(arg1));
4965 break;
4966 #endif
4967 case TARGET_NR_setdomainname:
4968 if (!(p = lock_user_string(arg1)))
4969 goto efault;
4970 ret = get_errno(setdomainname(p, arg2));
4971 unlock_user(p, arg1, 0);
4972 break;
4973 case TARGET_NR_uname:
4974 /* no need to transcode because we use the linux syscall */
4976 struct new_utsname * buf;
4978 if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
4979 goto efault;
4980 ret = get_errno(sys_uname(buf));
4981 if (!is_error(ret)) {
4982 /* Overrite the native machine name with whatever is being
4983 emulated. */
4984 strcpy (buf->machine, UNAME_MACHINE);
4985 /* Allow the user to override the reported release. */
4986 if (qemu_uname_release && *qemu_uname_release)
4987 strcpy (buf->release, qemu_uname_release);
4989 unlock_user_struct(buf, arg1, 1);
4991 break;
4992 #ifdef TARGET_I386
4993 case TARGET_NR_modify_ldt:
4994 ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
4995 break;
4996 #if !defined(TARGET_X86_64)
4997 case TARGET_NR_vm86old:
4998 goto unimplemented;
4999 case TARGET_NR_vm86:
5000 ret = do_vm86(cpu_env, arg1, arg2);
5001 break;
5002 #endif
5003 #endif
5004 case TARGET_NR_adjtimex:
5005 goto unimplemented;
5006 #ifdef TARGET_NR_create_module
5007 case TARGET_NR_create_module:
5008 #endif
5009 case TARGET_NR_init_module:
5010 case TARGET_NR_delete_module:
5011 #ifdef TARGET_NR_get_kernel_syms
5012 case TARGET_NR_get_kernel_syms:
5013 #endif
5014 goto unimplemented;
5015 case TARGET_NR_quotactl:
5016 goto unimplemented;
5017 case TARGET_NR_getpgid:
5018 ret = get_errno(getpgid(arg1));
5019 break;
5020 case TARGET_NR_fchdir:
5021 ret = get_errno(fchdir(arg1));
5022 break;
5023 #ifdef TARGET_NR_bdflush /* not on x86_64 */
5024 case TARGET_NR_bdflush:
5025 goto unimplemented;
5026 #endif
5027 #ifdef TARGET_NR_sysfs
5028 case TARGET_NR_sysfs:
5029 goto unimplemented;
5030 #endif
5031 case TARGET_NR_personality:
5032 ret = get_errno(personality(arg1));
5033 break;
5034 #ifdef TARGET_NR_afs_syscall
5035 case TARGET_NR_afs_syscall:
5036 goto unimplemented;
5037 #endif
5038 #ifdef TARGET_NR__llseek /* Not on alpha */
5039 case TARGET_NR__llseek:
5041 #if defined (__x86_64__)
5042 ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
5043 if (put_user_s64(ret, arg4))
5044 goto efault;
5045 #else
5046 int64_t res;
5047 ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
5048 if (put_user_s64(res, arg4))
5049 goto efault;
5050 #endif
5052 break;
5053 #endif
5054 case TARGET_NR_getdents:
5055 #if TARGET_ABI_BITS != 32
5056 goto unimplemented;
5057 #elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
5059 struct target_dirent *target_dirp;
5060 struct linux_dirent *dirp;
5061 abi_long count = arg3;
5063 dirp = malloc(count);
5064 if (!dirp) {
5065 ret = -TARGET_ENOMEM;
5066 goto fail;
5069 ret = get_errno(sys_getdents(arg1, dirp, count));
5070 if (!is_error(ret)) {
5071 struct linux_dirent *de;
5072 struct target_dirent *tde;
5073 int len = ret;
5074 int reclen, treclen;
5075 int count1, tnamelen;
5077 count1 = 0;
5078 de = dirp;
5079 if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5080 goto efault;
5081 tde = target_dirp;
5082 while (len > 0) {
5083 reclen = de->d_reclen;
5084 treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
5085 tde->d_reclen = tswap16(treclen);
5086 tde->d_ino = tswapl(de->d_ino);
5087 tde->d_off = tswapl(de->d_off);
5088 tnamelen = treclen - (2 * sizeof(abi_long) + 2);
5089 if (tnamelen > 256)
5090 tnamelen = 256;
5091 /* XXX: may not be correct */
5092 pstrcpy(tde->d_name, tnamelen, de->d_name);
5093 de = (struct linux_dirent *)((char *)de + reclen);
5094 len -= reclen;
5095 tde = (struct target_dirent *)((char *)tde + treclen);
5096 count1 += treclen;
5098 ret = count1;
5099 unlock_user(target_dirp, arg2, ret);
5101 free(dirp);
5103 #else
5105 struct linux_dirent *dirp;
5106 abi_long count = arg3;
5108 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5109 goto efault;
5110 ret = get_errno(sys_getdents(arg1, dirp, count));
5111 if (!is_error(ret)) {
5112 struct linux_dirent *de;
5113 int len = ret;
5114 int reclen;
5115 de = dirp;
5116 while (len > 0) {
5117 reclen = de->d_reclen;
5118 if (reclen > len)
5119 break;
5120 de->d_reclen = tswap16(reclen);
5121 tswapls(&de->d_ino);
5122 tswapls(&de->d_off);
5123 de = (struct linux_dirent *)((char *)de + reclen);
5124 len -= reclen;
5127 unlock_user(dirp, arg2, ret);
5129 #endif
5130 break;
5131 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
5132 case TARGET_NR_getdents64:
5134 struct linux_dirent64 *dirp;
5135 abi_long count = arg3;
5136 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5137 goto efault;
5138 ret = get_errno(sys_getdents64(arg1, dirp, count));
5139 if (!is_error(ret)) {
5140 struct linux_dirent64 *de;
5141 int len = ret;
5142 int reclen;
5143 de = dirp;
5144 while (len > 0) {
5145 reclen = de->d_reclen;
5146 if (reclen > len)
5147 break;
5148 de->d_reclen = tswap16(reclen);
5149 tswap64s((uint64_t *)&de->d_ino);
5150 tswap64s((uint64_t *)&de->d_off);
5151 de = (struct linux_dirent64 *)((char *)de + reclen);
5152 len -= reclen;
5155 unlock_user(dirp, arg2, ret);
5157 break;
5158 #endif /* TARGET_NR_getdents64 */
5159 #ifdef TARGET_NR__newselect
5160 case TARGET_NR__newselect:
5161 ret = do_select(arg1, arg2, arg3, arg4, arg5);
5162 break;
5163 #endif
5164 #ifdef TARGET_NR_poll
5165 case TARGET_NR_poll:
5167 struct target_pollfd *target_pfd;
5168 unsigned int nfds = arg2;
5169 int timeout = arg3;
5170 struct pollfd *pfd;
5171 unsigned int i;
5173 target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
5174 if (!target_pfd)
5175 goto efault;
5176 pfd = alloca(sizeof(struct pollfd) * nfds);
5177 for(i = 0; i < nfds; i++) {
5178 pfd[i].fd = tswap32(target_pfd[i].fd);
5179 pfd[i].events = tswap16(target_pfd[i].events);
5181 ret = get_errno(poll(pfd, nfds, timeout));
5182 if (!is_error(ret)) {
5183 for(i = 0; i < nfds; i++) {
5184 target_pfd[i].revents = tswap16(pfd[i].revents);
5186 ret += nfds * (sizeof(struct target_pollfd)
5187 - sizeof(struct pollfd));
5189 unlock_user(target_pfd, arg1, ret);
5191 break;
5192 #endif
5193 case TARGET_NR_flock:
5194 /* NOTE: the flock constant seems to be the same for every
5195 Linux platform */
5196 ret = get_errno(flock(arg1, arg2));
5197 break;
5198 case TARGET_NR_readv:
5200 int count = arg3;
5201 struct iovec *vec;
5203 vec = alloca(count * sizeof(struct iovec));
5204 if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
5205 goto efault;
5206 ret = get_errno(readv(arg1, vec, count));
5207 unlock_iovec(vec, arg2, count, 1);
5209 break;
5210 case TARGET_NR_writev:
5212 int count = arg3;
5213 struct iovec *vec;
5215 vec = alloca(count * sizeof(struct iovec));
5216 if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
5217 goto efault;
5218 ret = get_errno(writev(arg1, vec, count));
5219 unlock_iovec(vec, arg2, count, 0);
5221 break;
5222 case TARGET_NR_getsid:
5223 ret = get_errno(getsid(arg1));
5224 break;
5225 #if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
5226 case TARGET_NR_fdatasync:
5227 ret = get_errno(fdatasync(arg1));
5228 break;
5229 #endif
5230 case TARGET_NR__sysctl:
5231 /* We don't implement this, but ENOTDIR is always a safe
5232 return value. */
5233 ret = -TARGET_ENOTDIR;
5234 break;
5235 case TARGET_NR_sched_setparam:
5237 struct sched_param *target_schp;
5238 struct sched_param schp;
5240 if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
5241 goto efault;
5242 schp.sched_priority = tswap32(target_schp->sched_priority);
5243 unlock_user_struct(target_schp, arg2, 0);
5244 ret = get_errno(sched_setparam(arg1, &schp));
5246 break;
5247 case TARGET_NR_sched_getparam:
5249 struct sched_param *target_schp;
5250 struct sched_param schp;
5251 ret = get_errno(sched_getparam(arg1, &schp));
5252 if (!is_error(ret)) {
5253 if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
5254 goto efault;
5255 target_schp->sched_priority = tswap32(schp.sched_priority);
5256 unlock_user_struct(target_schp, arg2, 1);
5259 break;
5260 case TARGET_NR_sched_setscheduler:
5262 struct sched_param *target_schp;
5263 struct sched_param schp;
5264 if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
5265 goto efault;
5266 schp.sched_priority = tswap32(target_schp->sched_priority);
5267 unlock_user_struct(target_schp, arg3, 0);
5268 ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
5270 break;
5271 case TARGET_NR_sched_getscheduler:
5272 ret = get_errno(sched_getscheduler(arg1));
5273 break;
5274 case TARGET_NR_sched_yield:
5275 ret = get_errno(sched_yield());
5276 break;
5277 case TARGET_NR_sched_get_priority_max:
5278 ret = get_errno(sched_get_priority_max(arg1));
5279 break;
5280 case TARGET_NR_sched_get_priority_min:
5281 ret = get_errno(sched_get_priority_min(arg1));
5282 break;
5283 case TARGET_NR_sched_rr_get_interval:
5285 struct timespec ts;
5286 ret = get_errno(sched_rr_get_interval(arg1, &ts));
5287 if (!is_error(ret)) {
5288 host_to_target_timespec(arg2, &ts);
5291 break;
5292 case TARGET_NR_nanosleep:
5294 struct timespec req, rem;
5295 target_to_host_timespec(&req, arg1);
5296 ret = get_errno(nanosleep(&req, &rem));
5297 if (is_error(ret) && arg2) {
5298 host_to_target_timespec(arg2, &rem);
5301 break;
5302 #ifdef TARGET_NR_query_module
5303 case TARGET_NR_query_module:
5304 goto unimplemented;
5305 #endif
5306 #ifdef TARGET_NR_nfsservctl
5307 case TARGET_NR_nfsservctl:
5308 goto unimplemented;
5309 #endif
5310 case TARGET_NR_prctl:
5311 switch (arg1)
5313 case PR_GET_PDEATHSIG:
5315 int deathsig;
5316 ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
5317 if (!is_error(ret) && arg2
5318 && put_user_ual(deathsig, arg2))
5319 goto efault;
5321 break;
5322 default:
5323 ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
5324 break;
5326 break;
5327 #ifdef TARGET_NR_arch_prctl
5328 case TARGET_NR_arch_prctl:
5329 #if defined(TARGET_I386) && !defined(TARGET_ABI32)
5330 ret = do_arch_prctl(cpu_env, arg1, arg2);
5331 break;
5332 #else
5333 goto unimplemented;
5334 #endif
5335 #endif
5336 #ifdef TARGET_NR_pread
5337 case TARGET_NR_pread:
5338 #ifdef TARGET_ARM
5339 if (((CPUARMState *)cpu_env)->eabi)
5340 arg4 = arg5;
5341 #endif
5342 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5343 goto efault;
5344 ret = get_errno(pread(arg1, p, arg3, arg4));
5345 unlock_user(p, arg2, ret);
5346 break;
5347 case TARGET_NR_pwrite:
5348 #ifdef TARGET_ARM
5349 if (((CPUARMState *)cpu_env)->eabi)
5350 arg4 = arg5;
5351 #endif
5352 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5353 goto efault;
5354 ret = get_errno(pwrite(arg1, p, arg3, arg4));
5355 unlock_user(p, arg2, 0);
5356 break;
5357 #endif
5358 #ifdef TARGET_NR_pread64
5359 case TARGET_NR_pread64:
5360 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5361 goto efault;
5362 ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
5363 unlock_user(p, arg2, ret);
5364 break;
5365 case TARGET_NR_pwrite64:
5366 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5367 goto efault;
5368 ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
5369 unlock_user(p, arg2, 0);
5370 break;
5371 #endif
5372 case TARGET_NR_getcwd:
5373 if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
5374 goto efault;
5375 ret = get_errno(sys_getcwd1(p, arg2));
5376 unlock_user(p, arg1, ret);
5377 break;
5378 case TARGET_NR_capget:
5379 goto unimplemented;
5380 case TARGET_NR_capset:
5381 goto unimplemented;
5382 case TARGET_NR_sigaltstack:
5383 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
5384 defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA)
5385 ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env));
5386 break;
5387 #else
5388 goto unimplemented;
5389 #endif
5390 case TARGET_NR_sendfile:
5391 goto unimplemented;
5392 #ifdef TARGET_NR_getpmsg
5393 case TARGET_NR_getpmsg:
5394 goto unimplemented;
5395 #endif
5396 #ifdef TARGET_NR_putpmsg
5397 case TARGET_NR_putpmsg:
5398 goto unimplemented;
5399 #endif
5400 #ifdef TARGET_NR_vfork
5401 case TARGET_NR_vfork:
5402 ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
5403 0, 0, 0, 0));
5404 break;
5405 #endif
5406 #ifdef TARGET_NR_ugetrlimit
5407 case TARGET_NR_ugetrlimit:
5409 struct rlimit rlim;
5410 ret = get_errno(getrlimit(arg1, &rlim));
5411 if (!is_error(ret)) {
5412 struct target_rlimit *target_rlim;
5413 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
5414 goto efault;
5415 target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
5416 target_rlim->rlim_max = tswapl(rlim.rlim_max);
5417 unlock_user_struct(target_rlim, arg2, 1);
5419 break;
5421 #endif
5422 #ifdef TARGET_NR_truncate64
5423 case TARGET_NR_truncate64:
5424 if (!(p = lock_user_string(arg1)))
5425 goto efault;
5426 ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
5427 unlock_user(p, arg1, 0);
5428 break;
5429 #endif
5430 #ifdef TARGET_NR_ftruncate64
5431 case TARGET_NR_ftruncate64:
5432 ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
5433 break;
5434 #endif
5435 #ifdef TARGET_NR_stat64
5436 case TARGET_NR_stat64:
5437 if (!(p = lock_user_string(arg1)))
5438 goto efault;
5439 ret = get_errno(stat(path(p), &st));
5440 unlock_user(p, arg1, 0);
5441 if (!is_error(ret))
5442 ret = host_to_target_stat64(cpu_env, arg2, &st);
5443 break;
5444 #endif
5445 #ifdef TARGET_NR_lstat64
5446 case TARGET_NR_lstat64:
5447 if (!(p = lock_user_string(arg1)))
5448 goto efault;
5449 ret = get_errno(lstat(path(p), &st));
5450 unlock_user(p, arg1, 0);
5451 if (!is_error(ret))
5452 ret = host_to_target_stat64(cpu_env, arg2, &st);
5453 break;
5454 #endif
5455 #ifdef TARGET_NR_fstat64
5456 case TARGET_NR_fstat64:
5457 ret = get_errno(fstat(arg1, &st));
5458 if (!is_error(ret))
5459 ret = host_to_target_stat64(cpu_env, arg2, &st);
5460 break;
5461 #endif
5462 #if defined(TARGET_NR_fstatat64) && defined(__NR_fstatat64)
5463 case TARGET_NR_fstatat64:
5464 if (!(p = lock_user_string(arg2)))
5465 goto efault;
5466 ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
5467 if (!is_error(ret))
5468 ret = host_to_target_stat64(cpu_env, arg3, &st);
5469 break;
5470 #endif
5471 #ifdef USE_UID16
5472 case TARGET_NR_lchown:
5473 if (!(p = lock_user_string(arg1)))
5474 goto efault;
5475 ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
5476 unlock_user(p, arg1, 0);
5477 break;
5478 case TARGET_NR_getuid:
5479 ret = get_errno(high2lowuid(getuid()));
5480 break;
5481 case TARGET_NR_getgid:
5482 ret = get_errno(high2lowgid(getgid()));
5483 break;
5484 case TARGET_NR_geteuid:
5485 ret = get_errno(high2lowuid(geteuid()));
5486 break;
5487 case TARGET_NR_getegid:
5488 ret = get_errno(high2lowgid(getegid()));
5489 break;
5490 case TARGET_NR_setreuid:
5491 ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
5492 break;
5493 case TARGET_NR_setregid:
5494 ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
5495 break;
5496 case TARGET_NR_getgroups:
5498 int gidsetsize = arg1;
5499 uint16_t *target_grouplist;
5500 gid_t *grouplist;
5501 int i;
5503 grouplist = alloca(gidsetsize * sizeof(gid_t));
5504 ret = get_errno(getgroups(gidsetsize, grouplist));
5505 if (gidsetsize == 0)
5506 break;
5507 if (!is_error(ret)) {
5508 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
5509 if (!target_grouplist)
5510 goto efault;
5511 for(i = 0;i < ret; i++)
5512 target_grouplist[i] = tswap16(grouplist[i]);
5513 unlock_user(target_grouplist, arg2, gidsetsize * 2);
5516 break;
5517 case TARGET_NR_setgroups:
5519 int gidsetsize = arg1;
5520 uint16_t *target_grouplist;
5521 gid_t *grouplist;
5522 int i;
5524 grouplist = alloca(gidsetsize * sizeof(gid_t));
5525 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
5526 if (!target_grouplist) {
5527 ret = -TARGET_EFAULT;
5528 goto fail;
5530 for(i = 0;i < gidsetsize; i++)
5531 grouplist[i] = tswap16(target_grouplist[i]);
5532 unlock_user(target_grouplist, arg2, 0);
5533 ret = get_errno(setgroups(gidsetsize, grouplist));
5535 break;
5536 case TARGET_NR_fchown:
5537 ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
5538 break;
5539 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
5540 case TARGET_NR_fchownat:
5541 if (!(p = lock_user_string(arg2)))
5542 goto efault;
5543 ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
5544 unlock_user(p, arg2, 0);
5545 break;
5546 #endif
5547 #ifdef TARGET_NR_setresuid
5548 case TARGET_NR_setresuid:
5549 ret = get_errno(setresuid(low2highuid(arg1),
5550 low2highuid(arg2),
5551 low2highuid(arg3)));
5552 break;
5553 #endif
5554 #ifdef TARGET_NR_getresuid
5555 case TARGET_NR_getresuid:
5557 uid_t ruid, euid, suid;
5558 ret = get_errno(getresuid(&ruid, &euid, &suid));
5559 if (!is_error(ret)) {
5560 if (put_user_u16(high2lowuid(ruid), arg1)
5561 || put_user_u16(high2lowuid(euid), arg2)
5562 || put_user_u16(high2lowuid(suid), arg3))
5563 goto efault;
5566 break;
5567 #endif
5568 #ifdef TARGET_NR_getresgid
5569 case TARGET_NR_setresgid:
5570 ret = get_errno(setresgid(low2highgid(arg1),
5571 low2highgid(arg2),
5572 low2highgid(arg3)));
5573 break;
5574 #endif
5575 #ifdef TARGET_NR_getresgid
5576 case TARGET_NR_getresgid:
5578 gid_t rgid, egid, sgid;
5579 ret = get_errno(getresgid(&rgid, &egid, &sgid));
5580 if (!is_error(ret)) {
5581 if (put_user_u16(high2lowgid(rgid), arg1)
5582 || put_user_u16(high2lowgid(egid), arg2)
5583 || put_user_u16(high2lowgid(sgid), arg3))
5584 goto efault;
5587 break;
5588 #endif
5589 case TARGET_NR_chown:
5590 if (!(p = lock_user_string(arg1)))
5591 goto efault;
5592 ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
5593 unlock_user(p, arg1, 0);
5594 break;
5595 case TARGET_NR_setuid:
5596 ret = get_errno(setuid(low2highuid(arg1)));
5597 break;
5598 case TARGET_NR_setgid:
5599 ret = get_errno(setgid(low2highgid(arg1)));
5600 break;
5601 case TARGET_NR_setfsuid:
5602 ret = get_errno(setfsuid(arg1));
5603 break;
5604 case TARGET_NR_setfsgid:
5605 ret = get_errno(setfsgid(arg1));
5606 break;
5607 #endif /* USE_UID16 */
5609 #ifdef TARGET_NR_lchown32
5610 case TARGET_NR_lchown32:
5611 if (!(p = lock_user_string(arg1)))
5612 goto efault;
5613 ret = get_errno(lchown(p, arg2, arg3));
5614 unlock_user(p, arg1, 0);
5615 break;
5616 #endif
5617 #ifdef TARGET_NR_getuid32
5618 case TARGET_NR_getuid32:
5619 ret = get_errno(getuid());
5620 break;
5621 #endif
5623 #if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
5624 /* Alpha specific */
5625 case TARGET_NR_getxuid:
5627 uid_t euid;
5628 euid=geteuid();
5629 ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
5631 ret = get_errno(getuid());
5632 break;
5633 #endif
5634 #if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
5635 /* Alpha specific */
5636 case TARGET_NR_getxgid:
5638 uid_t egid;
5639 egid=getegid();
5640 ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
5642 ret = get_errno(getgid());
5643 break;
5644 #endif
5646 #ifdef TARGET_NR_getgid32
5647 case TARGET_NR_getgid32:
5648 ret = get_errno(getgid());
5649 break;
5650 #endif
5651 #ifdef TARGET_NR_geteuid32
5652 case TARGET_NR_geteuid32:
5653 ret = get_errno(geteuid());
5654 break;
5655 #endif
5656 #ifdef TARGET_NR_getegid32
5657 case TARGET_NR_getegid32:
5658 ret = get_errno(getegid());
5659 break;
5660 #endif
5661 #ifdef TARGET_NR_setreuid32
5662 case TARGET_NR_setreuid32:
5663 ret = get_errno(setreuid(arg1, arg2));
5664 break;
5665 #endif
5666 #ifdef TARGET_NR_setregid32
5667 case TARGET_NR_setregid32:
5668 ret = get_errno(setregid(arg1, arg2));
5669 break;
5670 #endif
5671 #ifdef TARGET_NR_getgroups32
5672 case TARGET_NR_getgroups32:
5674 int gidsetsize = arg1;
5675 uint32_t *target_grouplist;
5676 gid_t *grouplist;
5677 int i;
5679 grouplist = alloca(gidsetsize * sizeof(gid_t));
5680 ret = get_errno(getgroups(gidsetsize, grouplist));
5681 if (gidsetsize == 0)
5682 break;
5683 if (!is_error(ret)) {
5684 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
5685 if (!target_grouplist) {
5686 ret = -TARGET_EFAULT;
5687 goto fail;
5689 for(i = 0;i < ret; i++)
5690 target_grouplist[i] = tswap32(grouplist[i]);
5691 unlock_user(target_grouplist, arg2, gidsetsize * 4);
5694 break;
5695 #endif
5696 #ifdef TARGET_NR_setgroups32
5697 case TARGET_NR_setgroups32:
5699 int gidsetsize = arg1;
5700 uint32_t *target_grouplist;
5701 gid_t *grouplist;
5702 int i;
5704 grouplist = alloca(gidsetsize * sizeof(gid_t));
5705 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
5706 if (!target_grouplist) {
5707 ret = -TARGET_EFAULT;
5708 goto fail;
5710 for(i = 0;i < gidsetsize; i++)
5711 grouplist[i] = tswap32(target_grouplist[i]);
5712 unlock_user(target_grouplist, arg2, 0);
5713 ret = get_errno(setgroups(gidsetsize, grouplist));
5715 break;
5716 #endif
5717 #ifdef TARGET_NR_fchown32
5718 case TARGET_NR_fchown32:
5719 ret = get_errno(fchown(arg1, arg2, arg3));
5720 break;
5721 #endif
5722 #ifdef TARGET_NR_setresuid32
5723 case TARGET_NR_setresuid32:
5724 ret = get_errno(setresuid(arg1, arg2, arg3));
5725 break;
5726 #endif
5727 #ifdef TARGET_NR_getresuid32
5728 case TARGET_NR_getresuid32:
5730 uid_t ruid, euid, suid;
5731 ret = get_errno(getresuid(&ruid, &euid, &suid));
5732 if (!is_error(ret)) {
5733 if (put_user_u32(ruid, arg1)
5734 || put_user_u32(euid, arg2)
5735 || put_user_u32(suid, arg3))
5736 goto efault;
5739 break;
5740 #endif
5741 #ifdef TARGET_NR_setresgid32
5742 case TARGET_NR_setresgid32:
5743 ret = get_errno(setresgid(arg1, arg2, arg3));
5744 break;
5745 #endif
5746 #ifdef TARGET_NR_getresgid32
5747 case TARGET_NR_getresgid32:
5749 gid_t rgid, egid, sgid;
5750 ret = get_errno(getresgid(&rgid, &egid, &sgid));
5751 if (!is_error(ret)) {
5752 if (put_user_u32(rgid, arg1)
5753 || put_user_u32(egid, arg2)
5754 || put_user_u32(sgid, arg3))
5755 goto efault;
5758 break;
5759 #endif
5760 #ifdef TARGET_NR_chown32
5761 case TARGET_NR_chown32:
5762 if (!(p = lock_user_string(arg1)))
5763 goto efault;
5764 ret = get_errno(chown(p, arg2, arg3));
5765 unlock_user(p, arg1, 0);
5766 break;
5767 #endif
5768 #ifdef TARGET_NR_setuid32
5769 case TARGET_NR_setuid32:
5770 ret = get_errno(setuid(arg1));
5771 break;
5772 #endif
5773 #ifdef TARGET_NR_setgid32
5774 case TARGET_NR_setgid32:
5775 ret = get_errno(setgid(arg1));
5776 break;
5777 #endif
5778 #ifdef TARGET_NR_setfsuid32
5779 case TARGET_NR_setfsuid32:
5780 ret = get_errno(setfsuid(arg1));
5781 break;
5782 #endif
5783 #ifdef TARGET_NR_setfsgid32
5784 case TARGET_NR_setfsgid32:
5785 ret = get_errno(setfsgid(arg1));
5786 break;
5787 #endif
5789 case TARGET_NR_pivot_root:
5790 goto unimplemented;
5791 #ifdef TARGET_NR_mincore
5792 case TARGET_NR_mincore:
5794 void *a;
5795 ret = -TARGET_EFAULT;
5796 if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
5797 goto efault;
5798 if (!(p = lock_user_string(arg3)))
5799 goto mincore_fail;
5800 ret = get_errno(mincore(a, arg2, p));
5801 unlock_user(p, arg3, ret);
5802 mincore_fail:
5803 unlock_user(a, arg1, 0);
5805 break;
5806 #endif
5807 #ifdef TARGET_NR_arm_fadvise64_64
5808 case TARGET_NR_arm_fadvise64_64:
5811 * arm_fadvise64_64 looks like fadvise64_64 but
5812 * with different argument order
5814 abi_long temp;
5815 temp = arg3;
5816 arg3 = arg4;
5817 arg4 = temp;
5819 #endif
5820 #if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64)
5821 #ifdef TARGET_NR_fadvise64_64
5822 case TARGET_NR_fadvise64_64:
5823 #endif
5824 /* This is a hint, so ignoring and returning success is ok. */
5825 ret = get_errno(0);
5826 break;
5827 #endif
5828 #ifdef TARGET_NR_madvise
5829 case TARGET_NR_madvise:
5830 /* A straight passthrough may not be safe because qemu sometimes
5831 turns private flie-backed mappings into anonymous mappings.
5832 This will break MADV_DONTNEED.
5833 This is a hint, so ignoring and returning success is ok. */
5834 ret = get_errno(0);
5835 break;
5836 #endif
5837 #if TARGET_ABI_BITS == 32
5838 case TARGET_NR_fcntl64:
5840 int cmd;
5841 struct flock64 fl;
5842 struct target_flock64 *target_fl;
5843 #ifdef TARGET_ARM
5844 struct target_eabi_flock64 *target_efl;
5845 #endif
5847 switch(arg2){
5848 case TARGET_F_GETLK64:
5849 cmd = F_GETLK64;
5850 break;
5851 case TARGET_F_SETLK64:
5852 cmd = F_SETLK64;
5853 break;
5854 case TARGET_F_SETLKW64:
5855 cmd = F_SETLK64;
5856 break;
5857 default:
5858 cmd = arg2;
5859 break;
5862 switch(arg2) {
5863 case TARGET_F_GETLK64:
5864 #ifdef TARGET_ARM
5865 if (((CPUARMState *)cpu_env)->eabi) {
5866 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1))
5867 goto efault;
5868 fl.l_type = tswap16(target_efl->l_type);
5869 fl.l_whence = tswap16(target_efl->l_whence);
5870 fl.l_start = tswap64(target_efl->l_start);
5871 fl.l_len = tswap64(target_efl->l_len);
5872 fl.l_pid = tswapl(target_efl->l_pid);
5873 unlock_user_struct(target_efl, arg3, 0);
5874 } else
5875 #endif
5877 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1))
5878 goto efault;
5879 fl.l_type = tswap16(target_fl->l_type);
5880 fl.l_whence = tswap16(target_fl->l_whence);
5881 fl.l_start = tswap64(target_fl->l_start);
5882 fl.l_len = tswap64(target_fl->l_len);
5883 fl.l_pid = tswapl(target_fl->l_pid);
5884 unlock_user_struct(target_fl, arg3, 0);
5886 ret = get_errno(fcntl(arg1, cmd, &fl));
5887 if (ret == 0) {
5888 #ifdef TARGET_ARM
5889 if (((CPUARMState *)cpu_env)->eabi) {
5890 if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0))
5891 goto efault;
5892 target_efl->l_type = tswap16(fl.l_type);
5893 target_efl->l_whence = tswap16(fl.l_whence);
5894 target_efl->l_start = tswap64(fl.l_start);
5895 target_efl->l_len = tswap64(fl.l_len);
5896 target_efl->l_pid = tswapl(fl.l_pid);
5897 unlock_user_struct(target_efl, arg3, 1);
5898 } else
5899 #endif
5901 if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0))
5902 goto efault;
5903 target_fl->l_type = tswap16(fl.l_type);
5904 target_fl->l_whence = tswap16(fl.l_whence);
5905 target_fl->l_start = tswap64(fl.l_start);
5906 target_fl->l_len = tswap64(fl.l_len);
5907 target_fl->l_pid = tswapl(fl.l_pid);
5908 unlock_user_struct(target_fl, arg3, 1);
5911 break;
5913 case TARGET_F_SETLK64:
5914 case TARGET_F_SETLKW64:
5915 #ifdef TARGET_ARM
5916 if (((CPUARMState *)cpu_env)->eabi) {
5917 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1))
5918 goto efault;
5919 fl.l_type = tswap16(target_efl->l_type);
5920 fl.l_whence = tswap16(target_efl->l_whence);
5921 fl.l_start = tswap64(target_efl->l_start);
5922 fl.l_len = tswap64(target_efl->l_len);
5923 fl.l_pid = tswapl(target_efl->l_pid);
5924 unlock_user_struct(target_efl, arg3, 0);
5925 } else
5926 #endif
5928 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1))
5929 goto efault;
5930 fl.l_type = tswap16(target_fl->l_type);
5931 fl.l_whence = tswap16(target_fl->l_whence);
5932 fl.l_start = tswap64(target_fl->l_start);
5933 fl.l_len = tswap64(target_fl->l_len);
5934 fl.l_pid = tswapl(target_fl->l_pid);
5935 unlock_user_struct(target_fl, arg3, 0);
5937 ret = get_errno(fcntl(arg1, cmd, &fl));
5938 break;
5939 default:
5940 ret = do_fcntl(arg1, cmd, arg3);
5941 break;
5943 break;
5945 #endif
5946 #ifdef TARGET_NR_cacheflush
5947 case TARGET_NR_cacheflush:
5948 /* self-modifying code is handled automatically, so nothing needed */
5949 ret = 0;
5950 break;
5951 #endif
5952 #ifdef TARGET_NR_security
5953 case TARGET_NR_security:
5954 goto unimplemented;
5955 #endif
5956 #ifdef TARGET_NR_getpagesize
5957 case TARGET_NR_getpagesize:
5958 ret = TARGET_PAGE_SIZE;
5959 break;
5960 #endif
5961 case TARGET_NR_gettid:
5962 ret = get_errno(gettid());
5963 break;
5964 #ifdef TARGET_NR_readahead
5965 case TARGET_NR_readahead:
5966 #if TARGET_ABI_BITS == 32
5967 #ifdef TARGET_ARM
5968 if (((CPUARMState *)cpu_env)->eabi)
5970 arg2 = arg3;
5971 arg3 = arg4;
5972 arg4 = arg5;
5974 #endif
5975 ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
5976 #else
5977 ret = get_errno(readahead(arg1, arg2, arg3));
5978 #endif
5979 break;
5980 #endif
5981 #ifdef TARGET_NR_setxattr
5982 case TARGET_NR_setxattr:
5983 case TARGET_NR_lsetxattr:
5984 case TARGET_NR_fsetxattr:
5985 case TARGET_NR_getxattr:
5986 case TARGET_NR_lgetxattr:
5987 case TARGET_NR_fgetxattr:
5988 case TARGET_NR_listxattr:
5989 case TARGET_NR_llistxattr:
5990 case TARGET_NR_flistxattr:
5991 case TARGET_NR_removexattr:
5992 case TARGET_NR_lremovexattr:
5993 case TARGET_NR_fremovexattr:
5994 goto unimplemented_nowarn;
5995 #endif
5996 #ifdef TARGET_NR_set_thread_area
5997 case TARGET_NR_set_thread_area:
5998 #if defined(TARGET_MIPS)
5999 ((CPUMIPSState *) cpu_env)->tls_value = arg1;
6000 ret = 0;
6001 break;
6002 #elif defined(TARGET_CRIS)
6003 if (arg1 & 0xff)
6004 ret = -TARGET_EINVAL;
6005 else {
6006 ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
6007 ret = 0;
6009 break;
6010 #elif defined(TARGET_I386) && defined(TARGET_ABI32)
6011 ret = do_set_thread_area(cpu_env, arg1);
6012 break;
6013 #else
6014 goto unimplemented_nowarn;
6015 #endif
6016 #endif
6017 #ifdef TARGET_NR_get_thread_area
6018 case TARGET_NR_get_thread_area:
6019 #if defined(TARGET_I386) && defined(TARGET_ABI32)
6020 ret = do_get_thread_area(cpu_env, arg1);
6021 #else
6022 goto unimplemented_nowarn;
6023 #endif
6024 #endif
6025 #ifdef TARGET_NR_getdomainname
6026 case TARGET_NR_getdomainname:
6027 goto unimplemented_nowarn;
6028 #endif
6030 #ifdef TARGET_NR_clock_gettime
6031 case TARGET_NR_clock_gettime:
6033 struct timespec ts;
6034 ret = get_errno(clock_gettime(arg1, &ts));
6035 if (!is_error(ret)) {
6036 host_to_target_timespec(arg2, &ts);
6038 break;
6040 #endif
6041 #ifdef TARGET_NR_clock_getres
6042 case TARGET_NR_clock_getres:
6044 struct timespec ts;
6045 ret = get_errno(clock_getres(arg1, &ts));
6046 if (!is_error(ret)) {
6047 host_to_target_timespec(arg2, &ts);
6049 break;
6051 #endif
6052 #ifdef TARGET_NR_clock_nanosleep
6053 case TARGET_NR_clock_nanosleep:
6055 struct timespec ts;
6056 target_to_host_timespec(&ts, arg3);
6057 ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
6058 if (arg4)
6059 host_to_target_timespec(arg4, &ts);
6060 break;
6062 #endif
6064 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
6065 case TARGET_NR_set_tid_address:
6066 ret = get_errno(set_tid_address((int *)g2h(arg1)));
6067 break;
6068 #endif
6070 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
6071 case TARGET_NR_tkill:
6072 ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
6073 break;
6074 #endif
6076 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
6077 case TARGET_NR_tgkill:
6078 ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
6079 target_to_host_signal(arg3)));
6080 break;
6081 #endif
6083 #ifdef TARGET_NR_set_robust_list
6084 case TARGET_NR_set_robust_list:
6085 goto unimplemented_nowarn;
6086 #endif
6088 #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
6089 case TARGET_NR_utimensat:
6091 struct timespec ts[2];
6092 target_to_host_timespec(ts, arg3);
6093 target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
6094 if (!arg2)
6095 ret = get_errno(sys_utimensat(arg1, NULL, ts, arg4));
6096 else {
6097 if (!(p = lock_user_string(arg2))) {
6098 ret = -TARGET_EFAULT;
6099 goto fail;
6101 ret = get_errno(sys_utimensat(arg1, path(p), ts, arg4));
6102 unlock_user(p, arg2, 0);
6105 break;
6106 #endif
6107 #if defined(USE_NPTL)
6108 case TARGET_NR_futex:
6109 ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
6110 break;
6111 #endif
6112 #ifdef TARGET_NR_inotify_init
6113 case TARGET_NR_inotify_init:
6114 ret = get_errno(sys_inotify_init());
6115 break;
6116 #endif
6117 #ifdef TARGET_NR_inotify_add_watch
6118 case TARGET_NR_inotify_add_watch:
6119 p = lock_user_string(arg2);
6120 ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
6121 unlock_user(p, arg2, 0);
6122 break;
6123 #endif
6124 #ifdef TARGET_NR_inotify_rm_watch
6125 case TARGET_NR_inotify_rm_watch:
6126 ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
6127 break;
6128 #endif
6130 default:
6131 unimplemented:
6132 gemu_log("qemu: Unsupported syscall: %d\n", num);
6133 #if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
6134 unimplemented_nowarn:
6135 #endif
6136 ret = -TARGET_ENOSYS;
6137 break;
6139 fail:
6140 #ifdef DEBUG
6141 gemu_log(" = %ld\n", ret);
6142 #endif
6143 if(do_strace)
6144 print_syscall_ret(num, ret);
6145 return ret;
6146 efault:
6147 ret = -TARGET_EFAULT;
6148 goto fail;