Fix iovec for the case with invalid elements (Lauro Ramos Venancio).
[qemu/sh4.git] / linux-user / syscall.c
blob06d1597650d0ef2d03f0661461052cb9973cbf76
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., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <stdarg.h>
23 #include <string.h>
24 #include <elf.h>
25 #include <endian.h>
26 #include <errno.h>
27 #include <unistd.h>
28 #include <fcntl.h>
29 #include <time.h>
30 #include <limits.h>
31 #include <sys/types.h>
32 #include <sys/ipc.h>
33 #include <sys/msg.h>
34 #include <sys/wait.h>
35 #include <sys/time.h>
36 #include <sys/stat.h>
37 #include <sys/mount.h>
38 #include <sys/prctl.h>
39 #include <sys/resource.h>
40 #include <sys/mman.h>
41 #include <sys/swap.h>
42 #include <signal.h>
43 #include <sched.h>
44 #include <sys/socket.h>
45 #include <sys/uio.h>
46 #include <sys/poll.h>
47 #include <sys/times.h>
48 #include <sys/shm.h>
49 #include <sys/sem.h>
50 #include <sys/statfs.h>
51 #include <utime.h>
52 #include <sys/sysinfo.h>
53 //#include <sys/user.h>
54 #include <netinet/ip.h>
55 #include <netinet/tcp.h>
56 #include <qemu-common.h>
58 #define termios host_termios
59 #define winsize host_winsize
60 #define termio host_termio
61 #define sgttyb host_sgttyb /* same as target */
62 #define tchars host_tchars /* same as target */
63 #define ltchars host_ltchars /* same as target */
65 #include <linux/termios.h>
66 #include <linux/unistd.h>
67 #include <linux/utsname.h>
68 #include <linux/cdrom.h>
69 #include <linux/hdreg.h>
70 #include <linux/soundcard.h>
71 #include <linux/kd.h>
72 #include <linux/mtio.h>
73 #include "linux_loop.h"
75 #include "qemu.h"
76 #include "qemu-common.h"
78 #if defined(USE_NPTL)
79 #include <linux/futex.h>
80 #define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
81 CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
82 #else
83 /* XXX: Hardcode the above values. */
84 #define CLONE_NPTL_FLAGS2 0
85 #endif
87 //#define DEBUG
89 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \
90 || defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS)
91 /* 16 bit uid wrappers emulation */
92 #define USE_UID16
93 #endif
95 //#include <linux/msdos_fs.h>
96 #define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct linux_dirent [2])
97 #define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct linux_dirent [2])
100 #undef _syscall0
101 #undef _syscall1
102 #undef _syscall2
103 #undef _syscall3
104 #undef _syscall4
105 #undef _syscall5
106 #undef _syscall6
108 #define _syscall0(type,name) \
109 static type name (void) \
111 return syscall(__NR_##name); \
114 #define _syscall1(type,name,type1,arg1) \
115 static type name (type1 arg1) \
117 return syscall(__NR_##name, arg1); \
120 #define _syscall2(type,name,type1,arg1,type2,arg2) \
121 static type name (type1 arg1,type2 arg2) \
123 return syscall(__NR_##name, arg1, arg2); \
126 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
127 static type name (type1 arg1,type2 arg2,type3 arg3) \
129 return syscall(__NR_##name, arg1, arg2, arg3); \
132 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
133 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4) \
135 return syscall(__NR_##name, arg1, arg2, arg3, arg4); \
138 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
139 type5,arg5) \
140 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
142 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5); \
146 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
147 type5,arg5,type6,arg6) \
148 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \
149 type6 arg6) \
151 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6); \
155 #define __NR_sys_exit __NR_exit
156 #define __NR_sys_uname __NR_uname
157 #define __NR_sys_faccessat __NR_faccessat
158 #define __NR_sys_fchmodat __NR_fchmodat
159 #define __NR_sys_fchownat __NR_fchownat
160 #define __NR_sys_fstatat64 __NR_fstatat64
161 #define __NR_sys_futimesat __NR_futimesat
162 #define __NR_sys_getcwd1 __NR_getcwd
163 #define __NR_sys_getdents __NR_getdents
164 #define __NR_sys_getdents64 __NR_getdents64
165 #define __NR_sys_getpriority __NR_getpriority
166 #define __NR_sys_linkat __NR_linkat
167 #define __NR_sys_mkdirat __NR_mkdirat
168 #define __NR_sys_mknodat __NR_mknodat
169 #define __NR_sys_openat __NR_openat
170 #define __NR_sys_readlinkat __NR_readlinkat
171 #define __NR_sys_renameat __NR_renameat
172 #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
173 #define __NR_sys_symlinkat __NR_symlinkat
174 #define __NR_sys_syslog __NR_syslog
175 #define __NR_sys_tgkill __NR_tgkill
176 #define __NR_sys_tkill __NR_tkill
177 #define __NR_sys_unlinkat __NR_unlinkat
178 #define __NR_sys_utimensat __NR_utimensat
179 #define __NR_sys_futex __NR_futex
180 #define __NR_sys_inotify_init __NR_inotify_init
181 #define __NR_sys_inotify_add_watch __NR_inotify_add_watch
182 #define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
184 #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
185 #define __NR__llseek __NR_lseek
186 #endif
188 #ifdef __NR_gettid
189 _syscall0(int, gettid)
190 #else
191 /* This is a replacement for the host gettid() and must return a host
192 errno. */
193 static int gettid(void) {
194 return -ENOSYS;
196 #endif
197 _syscall1(int,sys_exit,int,status)
198 _syscall1(int,sys_uname,struct new_utsname *,buf)
199 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
200 _syscall4(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode,int,flags)
201 #endif
202 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
203 _syscall4(int,sys_fchmodat,int,dirfd,const char *,pathname,
204 mode_t,mode,int,flags)
205 #endif
206 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) && defined(USE_UID16)
207 _syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
208 uid_t,owner,gid_t,group,int,flags)
209 #endif
210 #if defined(TARGET_NR_fstatat64) && defined(__NR_fstatat64)
211 _syscall4(int,sys_fstatat64,int,dirfd,const char *,pathname,
212 struct stat *,buf,int,flags)
213 #endif
214 #if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
215 _syscall3(int,sys_futimesat,int,dirfd,const char *,pathname,
216 const struct timeval *,times)
217 #endif
218 _syscall2(int,sys_getcwd1,char *,buf,size_t,size)
219 #if TARGET_ABI_BITS == 32
220 _syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
221 #endif
222 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
223 _syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
224 #endif
225 _syscall2(int, sys_getpriority, int, which, int, who);
226 #if !defined (__x86_64__)
227 _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo,
228 loff_t *, res, uint, wh);
229 #endif
230 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
231 _syscall5(int,sys_linkat,int,olddirfd,const char *,oldpath,
232 int,newdirfd,const char *,newpath,int,flags)
233 #endif
234 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
235 _syscall3(int,sys_mkdirat,int,dirfd,const char *,pathname,mode_t,mode)
236 #endif
237 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
238 _syscall4(int,sys_mknodat,int,dirfd,const char *,pathname,
239 mode_t,mode,dev_t,dev)
240 #endif
241 #if defined(TARGET_NR_openat) && defined(__NR_openat)
242 _syscall4(int,sys_openat,int,dirfd,const char *,pathname,int,flags,mode_t,mode)
243 #endif
244 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
245 _syscall4(int,sys_readlinkat,int,dirfd,const char *,pathname,
246 char *,buf,size_t,bufsize)
247 #endif
248 #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
249 _syscall4(int,sys_renameat,int,olddirfd,const char *,oldpath,
250 int,newdirfd,const char *,newpath)
251 #endif
252 _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
253 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
254 _syscall3(int,sys_symlinkat,const char *,oldpath,
255 int,newdirfd,const char *,newpath)
256 #endif
257 _syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
258 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
259 _syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
260 #endif
261 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
262 _syscall2(int,sys_tkill,int,tid,int,sig)
263 #endif
264 #ifdef __NR_exit_group
265 _syscall1(int,exit_group,int,error_code)
266 #endif
267 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
268 _syscall1(int,set_tid_address,int *,tidptr)
269 #endif
270 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
271 _syscall3(int,sys_unlinkat,int,dirfd,const char *,pathname,int,flags)
272 #endif
273 #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
274 _syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
275 const struct timespec *,tsp,int,flags)
276 #endif
277 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
278 _syscall0(int,sys_inotify_init)
279 #endif
280 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
281 _syscall3(int,sys_inotify_add_watch,int,fd,const char *,pathname,uint32_t,mask)
282 #endif
283 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
284 _syscall2(int,sys_inotify_rm_watch,int,fd,uint32_t,wd)
285 #endif
286 #if defined(USE_NPTL)
287 #if defined(TARGET_NR_futex) && defined(__NR_futex)
288 _syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
289 const struct timespec *,timeout,int *,uaddr2,int,val3)
290 #endif
291 #endif
293 extern int personality(int);
294 extern int flock(int, int);
295 extern int setfsuid(int);
296 extern int setfsgid(int);
297 extern int setgroups(int, gid_t *);
299 #define ERRNO_TABLE_SIZE 1200
301 /* target_to_host_errno_table[] is initialized from
302 * host_to_target_errno_table[] in syscall_init(). */
303 static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
307 * This list is the union of errno values overridden in asm-<arch>/errno.h
308 * minus the errnos that are not actually generic to all archs.
310 static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
311 [EIDRM] = TARGET_EIDRM,
312 [ECHRNG] = TARGET_ECHRNG,
313 [EL2NSYNC] = TARGET_EL2NSYNC,
314 [EL3HLT] = TARGET_EL3HLT,
315 [EL3RST] = TARGET_EL3RST,
316 [ELNRNG] = TARGET_ELNRNG,
317 [EUNATCH] = TARGET_EUNATCH,
318 [ENOCSI] = TARGET_ENOCSI,
319 [EL2HLT] = TARGET_EL2HLT,
320 [EDEADLK] = TARGET_EDEADLK,
321 [ENOLCK] = TARGET_ENOLCK,
322 [EBADE] = TARGET_EBADE,
323 [EBADR] = TARGET_EBADR,
324 [EXFULL] = TARGET_EXFULL,
325 [ENOANO] = TARGET_ENOANO,
326 [EBADRQC] = TARGET_EBADRQC,
327 [EBADSLT] = TARGET_EBADSLT,
328 [EBFONT] = TARGET_EBFONT,
329 [ENOSTR] = TARGET_ENOSTR,
330 [ENODATA] = TARGET_ENODATA,
331 [ETIME] = TARGET_ETIME,
332 [ENOSR] = TARGET_ENOSR,
333 [ENONET] = TARGET_ENONET,
334 [ENOPKG] = TARGET_ENOPKG,
335 [EREMOTE] = TARGET_EREMOTE,
336 [ENOLINK] = TARGET_ENOLINK,
337 [EADV] = TARGET_EADV,
338 [ESRMNT] = TARGET_ESRMNT,
339 [ECOMM] = TARGET_ECOMM,
340 [EPROTO] = TARGET_EPROTO,
341 [EDOTDOT] = TARGET_EDOTDOT,
342 [EMULTIHOP] = TARGET_EMULTIHOP,
343 [EBADMSG] = TARGET_EBADMSG,
344 [ENAMETOOLONG] = TARGET_ENAMETOOLONG,
345 [EOVERFLOW] = TARGET_EOVERFLOW,
346 [ENOTUNIQ] = TARGET_ENOTUNIQ,
347 [EBADFD] = TARGET_EBADFD,
348 [EREMCHG] = TARGET_EREMCHG,
349 [ELIBACC] = TARGET_ELIBACC,
350 [ELIBBAD] = TARGET_ELIBBAD,
351 [ELIBSCN] = TARGET_ELIBSCN,
352 [ELIBMAX] = TARGET_ELIBMAX,
353 [ELIBEXEC] = TARGET_ELIBEXEC,
354 [EILSEQ] = TARGET_EILSEQ,
355 [ENOSYS] = TARGET_ENOSYS,
356 [ELOOP] = TARGET_ELOOP,
357 [ERESTART] = TARGET_ERESTART,
358 [ESTRPIPE] = TARGET_ESTRPIPE,
359 [ENOTEMPTY] = TARGET_ENOTEMPTY,
360 [EUSERS] = TARGET_EUSERS,
361 [ENOTSOCK] = TARGET_ENOTSOCK,
362 [EDESTADDRREQ] = TARGET_EDESTADDRREQ,
363 [EMSGSIZE] = TARGET_EMSGSIZE,
364 [EPROTOTYPE] = TARGET_EPROTOTYPE,
365 [ENOPROTOOPT] = TARGET_ENOPROTOOPT,
366 [EPROTONOSUPPORT] = TARGET_EPROTONOSUPPORT,
367 [ESOCKTNOSUPPORT] = TARGET_ESOCKTNOSUPPORT,
368 [EOPNOTSUPP] = TARGET_EOPNOTSUPP,
369 [EPFNOSUPPORT] = TARGET_EPFNOSUPPORT,
370 [EAFNOSUPPORT] = TARGET_EAFNOSUPPORT,
371 [EADDRINUSE] = TARGET_EADDRINUSE,
372 [EADDRNOTAVAIL] = TARGET_EADDRNOTAVAIL,
373 [ENETDOWN] = TARGET_ENETDOWN,
374 [ENETUNREACH] = TARGET_ENETUNREACH,
375 [ENETRESET] = TARGET_ENETRESET,
376 [ECONNABORTED] = TARGET_ECONNABORTED,
377 [ECONNRESET] = TARGET_ECONNRESET,
378 [ENOBUFS] = TARGET_ENOBUFS,
379 [EISCONN] = TARGET_EISCONN,
380 [ENOTCONN] = TARGET_ENOTCONN,
381 [EUCLEAN] = TARGET_EUCLEAN,
382 [ENOTNAM] = TARGET_ENOTNAM,
383 [ENAVAIL] = TARGET_ENAVAIL,
384 [EISNAM] = TARGET_EISNAM,
385 [EREMOTEIO] = TARGET_EREMOTEIO,
386 [ESHUTDOWN] = TARGET_ESHUTDOWN,
387 [ETOOMANYREFS] = TARGET_ETOOMANYREFS,
388 [ETIMEDOUT] = TARGET_ETIMEDOUT,
389 [ECONNREFUSED] = TARGET_ECONNREFUSED,
390 [EHOSTDOWN] = TARGET_EHOSTDOWN,
391 [EHOSTUNREACH] = TARGET_EHOSTUNREACH,
392 [EALREADY] = TARGET_EALREADY,
393 [EINPROGRESS] = TARGET_EINPROGRESS,
394 [ESTALE] = TARGET_ESTALE,
395 [ECANCELED] = TARGET_ECANCELED,
396 [ENOMEDIUM] = TARGET_ENOMEDIUM,
397 [EMEDIUMTYPE] = TARGET_EMEDIUMTYPE,
398 #ifdef ENOKEY
399 [ENOKEY] = TARGET_ENOKEY,
400 #endif
401 #ifdef EKEYEXPIRED
402 [EKEYEXPIRED] = TARGET_EKEYEXPIRED,
403 #endif
404 #ifdef EKEYREVOKED
405 [EKEYREVOKED] = TARGET_EKEYREVOKED,
406 #endif
407 #ifdef EKEYREJECTED
408 [EKEYREJECTED] = TARGET_EKEYREJECTED,
409 #endif
410 #ifdef EOWNERDEAD
411 [EOWNERDEAD] = TARGET_EOWNERDEAD,
412 #endif
413 #ifdef ENOTRECOVERABLE
414 [ENOTRECOVERABLE] = TARGET_ENOTRECOVERABLE,
415 #endif
418 static inline int host_to_target_errno(int err)
420 if(host_to_target_errno_table[err])
421 return host_to_target_errno_table[err];
422 return err;
425 static inline int target_to_host_errno(int err)
427 if (target_to_host_errno_table[err])
428 return target_to_host_errno_table[err];
429 return err;
432 static inline abi_long get_errno(abi_long ret)
434 if (ret == -1)
435 return -host_to_target_errno(errno);
436 else
437 return ret;
440 static inline int is_error(abi_long ret)
442 return (abi_ulong)ret >= (abi_ulong)(-4096);
445 char *target_strerror(int err)
447 return strerror(target_to_host_errno(err));
450 static abi_ulong target_brk;
451 static abi_ulong target_original_brk;
453 void target_set_brk(abi_ulong new_brk)
455 target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
458 /* do_brk() must return target values and target errnos. */
459 abi_long do_brk(abi_ulong new_brk)
461 abi_ulong brk_page;
462 abi_long mapped_addr;
463 int new_alloc_size;
465 if (!new_brk)
466 return target_brk;
467 if (new_brk < target_original_brk)
468 return target_brk;
470 brk_page = HOST_PAGE_ALIGN(target_brk);
472 /* If the new brk is less than this, set it and we're done... */
473 if (new_brk < brk_page) {
474 target_brk = new_brk;
475 return target_brk;
478 /* We need to allocate more memory after the brk... */
479 new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
480 mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
481 PROT_READ|PROT_WRITE,
482 MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
484 if (!is_error(mapped_addr))
485 target_brk = new_brk;
487 return target_brk;
490 static inline abi_long copy_from_user_fdset(fd_set *fds,
491 abi_ulong target_fds_addr,
492 int n)
494 int i, nw, j, k;
495 abi_ulong b, *target_fds;
497 nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
498 if (!(target_fds = lock_user(VERIFY_READ,
499 target_fds_addr,
500 sizeof(abi_ulong) * nw,
501 1)))
502 return -TARGET_EFAULT;
504 FD_ZERO(fds);
505 k = 0;
506 for (i = 0; i < nw; i++) {
507 /* grab the abi_ulong */
508 __get_user(b, &target_fds[i]);
509 for (j = 0; j < TARGET_ABI_BITS; j++) {
510 /* check the bit inside the abi_ulong */
511 if ((b >> j) & 1)
512 FD_SET(k, fds);
513 k++;
517 unlock_user(target_fds, target_fds_addr, 0);
519 return 0;
522 static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
523 const fd_set *fds,
524 int n)
526 int i, nw, j, k;
527 abi_long v;
528 abi_ulong *target_fds;
530 nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
531 if (!(target_fds = lock_user(VERIFY_WRITE,
532 target_fds_addr,
533 sizeof(abi_ulong) * nw,
534 0)))
535 return -TARGET_EFAULT;
537 k = 0;
538 for (i = 0; i < nw; i++) {
539 v = 0;
540 for (j = 0; j < TARGET_ABI_BITS; j++) {
541 v |= ((FD_ISSET(k, fds) != 0) << j);
542 k++;
544 __put_user(v, &target_fds[i]);
547 unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
549 return 0;
552 #if defined(__alpha__)
553 #define HOST_HZ 1024
554 #else
555 #define HOST_HZ 100
556 #endif
558 static inline abi_long host_to_target_clock_t(long ticks)
560 #if HOST_HZ == TARGET_HZ
561 return ticks;
562 #else
563 return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
564 #endif
567 static inline abi_long host_to_target_rusage(abi_ulong target_addr,
568 const struct rusage *rusage)
570 struct target_rusage *target_rusage;
572 if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
573 return -TARGET_EFAULT;
574 target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
575 target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
576 target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
577 target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec);
578 target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss);
579 target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss);
580 target_rusage->ru_idrss = tswapl(rusage->ru_idrss);
581 target_rusage->ru_isrss = tswapl(rusage->ru_isrss);
582 target_rusage->ru_minflt = tswapl(rusage->ru_minflt);
583 target_rusage->ru_majflt = tswapl(rusage->ru_majflt);
584 target_rusage->ru_nswap = tswapl(rusage->ru_nswap);
585 target_rusage->ru_inblock = tswapl(rusage->ru_inblock);
586 target_rusage->ru_oublock = tswapl(rusage->ru_oublock);
587 target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd);
588 target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv);
589 target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);
590 target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
591 target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
592 unlock_user_struct(target_rusage, target_addr, 1);
594 return 0;
597 static inline abi_long copy_from_user_timeval(struct timeval *tv,
598 abi_ulong target_tv_addr)
600 struct target_timeval *target_tv;
602 if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
603 return -TARGET_EFAULT;
605 __get_user(tv->tv_sec, &target_tv->tv_sec);
606 __get_user(tv->tv_usec, &target_tv->tv_usec);
608 unlock_user_struct(target_tv, target_tv_addr, 0);
610 return 0;
613 static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
614 const struct timeval *tv)
616 struct target_timeval *target_tv;
618 if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
619 return -TARGET_EFAULT;
621 __put_user(tv->tv_sec, &target_tv->tv_sec);
622 __put_user(tv->tv_usec, &target_tv->tv_usec);
624 unlock_user_struct(target_tv, target_tv_addr, 1);
626 return 0;
630 /* do_select() must return target values and target errnos. */
631 static abi_long do_select(int n,
632 abi_ulong rfd_addr, abi_ulong wfd_addr,
633 abi_ulong efd_addr, abi_ulong target_tv_addr)
635 fd_set rfds, wfds, efds;
636 fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
637 struct timeval tv, *tv_ptr;
638 abi_long ret;
640 if (rfd_addr) {
641 if (copy_from_user_fdset(&rfds, rfd_addr, n))
642 return -TARGET_EFAULT;
643 rfds_ptr = &rfds;
644 } else {
645 rfds_ptr = NULL;
647 if (wfd_addr) {
648 if (copy_from_user_fdset(&wfds, wfd_addr, n))
649 return -TARGET_EFAULT;
650 wfds_ptr = &wfds;
651 } else {
652 wfds_ptr = NULL;
654 if (efd_addr) {
655 if (copy_from_user_fdset(&efds, efd_addr, n))
656 return -TARGET_EFAULT;
657 efds_ptr = &efds;
658 } else {
659 efds_ptr = NULL;
662 if (target_tv_addr) {
663 if (copy_from_user_timeval(&tv, target_tv_addr))
664 return -TARGET_EFAULT;
665 tv_ptr = &tv;
666 } else {
667 tv_ptr = NULL;
670 ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
672 if (!is_error(ret)) {
673 if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
674 return -TARGET_EFAULT;
675 if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
676 return -TARGET_EFAULT;
677 if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
678 return -TARGET_EFAULT;
680 if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
681 return -TARGET_EFAULT;
684 return ret;
687 static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
688 abi_ulong target_addr,
689 socklen_t len)
691 struct target_sockaddr *target_saddr;
693 target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
694 if (!target_saddr)
695 return -TARGET_EFAULT;
696 memcpy(addr, target_saddr, len);
697 addr->sa_family = tswap16(target_saddr->sa_family);
698 unlock_user(target_saddr, target_addr, 0);
700 return 0;
703 static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
704 struct sockaddr *addr,
705 socklen_t len)
707 struct target_sockaddr *target_saddr;
709 target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
710 if (!target_saddr)
711 return -TARGET_EFAULT;
712 memcpy(target_saddr, addr, len);
713 target_saddr->sa_family = tswap16(addr->sa_family);
714 unlock_user(target_saddr, target_addr, len);
716 return 0;
719 /* ??? Should this also swap msgh->name? */
720 static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
721 struct target_msghdr *target_msgh)
723 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
724 abi_long msg_controllen;
725 abi_ulong target_cmsg_addr;
726 struct target_cmsghdr *target_cmsg;
727 socklen_t space = 0;
729 msg_controllen = tswapl(target_msgh->msg_controllen);
730 if (msg_controllen < sizeof (struct target_cmsghdr))
731 goto the_end;
732 target_cmsg_addr = tswapl(target_msgh->msg_control);
733 target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
734 if (!target_cmsg)
735 return -TARGET_EFAULT;
737 while (cmsg && target_cmsg) {
738 void *data = CMSG_DATA(cmsg);
739 void *target_data = TARGET_CMSG_DATA(target_cmsg);
741 int len = tswapl(target_cmsg->cmsg_len)
742 - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
744 space += CMSG_SPACE(len);
745 if (space > msgh->msg_controllen) {
746 space -= CMSG_SPACE(len);
747 gemu_log("Host cmsg overflow\n");
748 break;
751 cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
752 cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
753 cmsg->cmsg_len = CMSG_LEN(len);
755 if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
756 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
757 memcpy(data, target_data, len);
758 } else {
759 int *fd = (int *)data;
760 int *target_fd = (int *)target_data;
761 int i, numfds = len / sizeof(int);
763 for (i = 0; i < numfds; i++)
764 fd[i] = tswap32(target_fd[i]);
767 cmsg = CMSG_NXTHDR(msgh, cmsg);
768 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
770 unlock_user(target_cmsg, target_cmsg_addr, 0);
771 the_end:
772 msgh->msg_controllen = space;
773 return 0;
776 /* ??? Should this also swap msgh->name? */
777 static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
778 struct msghdr *msgh)
780 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
781 abi_long msg_controllen;
782 abi_ulong target_cmsg_addr;
783 struct target_cmsghdr *target_cmsg;
784 socklen_t space = 0;
786 msg_controllen = tswapl(target_msgh->msg_controllen);
787 if (msg_controllen < sizeof (struct target_cmsghdr))
788 goto the_end;
789 target_cmsg_addr = tswapl(target_msgh->msg_control);
790 target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
791 if (!target_cmsg)
792 return -TARGET_EFAULT;
794 while (cmsg && target_cmsg) {
795 void *data = CMSG_DATA(cmsg);
796 void *target_data = TARGET_CMSG_DATA(target_cmsg);
798 int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
800 space += TARGET_CMSG_SPACE(len);
801 if (space > msg_controllen) {
802 space -= TARGET_CMSG_SPACE(len);
803 gemu_log("Target cmsg overflow\n");
804 break;
807 target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
808 target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
809 target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
811 if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
812 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
813 memcpy(target_data, data, len);
814 } else {
815 int *fd = (int *)data;
816 int *target_fd = (int *)target_data;
817 int i, numfds = len / sizeof(int);
819 for (i = 0; i < numfds; i++)
820 target_fd[i] = tswap32(fd[i]);
823 cmsg = CMSG_NXTHDR(msgh, cmsg);
824 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
826 unlock_user(target_cmsg, target_cmsg_addr, space);
827 the_end:
828 target_msgh->msg_controllen = tswapl(space);
829 return 0;
832 /* do_setsockopt() Must return target values and target errnos. */
833 static abi_long do_setsockopt(int sockfd, int level, int optname,
834 abi_ulong optval_addr, socklen_t optlen)
836 abi_long ret;
837 int val;
839 switch(level) {
840 case SOL_TCP:
841 /* TCP options all take an 'int' value. */
842 if (optlen < sizeof(uint32_t))
843 return -TARGET_EINVAL;
845 if (get_user_u32(val, optval_addr))
846 return -TARGET_EFAULT;
847 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
848 break;
849 case SOL_IP:
850 switch(optname) {
851 case IP_TOS:
852 case IP_TTL:
853 case IP_HDRINCL:
854 case IP_ROUTER_ALERT:
855 case IP_RECVOPTS:
856 case IP_RETOPTS:
857 case IP_PKTINFO:
858 case IP_MTU_DISCOVER:
859 case IP_RECVERR:
860 case IP_RECVTOS:
861 #ifdef IP_FREEBIND
862 case IP_FREEBIND:
863 #endif
864 case IP_MULTICAST_TTL:
865 case IP_MULTICAST_LOOP:
866 val = 0;
867 if (optlen >= sizeof(uint32_t)) {
868 if (get_user_u32(val, optval_addr))
869 return -TARGET_EFAULT;
870 } else if (optlen >= 1) {
871 if (get_user_u8(val, optval_addr))
872 return -TARGET_EFAULT;
874 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
875 break;
876 default:
877 goto unimplemented;
879 break;
880 case TARGET_SOL_SOCKET:
881 switch (optname) {
882 /* Options with 'int' argument. */
883 case TARGET_SO_DEBUG:
884 optname = SO_DEBUG;
885 break;
886 case TARGET_SO_REUSEADDR:
887 optname = SO_REUSEADDR;
888 break;
889 case TARGET_SO_TYPE:
890 optname = SO_TYPE;
891 break;
892 case TARGET_SO_ERROR:
893 optname = SO_ERROR;
894 break;
895 case TARGET_SO_DONTROUTE:
896 optname = SO_DONTROUTE;
897 break;
898 case TARGET_SO_BROADCAST:
899 optname = SO_BROADCAST;
900 break;
901 case TARGET_SO_SNDBUF:
902 optname = SO_SNDBUF;
903 break;
904 case TARGET_SO_RCVBUF:
905 optname = SO_RCVBUF;
906 break;
907 case TARGET_SO_KEEPALIVE:
908 optname = SO_KEEPALIVE;
909 break;
910 case TARGET_SO_OOBINLINE:
911 optname = SO_OOBINLINE;
912 break;
913 case TARGET_SO_NO_CHECK:
914 optname = SO_NO_CHECK;
915 break;
916 case TARGET_SO_PRIORITY:
917 optname = SO_PRIORITY;
918 break;
919 #ifdef SO_BSDCOMPAT
920 case TARGET_SO_BSDCOMPAT:
921 optname = SO_BSDCOMPAT;
922 break;
923 #endif
924 case TARGET_SO_PASSCRED:
925 optname = SO_PASSCRED;
926 break;
927 case TARGET_SO_TIMESTAMP:
928 optname = SO_TIMESTAMP;
929 break;
930 case TARGET_SO_RCVLOWAT:
931 optname = SO_RCVLOWAT;
932 break;
933 case TARGET_SO_RCVTIMEO:
934 optname = SO_RCVTIMEO;
935 break;
936 case TARGET_SO_SNDTIMEO:
937 optname = SO_SNDTIMEO;
938 break;
939 break;
940 default:
941 goto unimplemented;
943 if (optlen < sizeof(uint32_t))
944 return -TARGET_EINVAL;
946 if (get_user_u32(val, optval_addr))
947 return -TARGET_EFAULT;
948 ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
949 break;
950 default:
951 unimplemented:
952 gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
953 ret = -TARGET_ENOPROTOOPT;
955 return ret;
958 /* do_getsockopt() Must return target values and target errnos. */
959 static abi_long do_getsockopt(int sockfd, int level, int optname,
960 abi_ulong optval_addr, abi_ulong optlen)
962 abi_long ret;
963 int len, val;
964 socklen_t lv;
966 switch(level) {
967 case TARGET_SOL_SOCKET:
968 level = SOL_SOCKET;
969 switch (optname) {
970 case TARGET_SO_LINGER:
971 case TARGET_SO_RCVTIMEO:
972 case TARGET_SO_SNDTIMEO:
973 case TARGET_SO_PEERCRED:
974 case TARGET_SO_PEERNAME:
975 /* These don't just return a single integer */
976 goto unimplemented;
977 default:
978 goto int_case;
980 break;
981 case SOL_TCP:
982 /* TCP options all take an 'int' value. */
983 int_case:
984 if (get_user_u32(len, optlen))
985 return -TARGET_EFAULT;
986 if (len < 0)
987 return -TARGET_EINVAL;
988 lv = sizeof(int);
989 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
990 if (ret < 0)
991 return ret;
992 val = tswap32(val);
993 if (len > lv)
994 len = lv;
995 if (len == 4) {
996 if (put_user_u32(val, optval_addr))
997 return -TARGET_EFAULT;
998 } else {
999 if (put_user_u8(val, optval_addr))
1000 return -TARGET_EFAULT;
1002 if (put_user_u32(len, optlen))
1003 return -TARGET_EFAULT;
1004 break;
1005 case SOL_IP:
1006 switch(optname) {
1007 case IP_TOS:
1008 case IP_TTL:
1009 case IP_HDRINCL:
1010 case IP_ROUTER_ALERT:
1011 case IP_RECVOPTS:
1012 case IP_RETOPTS:
1013 case IP_PKTINFO:
1014 case IP_MTU_DISCOVER:
1015 case IP_RECVERR:
1016 case IP_RECVTOS:
1017 #ifdef IP_FREEBIND
1018 case IP_FREEBIND:
1019 #endif
1020 case IP_MULTICAST_TTL:
1021 case IP_MULTICAST_LOOP:
1022 if (get_user_u32(len, optlen))
1023 return -TARGET_EFAULT;
1024 if (len < 0)
1025 return -TARGET_EINVAL;
1026 lv = sizeof(int);
1027 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1028 if (ret < 0)
1029 return ret;
1030 if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
1031 len = 1;
1032 if (put_user_u32(len, optlen)
1033 || put_user_u8(val, optval_addr))
1034 return -TARGET_EFAULT;
1035 } else {
1036 if (len > sizeof(int))
1037 len = sizeof(int);
1038 if (put_user_u32(len, optlen)
1039 || put_user_u32(val, optval_addr))
1040 return -TARGET_EFAULT;
1042 break;
1043 default:
1044 ret = -TARGET_ENOPROTOOPT;
1045 break;
1047 break;
1048 default:
1049 unimplemented:
1050 gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1051 level, optname);
1052 ret = -TARGET_EOPNOTSUPP;
1053 break;
1055 return ret;
1058 /* FIXME
1059 * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1060 * other lock functions have a return code of 0 for failure.
1062 static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1063 int count, int copy)
1065 struct target_iovec *target_vec;
1066 abi_ulong base;
1067 int i;
1069 target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1070 if (!target_vec)
1071 return -TARGET_EFAULT;
1072 for(i = 0;i < count; i++) {
1073 base = tswapl(target_vec[i].iov_base);
1074 vec[i].iov_len = tswapl(target_vec[i].iov_len);
1075 if (vec[i].iov_len != 0) {
1076 vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
1077 /* Don't check lock_user return value. We must call writev even
1078 if a element has invalid base address. */
1079 } else {
1080 /* zero length pointer is ignored */
1081 vec[i].iov_base = NULL;
1084 unlock_user (target_vec, target_addr, 0);
1085 return 0;
1088 static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1089 int count, int copy)
1091 struct target_iovec *target_vec;
1092 abi_ulong base;
1093 int i;
1095 target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1096 if (!target_vec)
1097 return -TARGET_EFAULT;
1098 for(i = 0;i < count; i++) {
1099 if (target_vec[i].iov_base) {
1100 base = tswapl(target_vec[i].iov_base);
1101 unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1104 unlock_user (target_vec, target_addr, 0);
1106 return 0;
1109 /* do_socket() Must return target values and target errnos. */
1110 static abi_long do_socket(int domain, int type, int protocol)
1112 #if defined(TARGET_MIPS)
1113 switch(type) {
1114 case TARGET_SOCK_DGRAM:
1115 type = SOCK_DGRAM;
1116 break;
1117 case TARGET_SOCK_STREAM:
1118 type = SOCK_STREAM;
1119 break;
1120 case TARGET_SOCK_RAW:
1121 type = SOCK_RAW;
1122 break;
1123 case TARGET_SOCK_RDM:
1124 type = SOCK_RDM;
1125 break;
1126 case TARGET_SOCK_SEQPACKET:
1127 type = SOCK_SEQPACKET;
1128 break;
1129 case TARGET_SOCK_PACKET:
1130 type = SOCK_PACKET;
1131 break;
1133 #endif
1134 if (domain == PF_NETLINK)
1135 return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1136 return get_errno(socket(domain, type, protocol));
1139 /* do_bind() Must return target values and target errnos. */
1140 static abi_long do_bind(int sockfd, abi_ulong target_addr,
1141 socklen_t addrlen)
1143 void *addr = alloca(addrlen);
1145 target_to_host_sockaddr(addr, target_addr, addrlen);
1146 return get_errno(bind(sockfd, addr, addrlen));
1149 /* do_connect() Must return target values and target errnos. */
1150 static abi_long do_connect(int sockfd, abi_ulong target_addr,
1151 socklen_t addrlen)
1153 void *addr = alloca(addrlen);
1155 target_to_host_sockaddr(addr, target_addr, addrlen);
1156 return get_errno(connect(sockfd, addr, addrlen));
1159 /* do_sendrecvmsg() Must return target values and target errnos. */
1160 static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1161 int flags, int send)
1163 abi_long ret;
1164 struct target_msghdr *msgp;
1165 struct msghdr msg;
1166 int count;
1167 struct iovec *vec;
1168 abi_ulong target_vec;
1170 /* FIXME */
1171 if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1172 msgp,
1173 target_msg,
1174 send ? 1 : 0))
1175 return -TARGET_EFAULT;
1176 if (msgp->msg_name) {
1177 msg.msg_namelen = tswap32(msgp->msg_namelen);
1178 msg.msg_name = alloca(msg.msg_namelen);
1179 target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
1180 msg.msg_namelen);
1181 } else {
1182 msg.msg_name = NULL;
1183 msg.msg_namelen = 0;
1185 msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
1186 msg.msg_control = alloca(msg.msg_controllen);
1187 msg.msg_flags = tswap32(msgp->msg_flags);
1189 count = tswapl(msgp->msg_iovlen);
1190 vec = alloca(count * sizeof(struct iovec));
1191 target_vec = tswapl(msgp->msg_iov);
1192 lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1193 msg.msg_iovlen = count;
1194 msg.msg_iov = vec;
1196 if (send) {
1197 ret = target_to_host_cmsg(&msg, msgp);
1198 if (ret == 0)
1199 ret = get_errno(sendmsg(fd, &msg, flags));
1200 } else {
1201 ret = get_errno(recvmsg(fd, &msg, flags));
1202 if (!is_error(ret))
1203 ret = host_to_target_cmsg(msgp, &msg);
1205 unlock_iovec(vec, target_vec, count, !send);
1206 unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1207 return ret;
1210 /* do_accept() Must return target values and target errnos. */
1211 static abi_long do_accept(int fd, abi_ulong target_addr,
1212 abi_ulong target_addrlen_addr)
1214 socklen_t addrlen;
1215 void *addr;
1216 abi_long ret;
1218 if (get_user_u32(addrlen, target_addrlen_addr))
1219 return -TARGET_EFAULT;
1221 addr = alloca(addrlen);
1223 ret = get_errno(accept(fd, addr, &addrlen));
1224 if (!is_error(ret)) {
1225 host_to_target_sockaddr(target_addr, addr, addrlen);
1226 if (put_user_u32(addrlen, target_addrlen_addr))
1227 ret = -TARGET_EFAULT;
1229 return ret;
1232 /* do_getpeername() Must return target values and target errnos. */
1233 static abi_long do_getpeername(int fd, abi_ulong target_addr,
1234 abi_ulong target_addrlen_addr)
1236 socklen_t addrlen;
1237 void *addr;
1238 abi_long ret;
1240 if (get_user_u32(addrlen, target_addrlen_addr))
1241 return -TARGET_EFAULT;
1243 addr = alloca(addrlen);
1245 ret = get_errno(getpeername(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_getsockname() Must return target values and target errnos. */
1255 static abi_long do_getsockname(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 addr = alloca(addrlen);
1267 ret = get_errno(getsockname(fd, addr, &addrlen));
1268 if (!is_error(ret)) {
1269 host_to_target_sockaddr(target_addr, addr, addrlen);
1270 if (put_user_u32(addrlen, target_addrlen_addr))
1271 ret = -TARGET_EFAULT;
1273 return ret;
1276 /* do_socketpair() Must return target values and target errnos. */
1277 static abi_long do_socketpair(int domain, int type, int protocol,
1278 abi_ulong target_tab_addr)
1280 int tab[2];
1281 abi_long ret;
1283 ret = get_errno(socketpair(domain, type, protocol, tab));
1284 if (!is_error(ret)) {
1285 if (put_user_s32(tab[0], target_tab_addr)
1286 || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1287 ret = -TARGET_EFAULT;
1289 return ret;
1292 /* do_sendto() Must return target values and target errnos. */
1293 static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
1294 abi_ulong target_addr, socklen_t addrlen)
1296 void *addr;
1297 void *host_msg;
1298 abi_long ret;
1300 host_msg = lock_user(VERIFY_READ, msg, len, 1);
1301 if (!host_msg)
1302 return -TARGET_EFAULT;
1303 if (target_addr) {
1304 addr = alloca(addrlen);
1305 target_to_host_sockaddr(addr, target_addr, addrlen);
1306 ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
1307 } else {
1308 ret = get_errno(send(fd, host_msg, len, flags));
1310 unlock_user(host_msg, msg, 0);
1311 return ret;
1314 /* do_recvfrom() Must return target values and target errnos. */
1315 static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
1316 abi_ulong target_addr,
1317 abi_ulong target_addrlen)
1319 socklen_t addrlen;
1320 void *addr;
1321 void *host_msg;
1322 abi_long ret;
1324 host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
1325 if (!host_msg)
1326 return -TARGET_EFAULT;
1327 if (target_addr) {
1328 if (get_user_u32(addrlen, target_addrlen)) {
1329 ret = -TARGET_EFAULT;
1330 goto fail;
1332 addr = alloca(addrlen);
1333 ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
1334 } else {
1335 addr = NULL; /* To keep compiler quiet. */
1336 ret = get_errno(recv(fd, host_msg, len, flags));
1338 if (!is_error(ret)) {
1339 if (target_addr) {
1340 host_to_target_sockaddr(target_addr, addr, addrlen);
1341 if (put_user_u32(addrlen, target_addrlen)) {
1342 ret = -TARGET_EFAULT;
1343 goto fail;
1346 unlock_user(host_msg, msg, len);
1347 } else {
1348 fail:
1349 unlock_user(host_msg, msg, 0);
1351 return ret;
1354 #ifdef TARGET_NR_socketcall
1355 /* do_socketcall() Must return target values and target errnos. */
1356 static abi_long do_socketcall(int num, abi_ulong vptr)
1358 abi_long ret;
1359 const int n = sizeof(abi_ulong);
1361 switch(num) {
1362 case SOCKOP_socket:
1364 int domain, type, protocol;
1366 if (get_user_s32(domain, vptr)
1367 || get_user_s32(type, vptr + n)
1368 || get_user_s32(protocol, vptr + 2 * n))
1369 return -TARGET_EFAULT;
1371 ret = do_socket(domain, type, protocol);
1373 break;
1374 case SOCKOP_bind:
1376 int sockfd;
1377 abi_ulong target_addr;
1378 socklen_t addrlen;
1380 if (get_user_s32(sockfd, vptr)
1381 || get_user_ual(target_addr, vptr + n)
1382 || get_user_u32(addrlen, vptr + 2 * n))
1383 return -TARGET_EFAULT;
1385 ret = do_bind(sockfd, target_addr, addrlen);
1387 break;
1388 case SOCKOP_connect:
1390 int sockfd;
1391 abi_ulong target_addr;
1392 socklen_t addrlen;
1394 if (get_user_s32(sockfd, vptr)
1395 || get_user_ual(target_addr, vptr + n)
1396 || get_user_u32(addrlen, vptr + 2 * n))
1397 return -TARGET_EFAULT;
1399 ret = do_connect(sockfd, target_addr, addrlen);
1401 break;
1402 case SOCKOP_listen:
1404 int sockfd, backlog;
1406 if (get_user_s32(sockfd, vptr)
1407 || get_user_s32(backlog, vptr + n))
1408 return -TARGET_EFAULT;
1410 ret = get_errno(listen(sockfd, backlog));
1412 break;
1413 case SOCKOP_accept:
1415 int sockfd;
1416 abi_ulong target_addr, target_addrlen;
1418 if (get_user_s32(sockfd, vptr)
1419 || get_user_ual(target_addr, vptr + n)
1420 || get_user_u32(target_addrlen, vptr + 2 * n))
1421 return -TARGET_EFAULT;
1423 ret = do_accept(sockfd, target_addr, target_addrlen);
1425 break;
1426 case SOCKOP_getsockname:
1428 int sockfd;
1429 abi_ulong target_addr, target_addrlen;
1431 if (get_user_s32(sockfd, vptr)
1432 || get_user_ual(target_addr, vptr + n)
1433 || get_user_u32(target_addrlen, vptr + 2 * n))
1434 return -TARGET_EFAULT;
1436 ret = do_getsockname(sockfd, target_addr, target_addrlen);
1438 break;
1439 case SOCKOP_getpeername:
1441 int sockfd;
1442 abi_ulong target_addr, target_addrlen;
1444 if (get_user_s32(sockfd, vptr)
1445 || get_user_ual(target_addr, vptr + n)
1446 || get_user_u32(target_addrlen, vptr + 2 * n))
1447 return -TARGET_EFAULT;
1449 ret = do_getpeername(sockfd, target_addr, target_addrlen);
1451 break;
1452 case SOCKOP_socketpair:
1454 int domain, type, protocol;
1455 abi_ulong tab;
1457 if (get_user_s32(domain, vptr)
1458 || get_user_s32(type, vptr + n)
1459 || get_user_s32(protocol, vptr + 2 * n)
1460 || get_user_ual(tab, vptr + 3 * n))
1461 return -TARGET_EFAULT;
1463 ret = do_socketpair(domain, type, protocol, tab);
1465 break;
1466 case SOCKOP_send:
1468 int sockfd;
1469 abi_ulong msg;
1470 size_t len;
1471 int flags;
1473 if (get_user_s32(sockfd, vptr)
1474 || get_user_ual(msg, vptr + n)
1475 || get_user_ual(len, vptr + 2 * n)
1476 || get_user_s32(flags, vptr + 3 * n))
1477 return -TARGET_EFAULT;
1479 ret = do_sendto(sockfd, msg, len, flags, 0, 0);
1481 break;
1482 case SOCKOP_recv:
1484 int sockfd;
1485 abi_ulong msg;
1486 size_t len;
1487 int flags;
1489 if (get_user_s32(sockfd, vptr)
1490 || get_user_ual(msg, vptr + n)
1491 || get_user_ual(len, vptr + 2 * n)
1492 || get_user_s32(flags, vptr + 3 * n))
1493 return -TARGET_EFAULT;
1495 ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
1497 break;
1498 case SOCKOP_sendto:
1500 int sockfd;
1501 abi_ulong msg;
1502 size_t len;
1503 int flags;
1504 abi_ulong addr;
1505 socklen_t addrlen;
1507 if (get_user_s32(sockfd, vptr)
1508 || get_user_ual(msg, vptr + n)
1509 || get_user_ual(len, vptr + 2 * n)
1510 || get_user_s32(flags, vptr + 3 * n)
1511 || get_user_ual(addr, vptr + 4 * n)
1512 || get_user_u32(addrlen, vptr + 5 * n))
1513 return -TARGET_EFAULT;
1515 ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
1517 break;
1518 case SOCKOP_recvfrom:
1520 int sockfd;
1521 abi_ulong msg;
1522 size_t len;
1523 int flags;
1524 abi_ulong addr;
1525 socklen_t addrlen;
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 || get_user_ual(addr, vptr + 4 * n)
1532 || get_user_u32(addrlen, vptr + 5 * n))
1533 return -TARGET_EFAULT;
1535 ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
1537 break;
1538 case SOCKOP_shutdown:
1540 int sockfd, how;
1542 if (get_user_s32(sockfd, vptr)
1543 || get_user_s32(how, vptr + n))
1544 return -TARGET_EFAULT;
1546 ret = get_errno(shutdown(sockfd, how));
1548 break;
1549 case SOCKOP_sendmsg:
1550 case SOCKOP_recvmsg:
1552 int fd;
1553 abi_ulong target_msg;
1554 int flags;
1556 if (get_user_s32(fd, vptr)
1557 || get_user_ual(target_msg, vptr + n)
1558 || get_user_s32(flags, vptr + 2 * n))
1559 return -TARGET_EFAULT;
1561 ret = do_sendrecvmsg(fd, target_msg, flags,
1562 (num == SOCKOP_sendmsg));
1564 break;
1565 case SOCKOP_setsockopt:
1567 int sockfd;
1568 int level;
1569 int optname;
1570 abi_ulong optval;
1571 socklen_t optlen;
1573 if (get_user_s32(sockfd, vptr)
1574 || get_user_s32(level, vptr + n)
1575 || get_user_s32(optname, vptr + 2 * n)
1576 || get_user_ual(optval, vptr + 3 * n)
1577 || get_user_u32(optlen, vptr + 4 * n))
1578 return -TARGET_EFAULT;
1580 ret = do_setsockopt(sockfd, level, optname, optval, optlen);
1582 break;
1583 case SOCKOP_getsockopt:
1585 int sockfd;
1586 int level;
1587 int optname;
1588 abi_ulong optval;
1589 socklen_t optlen;
1591 if (get_user_s32(sockfd, vptr)
1592 || get_user_s32(level, vptr + n)
1593 || get_user_s32(optname, vptr + 2 * n)
1594 || get_user_ual(optval, vptr + 3 * n)
1595 || get_user_u32(optlen, vptr + 4 * n))
1596 return -TARGET_EFAULT;
1598 ret = do_getsockopt(sockfd, level, optname, optval, optlen);
1600 break;
1601 default:
1602 gemu_log("Unsupported socketcall: %d\n", num);
1603 ret = -TARGET_ENOSYS;
1604 break;
1606 return ret;
1608 #endif
1610 #define N_SHM_REGIONS 32
1612 static struct shm_region {
1613 abi_ulong start;
1614 abi_ulong size;
1615 } shm_regions[N_SHM_REGIONS];
1617 struct target_ipc_perm
1619 abi_long __key;
1620 abi_ulong uid;
1621 abi_ulong gid;
1622 abi_ulong cuid;
1623 abi_ulong cgid;
1624 unsigned short int mode;
1625 unsigned short int __pad1;
1626 unsigned short int __seq;
1627 unsigned short int __pad2;
1628 abi_ulong __unused1;
1629 abi_ulong __unused2;
1632 struct target_semid_ds
1634 struct target_ipc_perm sem_perm;
1635 abi_ulong sem_otime;
1636 abi_ulong __unused1;
1637 abi_ulong sem_ctime;
1638 abi_ulong __unused2;
1639 abi_ulong sem_nsems;
1640 abi_ulong __unused3;
1641 abi_ulong __unused4;
1644 static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
1645 abi_ulong target_addr)
1647 struct target_ipc_perm *target_ip;
1648 struct target_semid_ds *target_sd;
1650 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
1651 return -TARGET_EFAULT;
1652 target_ip=&(target_sd->sem_perm);
1653 host_ip->__key = tswapl(target_ip->__key);
1654 host_ip->uid = tswapl(target_ip->uid);
1655 host_ip->gid = tswapl(target_ip->gid);
1656 host_ip->cuid = tswapl(target_ip->cuid);
1657 host_ip->cgid = tswapl(target_ip->cgid);
1658 host_ip->mode = tswapl(target_ip->mode);
1659 unlock_user_struct(target_sd, target_addr, 0);
1660 return 0;
1663 static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
1664 struct ipc_perm *host_ip)
1666 struct target_ipc_perm *target_ip;
1667 struct target_semid_ds *target_sd;
1669 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
1670 return -TARGET_EFAULT;
1671 target_ip = &(target_sd->sem_perm);
1672 target_ip->__key = tswapl(host_ip->__key);
1673 target_ip->uid = tswapl(host_ip->uid);
1674 target_ip->gid = tswapl(host_ip->gid);
1675 target_ip->cuid = tswapl(host_ip->cuid);
1676 target_ip->cgid = tswapl(host_ip->cgid);
1677 target_ip->mode = tswapl(host_ip->mode);
1678 unlock_user_struct(target_sd, target_addr, 1);
1679 return 0;
1682 static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
1683 abi_ulong target_addr)
1685 struct target_semid_ds *target_sd;
1687 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
1688 return -TARGET_EFAULT;
1689 target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr);
1690 host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
1691 host_sd->sem_otime = tswapl(target_sd->sem_otime);
1692 host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
1693 unlock_user_struct(target_sd, target_addr, 0);
1694 return 0;
1697 static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
1698 struct semid_ds *host_sd)
1700 struct target_semid_ds *target_sd;
1702 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
1703 return -TARGET_EFAULT;
1704 host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm));
1705 target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
1706 target_sd->sem_otime = tswapl(host_sd->sem_otime);
1707 target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
1708 unlock_user_struct(target_sd, target_addr, 1);
1709 return 0;
1712 union semun {
1713 int val;
1714 struct semid_ds *buf;
1715 unsigned short *array;
1718 union target_semun {
1719 int val;
1720 abi_long buf;
1721 unsigned short int *array;
1724 static inline abi_long target_to_host_semun(int cmd,
1725 union semun *host_su,
1726 abi_ulong target_addr,
1727 struct semid_ds *ds)
1729 union target_semun *target_su;
1731 switch( cmd ) {
1732 case IPC_STAT:
1733 case IPC_SET:
1734 if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1735 return -TARGET_EFAULT;
1736 target_to_host_semid_ds(ds,target_su->buf);
1737 host_su->buf = ds;
1738 unlock_user_struct(target_su, target_addr, 0);
1739 break;
1740 case GETVAL:
1741 case SETVAL:
1742 if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1743 return -TARGET_EFAULT;
1744 host_su->val = tswapl(target_su->val);
1745 unlock_user_struct(target_su, target_addr, 0);
1746 break;
1747 case GETALL:
1748 case SETALL:
1749 if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1750 return -TARGET_EFAULT;
1751 *host_su->array = tswap16(*target_su->array);
1752 unlock_user_struct(target_su, target_addr, 0);
1753 break;
1754 default:
1755 gemu_log("semun operation not fully supported: %d\n", (int)cmd);
1757 return 0;
1760 static inline abi_long host_to_target_semun(int cmd,
1761 abi_ulong target_addr,
1762 union semun *host_su,
1763 struct semid_ds *ds)
1765 union target_semun *target_su;
1767 switch( cmd ) {
1768 case IPC_STAT:
1769 case IPC_SET:
1770 if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1771 return -TARGET_EFAULT;
1772 host_to_target_semid_ds(target_su->buf,ds);
1773 unlock_user_struct(target_su, target_addr, 1);
1774 break;
1775 case GETVAL:
1776 case SETVAL:
1777 if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1778 return -TARGET_EFAULT;
1779 target_su->val = tswapl(host_su->val);
1780 unlock_user_struct(target_su, target_addr, 1);
1781 break;
1782 case GETALL:
1783 case SETALL:
1784 if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1785 return -TARGET_EFAULT;
1786 *target_su->array = tswap16(*host_su->array);
1787 unlock_user_struct(target_su, target_addr, 1);
1788 break;
1789 default:
1790 gemu_log("semun operation not fully supported: %d\n", (int)cmd);
1792 return 0;
1795 static inline abi_long do_semctl(int first, int second, int third,
1796 abi_long ptr)
1798 union semun arg;
1799 struct semid_ds dsarg;
1800 int cmd = third&0xff;
1801 abi_long ret = 0;
1803 switch( cmd ) {
1804 case GETVAL:
1805 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1806 ret = get_errno(semctl(first, second, cmd, arg));
1807 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1808 break;
1809 case SETVAL:
1810 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1811 ret = get_errno(semctl(first, second, cmd, arg));
1812 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1813 break;
1814 case GETALL:
1815 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1816 ret = get_errno(semctl(first, second, cmd, arg));
1817 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1818 break;
1819 case SETALL:
1820 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1821 ret = get_errno(semctl(first, second, cmd, arg));
1822 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1823 break;
1824 case IPC_STAT:
1825 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1826 ret = get_errno(semctl(first, second, cmd, arg));
1827 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1828 break;
1829 case IPC_SET:
1830 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1831 ret = get_errno(semctl(first, second, cmd, arg));
1832 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1833 break;
1834 default:
1835 ret = get_errno(semctl(first, second, cmd, arg));
1838 return ret;
1841 struct target_msqid_ds
1843 struct target_ipc_perm msg_perm;
1844 abi_ulong msg_stime;
1845 #if TARGET_ABI_BITS == 32
1846 abi_ulong __unused1;
1847 #endif
1848 abi_ulong msg_rtime;
1849 #if TARGET_ABI_BITS == 32
1850 abi_ulong __unused2;
1851 #endif
1852 abi_ulong msg_ctime;
1853 #if TARGET_ABI_BITS == 32
1854 abi_ulong __unused3;
1855 #endif
1856 abi_ulong __msg_cbytes;
1857 abi_ulong msg_qnum;
1858 abi_ulong msg_qbytes;
1859 abi_ulong msg_lspid;
1860 abi_ulong msg_lrpid;
1861 abi_ulong __unused4;
1862 abi_ulong __unused5;
1865 static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
1866 abi_ulong target_addr)
1868 struct target_msqid_ds *target_md;
1870 if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
1871 return -TARGET_EFAULT;
1872 if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
1873 return -TARGET_EFAULT;
1874 host_md->msg_stime = tswapl(target_md->msg_stime);
1875 host_md->msg_rtime = tswapl(target_md->msg_rtime);
1876 host_md->msg_ctime = tswapl(target_md->msg_ctime);
1877 host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
1878 host_md->msg_qnum = tswapl(target_md->msg_qnum);
1879 host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
1880 host_md->msg_lspid = tswapl(target_md->msg_lspid);
1881 host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
1882 unlock_user_struct(target_md, target_addr, 0);
1883 return 0;
1886 static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
1887 struct msqid_ds *host_md)
1889 struct target_msqid_ds *target_md;
1891 if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
1892 return -TARGET_EFAULT;
1893 if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
1894 return -TARGET_EFAULT;
1895 target_md->msg_stime = tswapl(host_md->msg_stime);
1896 target_md->msg_rtime = tswapl(host_md->msg_rtime);
1897 target_md->msg_ctime = tswapl(host_md->msg_ctime);
1898 target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
1899 target_md->msg_qnum = tswapl(host_md->msg_qnum);
1900 target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
1901 target_md->msg_lspid = tswapl(host_md->msg_lspid);
1902 target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
1903 unlock_user_struct(target_md, target_addr, 1);
1904 return 0;
1907 struct target_msginfo {
1908 int msgpool;
1909 int msgmap;
1910 int msgmax;
1911 int msgmnb;
1912 int msgmni;
1913 int msgssz;
1914 int msgtql;
1915 unsigned short int msgseg;
1918 static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
1919 struct msginfo *host_msginfo)
1921 struct target_msginfo *target_msginfo;
1922 if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
1923 return -TARGET_EFAULT;
1924 __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
1925 __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
1926 __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
1927 __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
1928 __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
1929 __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
1930 __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
1931 __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
1932 unlock_user_struct(target_msginfo, target_addr, 1);
1933 return 0;
1936 static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
1938 struct msqid_ds dsarg;
1939 struct msginfo msginfo;
1940 abi_long ret = -TARGET_EINVAL;
1942 cmd &= 0xff;
1944 switch (cmd) {
1945 case IPC_STAT:
1946 case IPC_SET:
1947 case MSG_STAT:
1948 if (target_to_host_msqid_ds(&dsarg,ptr))
1949 return -TARGET_EFAULT;
1950 ret = get_errno(msgctl(msgid, cmd, &dsarg));
1951 if (host_to_target_msqid_ds(ptr,&dsarg))
1952 return -TARGET_EFAULT;
1953 break;
1954 case IPC_RMID:
1955 ret = get_errno(msgctl(msgid, cmd, NULL));
1956 break;
1957 case IPC_INFO:
1958 case MSG_INFO:
1959 ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
1960 if (host_to_target_msginfo(ptr, &msginfo))
1961 return -TARGET_EFAULT;
1962 break;
1965 return ret;
1968 struct target_msgbuf {
1969 abi_long mtype;
1970 char mtext[1];
1973 static inline abi_long do_msgsnd(int msqid, abi_long msgp,
1974 unsigned int msgsz, int msgflg)
1976 struct target_msgbuf *target_mb;
1977 struct msgbuf *host_mb;
1978 abi_long ret = 0;
1980 if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
1981 return -TARGET_EFAULT;
1982 host_mb = malloc(msgsz+sizeof(long));
1983 host_mb->mtype = (abi_long) tswapl(target_mb->mtype);
1984 memcpy(host_mb->mtext, target_mb->mtext, msgsz);
1985 ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
1986 free(host_mb);
1987 unlock_user_struct(target_mb, msgp, 0);
1989 return ret;
1992 static inline abi_long do_msgrcv(int msqid, abi_long msgp,
1993 unsigned int msgsz, abi_long msgtyp,
1994 int msgflg)
1996 struct target_msgbuf *target_mb;
1997 char *target_mtext;
1998 struct msgbuf *host_mb;
1999 abi_long ret = 0;
2001 if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2002 return -TARGET_EFAULT;
2004 host_mb = malloc(msgsz+sizeof(long));
2005 ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapl(msgtyp), msgflg));
2007 if (ret > 0) {
2008 abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2009 target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2010 if (!target_mtext) {
2011 ret = -TARGET_EFAULT;
2012 goto end;
2014 memcpy(target_mb->mtext, host_mb->mtext, ret);
2015 unlock_user(target_mtext, target_mtext_addr, ret);
2018 target_mb->mtype = tswapl(host_mb->mtype);
2019 free(host_mb);
2021 end:
2022 if (target_mb)
2023 unlock_user_struct(target_mb, msgp, 1);
2024 return ret;
2027 #ifdef TARGET_NR_ipc
2028 /* ??? This only works with linear mappings. */
2029 /* do_ipc() must return target values and target errnos. */
2030 static abi_long do_ipc(unsigned int call, int first,
2031 int second, int third,
2032 abi_long ptr, abi_long fifth)
2034 int version;
2035 abi_long ret = 0;
2036 struct shmid_ds shm_info;
2037 int i;
2039 version = call >> 16;
2040 call &= 0xffff;
2042 switch (call) {
2043 case IPCOP_semop:
2044 ret = get_errno(semop(first,(struct sembuf *)g2h(ptr), second));
2045 break;
2047 case IPCOP_semget:
2048 ret = get_errno(semget(first, second, third));
2049 break;
2051 case IPCOP_semctl:
2052 ret = do_semctl(first, second, third, ptr);
2053 break;
2055 case IPCOP_semtimedop:
2056 gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2057 ret = -TARGET_ENOSYS;
2058 break;
2060 case IPCOP_msgget:
2061 ret = get_errno(msgget(first, second));
2062 break;
2064 case IPCOP_msgsnd:
2065 ret = do_msgsnd(first, ptr, second, third);
2066 break;
2068 case IPCOP_msgctl:
2069 ret = do_msgctl(first, second, ptr);
2070 break;
2072 case IPCOP_msgrcv:
2073 switch (version) {
2074 case 0:
2076 struct target_ipc_kludge {
2077 abi_long msgp;
2078 abi_long msgtyp;
2079 } *tmp;
2081 if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
2082 ret = -TARGET_EFAULT;
2083 break;
2086 ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
2088 unlock_user_struct(tmp, ptr, 0);
2089 break;
2091 default:
2092 ret = do_msgrcv(first, ptr, second, fifth, third);
2094 break;
2096 case IPCOP_shmat:
2098 abi_ulong raddr;
2099 void *host_addr;
2100 /* SHM_* flags are the same on all linux platforms */
2101 host_addr = shmat(first, (void *)g2h(ptr), second);
2102 if (host_addr == (void *)-1) {
2103 ret = get_errno((long)host_addr);
2104 break;
2106 raddr = h2g((unsigned long)host_addr);
2107 /* find out the length of the shared memory segment */
2109 ret = get_errno(shmctl(first, IPC_STAT, &shm_info));
2110 if (is_error(ret)) {
2111 /* can't get length, bail out */
2112 shmdt(host_addr);
2113 break;
2115 page_set_flags(raddr, raddr + shm_info.shm_segsz,
2116 PAGE_VALID | PAGE_READ |
2117 ((second & SHM_RDONLY)? 0: PAGE_WRITE));
2118 for (i = 0; i < N_SHM_REGIONS; ++i) {
2119 if (shm_regions[i].start == 0) {
2120 shm_regions[i].start = raddr;
2121 shm_regions[i].size = shm_info.shm_segsz;
2122 break;
2125 if (put_user_ual(raddr, third))
2126 return -TARGET_EFAULT;
2127 ret = 0;
2129 break;
2130 case IPCOP_shmdt:
2131 for (i = 0; i < N_SHM_REGIONS; ++i) {
2132 if (shm_regions[i].start == ptr) {
2133 shm_regions[i].start = 0;
2134 page_set_flags(ptr, shm_regions[i].size, 0);
2135 break;
2138 ret = get_errno(shmdt((void *)g2h(ptr)));
2139 break;
2141 case IPCOP_shmget:
2142 /* IPC_* flag values are the same on all linux platforms */
2143 ret = get_errno(shmget(first, second, third));
2144 break;
2146 /* IPC_* and SHM_* command values are the same on all linux platforms */
2147 case IPCOP_shmctl:
2148 switch(second) {
2149 case IPC_RMID:
2150 case SHM_LOCK:
2151 case SHM_UNLOCK:
2152 ret = get_errno(shmctl(first, second, NULL));
2153 break;
2154 default:
2155 goto unimplemented;
2157 break;
2158 default:
2159 unimplemented:
2160 gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2161 ret = -TARGET_ENOSYS;
2162 break;
2164 return ret;
2166 #endif
2168 /* kernel structure types definitions */
2169 #define IFNAMSIZ 16
2171 #define STRUCT(name, list...) STRUCT_ ## name,
2172 #define STRUCT_SPECIAL(name) STRUCT_ ## name,
2173 enum {
2174 #include "syscall_types.h"
2176 #undef STRUCT
2177 #undef STRUCT_SPECIAL
2179 #define STRUCT(name, list...) static const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };
2180 #define STRUCT_SPECIAL(name)
2181 #include "syscall_types.h"
2182 #undef STRUCT
2183 #undef STRUCT_SPECIAL
2185 typedef struct IOCTLEntry {
2186 unsigned int target_cmd;
2187 unsigned int host_cmd;
2188 const char *name;
2189 int access;
2190 const argtype arg_type[5];
2191 } IOCTLEntry;
2193 #define IOC_R 0x0001
2194 #define IOC_W 0x0002
2195 #define IOC_RW (IOC_R | IOC_W)
2197 #define MAX_STRUCT_SIZE 4096
2199 static IOCTLEntry ioctl_entries[] = {
2200 #define IOCTL(cmd, access, types...) \
2201 { TARGET_ ## cmd, cmd, #cmd, access, { types } },
2202 #include "ioctls.h"
2203 { 0, 0, },
2206 /* ??? Implement proper locking for ioctls. */
2207 /* do_ioctl() Must return target values and target errnos. */
2208 static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
2210 const IOCTLEntry *ie;
2211 const argtype *arg_type;
2212 abi_long ret;
2213 uint8_t buf_temp[MAX_STRUCT_SIZE];
2214 int target_size;
2215 void *argptr;
2217 ie = ioctl_entries;
2218 for(;;) {
2219 if (ie->target_cmd == 0) {
2220 gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
2221 return -TARGET_ENOSYS;
2223 if (ie->target_cmd == cmd)
2224 break;
2225 ie++;
2227 arg_type = ie->arg_type;
2228 #if defined(DEBUG)
2229 gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
2230 #endif
2231 switch(arg_type[0]) {
2232 case TYPE_NULL:
2233 /* no argument */
2234 ret = get_errno(ioctl(fd, ie->host_cmd));
2235 break;
2236 case TYPE_PTRVOID:
2237 case TYPE_INT:
2238 /* int argment */
2239 ret = get_errno(ioctl(fd, ie->host_cmd, arg));
2240 break;
2241 case TYPE_PTR:
2242 arg_type++;
2243 target_size = thunk_type_size(arg_type, 0);
2244 switch(ie->access) {
2245 case IOC_R:
2246 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2247 if (!is_error(ret)) {
2248 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2249 if (!argptr)
2250 return -TARGET_EFAULT;
2251 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2252 unlock_user(argptr, arg, target_size);
2254 break;
2255 case IOC_W:
2256 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2257 if (!argptr)
2258 return -TARGET_EFAULT;
2259 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2260 unlock_user(argptr, arg, 0);
2261 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2262 break;
2263 default:
2264 case IOC_RW:
2265 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2266 if (!argptr)
2267 return -TARGET_EFAULT;
2268 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2269 unlock_user(argptr, arg, 0);
2270 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2271 if (!is_error(ret)) {
2272 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2273 if (!argptr)
2274 return -TARGET_EFAULT;
2275 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2276 unlock_user(argptr, arg, target_size);
2278 break;
2280 break;
2281 default:
2282 gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
2283 (long)cmd, arg_type[0]);
2284 ret = -TARGET_ENOSYS;
2285 break;
2287 return ret;
2290 static const bitmask_transtbl iflag_tbl[] = {
2291 { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
2292 { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
2293 { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
2294 { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
2295 { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
2296 { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
2297 { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
2298 { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
2299 { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
2300 { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
2301 { TARGET_IXON, TARGET_IXON, IXON, IXON },
2302 { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
2303 { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
2304 { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
2305 { 0, 0, 0, 0 }
2308 static const bitmask_transtbl oflag_tbl[] = {
2309 { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
2310 { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
2311 { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
2312 { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
2313 { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
2314 { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
2315 { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
2316 { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
2317 { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
2318 { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
2319 { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
2320 { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
2321 { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
2322 { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
2323 { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
2324 { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
2325 { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
2326 { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
2327 { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
2328 { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
2329 { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
2330 { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
2331 { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
2332 { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
2333 { 0, 0, 0, 0 }
2336 static const bitmask_transtbl cflag_tbl[] = {
2337 { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
2338 { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
2339 { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
2340 { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
2341 { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
2342 { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
2343 { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
2344 { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
2345 { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
2346 { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
2347 { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
2348 { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
2349 { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
2350 { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
2351 { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
2352 { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
2353 { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
2354 { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
2355 { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
2356 { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
2357 { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
2358 { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
2359 { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
2360 { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
2361 { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
2362 { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
2363 { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
2364 { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
2365 { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
2366 { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
2367 { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
2368 { 0, 0, 0, 0 }
2371 static const bitmask_transtbl lflag_tbl[] = {
2372 { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
2373 { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
2374 { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
2375 { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
2376 { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
2377 { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
2378 { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
2379 { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
2380 { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
2381 { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
2382 { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
2383 { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
2384 { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
2385 { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
2386 { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
2387 { 0, 0, 0, 0 }
2390 static void target_to_host_termios (void *dst, const void *src)
2392 struct host_termios *host = dst;
2393 const struct target_termios *target = src;
2395 host->c_iflag =
2396 target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
2397 host->c_oflag =
2398 target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
2399 host->c_cflag =
2400 target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
2401 host->c_lflag =
2402 target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
2403 host->c_line = target->c_line;
2405 host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
2406 host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
2407 host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
2408 host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
2409 host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
2410 host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
2411 host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
2412 host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
2413 host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
2414 host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
2415 host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
2416 host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
2417 host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
2418 host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
2419 host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
2420 host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
2421 host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
2424 static void host_to_target_termios (void *dst, const void *src)
2426 struct target_termios *target = dst;
2427 const struct host_termios *host = src;
2429 target->c_iflag =
2430 tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
2431 target->c_oflag =
2432 tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
2433 target->c_cflag =
2434 tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
2435 target->c_lflag =
2436 tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
2437 target->c_line = host->c_line;
2439 target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
2440 target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
2441 target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
2442 target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
2443 target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
2444 target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
2445 target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
2446 target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
2447 target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
2448 target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
2449 target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
2450 target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
2451 target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
2452 target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
2453 target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
2454 target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
2455 target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
2458 static const StructEntry struct_termios_def = {
2459 .convert = { host_to_target_termios, target_to_host_termios },
2460 .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
2461 .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
2464 static bitmask_transtbl mmap_flags_tbl[] = {
2465 { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
2466 { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
2467 { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
2468 { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
2469 { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
2470 { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
2471 { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
2472 { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
2473 { 0, 0, 0, 0 }
2476 static bitmask_transtbl fcntl_flags_tbl[] = {
2477 { TARGET_O_ACCMODE, TARGET_O_WRONLY, O_ACCMODE, O_WRONLY, },
2478 { TARGET_O_ACCMODE, TARGET_O_RDWR, O_ACCMODE, O_RDWR, },
2479 { TARGET_O_CREAT, TARGET_O_CREAT, O_CREAT, O_CREAT, },
2480 { TARGET_O_EXCL, TARGET_O_EXCL, O_EXCL, O_EXCL, },
2481 { TARGET_O_NOCTTY, TARGET_O_NOCTTY, O_NOCTTY, O_NOCTTY, },
2482 { TARGET_O_TRUNC, TARGET_O_TRUNC, O_TRUNC, O_TRUNC, },
2483 { TARGET_O_APPEND, TARGET_O_APPEND, O_APPEND, O_APPEND, },
2484 { TARGET_O_NONBLOCK, TARGET_O_NONBLOCK, O_NONBLOCK, O_NONBLOCK, },
2485 { TARGET_O_SYNC, TARGET_O_SYNC, O_SYNC, O_SYNC, },
2486 { TARGET_FASYNC, TARGET_FASYNC, FASYNC, FASYNC, },
2487 { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
2488 { TARGET_O_NOFOLLOW, TARGET_O_NOFOLLOW, O_NOFOLLOW, O_NOFOLLOW, },
2489 { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
2490 #if defined(O_DIRECT)
2491 { TARGET_O_DIRECT, TARGET_O_DIRECT, O_DIRECT, O_DIRECT, },
2492 #endif
2493 { 0, 0, 0, 0 }
2496 #if defined(TARGET_I386)
2498 /* NOTE: there is really one LDT for all the threads */
2499 static uint8_t *ldt_table;
2501 static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
2503 int size;
2504 void *p;
2506 if (!ldt_table)
2507 return 0;
2508 size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
2509 if (size > bytecount)
2510 size = bytecount;
2511 p = lock_user(VERIFY_WRITE, ptr, size, 0);
2512 if (!p)
2513 return -TARGET_EFAULT;
2514 /* ??? Should this by byteswapped? */
2515 memcpy(p, ldt_table, size);
2516 unlock_user(p, ptr, size);
2517 return size;
2520 /* XXX: add locking support */
2521 static abi_long write_ldt(CPUX86State *env,
2522 abi_ulong ptr, unsigned long bytecount, int oldmode)
2524 struct target_modify_ldt_ldt_s ldt_info;
2525 struct target_modify_ldt_ldt_s *target_ldt_info;
2526 int seg_32bit, contents, read_exec_only, limit_in_pages;
2527 int seg_not_present, useable, lm;
2528 uint32_t *lp, entry_1, entry_2;
2530 if (bytecount != sizeof(ldt_info))
2531 return -TARGET_EINVAL;
2532 if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
2533 return -TARGET_EFAULT;
2534 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2535 ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2536 ldt_info.limit = tswap32(target_ldt_info->limit);
2537 ldt_info.flags = tswap32(target_ldt_info->flags);
2538 unlock_user_struct(target_ldt_info, ptr, 0);
2540 if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
2541 return -TARGET_EINVAL;
2542 seg_32bit = ldt_info.flags & 1;
2543 contents = (ldt_info.flags >> 1) & 3;
2544 read_exec_only = (ldt_info.flags >> 3) & 1;
2545 limit_in_pages = (ldt_info.flags >> 4) & 1;
2546 seg_not_present = (ldt_info.flags >> 5) & 1;
2547 useable = (ldt_info.flags >> 6) & 1;
2548 #ifdef TARGET_ABI32
2549 lm = 0;
2550 #else
2551 lm = (ldt_info.flags >> 7) & 1;
2552 #endif
2553 if (contents == 3) {
2554 if (oldmode)
2555 return -TARGET_EINVAL;
2556 if (seg_not_present == 0)
2557 return -TARGET_EINVAL;
2559 /* allocate the LDT */
2560 if (!ldt_table) {
2561 ldt_table = malloc(TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
2562 if (!ldt_table)
2563 return -TARGET_ENOMEM;
2564 memset(ldt_table, 0, TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
2565 env->ldt.base = h2g((unsigned long)ldt_table);
2566 env->ldt.limit = 0xffff;
2569 /* NOTE: same code as Linux kernel */
2570 /* Allow LDTs to be cleared by the user. */
2571 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2572 if (oldmode ||
2573 (contents == 0 &&
2574 read_exec_only == 1 &&
2575 seg_32bit == 0 &&
2576 limit_in_pages == 0 &&
2577 seg_not_present == 1 &&
2578 useable == 0 )) {
2579 entry_1 = 0;
2580 entry_2 = 0;
2581 goto install;
2585 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2586 (ldt_info.limit & 0x0ffff);
2587 entry_2 = (ldt_info.base_addr & 0xff000000) |
2588 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2589 (ldt_info.limit & 0xf0000) |
2590 ((read_exec_only ^ 1) << 9) |
2591 (contents << 10) |
2592 ((seg_not_present ^ 1) << 15) |
2593 (seg_32bit << 22) |
2594 (limit_in_pages << 23) |
2595 (lm << 21) |
2596 0x7000;
2597 if (!oldmode)
2598 entry_2 |= (useable << 20);
2600 /* Install the new entry ... */
2601 install:
2602 lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
2603 lp[0] = tswap32(entry_1);
2604 lp[1] = tswap32(entry_2);
2605 return 0;
2608 /* specific and weird i386 syscalls */
2609 static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
2610 unsigned long bytecount)
2612 abi_long ret;
2614 switch (func) {
2615 case 0:
2616 ret = read_ldt(ptr, bytecount);
2617 break;
2618 case 1:
2619 ret = write_ldt(env, ptr, bytecount, 1);
2620 break;
2621 case 0x11:
2622 ret = write_ldt(env, ptr, bytecount, 0);
2623 break;
2624 default:
2625 ret = -TARGET_ENOSYS;
2626 break;
2628 return ret;
2631 #if defined(TARGET_I386) && defined(TARGET_ABI32)
2632 static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
2634 uint64_t *gdt_table = g2h(env->gdt.base);
2635 struct target_modify_ldt_ldt_s ldt_info;
2636 struct target_modify_ldt_ldt_s *target_ldt_info;
2637 int seg_32bit, contents, read_exec_only, limit_in_pages;
2638 int seg_not_present, useable, lm;
2639 uint32_t *lp, entry_1, entry_2;
2640 int i;
2642 lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
2643 if (!target_ldt_info)
2644 return -TARGET_EFAULT;
2645 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2646 ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2647 ldt_info.limit = tswap32(target_ldt_info->limit);
2648 ldt_info.flags = tswap32(target_ldt_info->flags);
2649 if (ldt_info.entry_number == -1) {
2650 for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
2651 if (gdt_table[i] == 0) {
2652 ldt_info.entry_number = i;
2653 target_ldt_info->entry_number = tswap32(i);
2654 break;
2658 unlock_user_struct(target_ldt_info, ptr, 1);
2660 if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN ||
2661 ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
2662 return -TARGET_EINVAL;
2663 seg_32bit = ldt_info.flags & 1;
2664 contents = (ldt_info.flags >> 1) & 3;
2665 read_exec_only = (ldt_info.flags >> 3) & 1;
2666 limit_in_pages = (ldt_info.flags >> 4) & 1;
2667 seg_not_present = (ldt_info.flags >> 5) & 1;
2668 useable = (ldt_info.flags >> 6) & 1;
2669 #ifdef TARGET_ABI32
2670 lm = 0;
2671 #else
2672 lm = (ldt_info.flags >> 7) & 1;
2673 #endif
2675 if (contents == 3) {
2676 if (seg_not_present == 0)
2677 return -TARGET_EINVAL;
2680 /* NOTE: same code as Linux kernel */
2681 /* Allow LDTs to be cleared by the user. */
2682 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2683 if ((contents == 0 &&
2684 read_exec_only == 1 &&
2685 seg_32bit == 0 &&
2686 limit_in_pages == 0 &&
2687 seg_not_present == 1 &&
2688 useable == 0 )) {
2689 entry_1 = 0;
2690 entry_2 = 0;
2691 goto install;
2695 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2696 (ldt_info.limit & 0x0ffff);
2697 entry_2 = (ldt_info.base_addr & 0xff000000) |
2698 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2699 (ldt_info.limit & 0xf0000) |
2700 ((read_exec_only ^ 1) << 9) |
2701 (contents << 10) |
2702 ((seg_not_present ^ 1) << 15) |
2703 (seg_32bit << 22) |
2704 (limit_in_pages << 23) |
2705 (useable << 20) |
2706 (lm << 21) |
2707 0x7000;
2709 /* Install the new entry ... */
2710 install:
2711 lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
2712 lp[0] = tswap32(entry_1);
2713 lp[1] = tswap32(entry_2);
2714 return 0;
2717 static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
2719 struct target_modify_ldt_ldt_s *target_ldt_info;
2720 uint64_t *gdt_table = g2h(env->gdt.base);
2721 uint32_t base_addr, limit, flags;
2722 int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
2723 int seg_not_present, useable, lm;
2724 uint32_t *lp, entry_1, entry_2;
2726 lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
2727 if (!target_ldt_info)
2728 return -TARGET_EFAULT;
2729 idx = tswap32(target_ldt_info->entry_number);
2730 if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
2731 idx > TARGET_GDT_ENTRY_TLS_MAX) {
2732 unlock_user_struct(target_ldt_info, ptr, 1);
2733 return -TARGET_EINVAL;
2735 lp = (uint32_t *)(gdt_table + idx);
2736 entry_1 = tswap32(lp[0]);
2737 entry_2 = tswap32(lp[1]);
2739 read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
2740 contents = (entry_2 >> 10) & 3;
2741 seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
2742 seg_32bit = (entry_2 >> 22) & 1;
2743 limit_in_pages = (entry_2 >> 23) & 1;
2744 useable = (entry_2 >> 20) & 1;
2745 #ifdef TARGET_ABI32
2746 lm = 0;
2747 #else
2748 lm = (entry_2 >> 21) & 1;
2749 #endif
2750 flags = (seg_32bit << 0) | (contents << 1) |
2751 (read_exec_only << 3) | (limit_in_pages << 4) |
2752 (seg_not_present << 5) | (useable << 6) | (lm << 7);
2753 limit = (entry_1 & 0xffff) | (entry_2 & 0xf0000);
2754 base_addr = (entry_1 >> 16) |
2755 (entry_2 & 0xff000000) |
2756 ((entry_2 & 0xff) << 16);
2757 target_ldt_info->base_addr = tswapl(base_addr);
2758 target_ldt_info->limit = tswap32(limit);
2759 target_ldt_info->flags = tswap32(flags);
2760 unlock_user_struct(target_ldt_info, ptr, 1);
2761 return 0;
2763 #endif /* TARGET_I386 && TARGET_ABI32 */
2765 #ifndef TARGET_ABI32
2766 static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
2768 abi_long ret;
2769 abi_ulong val;
2770 int idx;
2772 switch(code) {
2773 case TARGET_ARCH_SET_GS:
2774 case TARGET_ARCH_SET_FS:
2775 if (code == TARGET_ARCH_SET_GS)
2776 idx = R_GS;
2777 else
2778 idx = R_FS;
2779 cpu_x86_load_seg(env, idx, 0);
2780 env->segs[idx].base = addr;
2781 break;
2782 case TARGET_ARCH_GET_GS:
2783 case TARGET_ARCH_GET_FS:
2784 if (code == TARGET_ARCH_GET_GS)
2785 idx = R_GS;
2786 else
2787 idx = R_FS;
2788 val = env->segs[idx].base;
2789 if (put_user(val, addr, abi_ulong))
2790 return -TARGET_EFAULT;
2791 break;
2792 default:
2793 ret = -TARGET_EINVAL;
2794 break;
2796 return 0;
2798 #endif
2800 #endif /* defined(TARGET_I386) */
2802 #if defined(USE_NPTL)
2804 #define NEW_STACK_SIZE PTHREAD_STACK_MIN
2806 static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
2807 typedef struct {
2808 CPUState *env;
2809 pthread_mutex_t mutex;
2810 pthread_cond_t cond;
2811 pthread_t thread;
2812 uint32_t tid;
2813 abi_ulong child_tidptr;
2814 abi_ulong parent_tidptr;
2815 sigset_t sigmask;
2816 } new_thread_info;
2818 static void *clone_func(void *arg)
2820 new_thread_info *info = arg;
2821 CPUState *env;
2823 env = info->env;
2824 thread_env = env;
2825 info->tid = gettid();
2826 if (info->child_tidptr)
2827 put_user_u32(info->tid, info->child_tidptr);
2828 if (info->parent_tidptr)
2829 put_user_u32(info->tid, info->parent_tidptr);
2830 /* Enable signals. */
2831 sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
2832 /* Signal to the parent that we're ready. */
2833 pthread_mutex_lock(&info->mutex);
2834 pthread_cond_broadcast(&info->cond);
2835 pthread_mutex_unlock(&info->mutex);
2836 /* Wait until the parent has finshed initializing the tls state. */
2837 pthread_mutex_lock(&clone_lock);
2838 pthread_mutex_unlock(&clone_lock);
2839 cpu_loop(env);
2840 /* never exits */
2841 return NULL;
2843 #else
2844 /* this stack is the equivalent of the kernel stack associated with a
2845 thread/process */
2846 #define NEW_STACK_SIZE 8192
2848 static int clone_func(void *arg)
2850 CPUState *env = arg;
2851 cpu_loop(env);
2852 /* never exits */
2853 return 0;
2855 #endif
2857 /* do_fork() Must return host values and target errnos (unlike most
2858 do_*() functions). */
2859 static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
2860 abi_ulong parent_tidptr, target_ulong newtls,
2861 abi_ulong child_tidptr)
2863 int ret;
2864 TaskState *ts;
2865 uint8_t *new_stack;
2866 CPUState *new_env;
2867 #if defined(USE_NPTL)
2868 unsigned int nptl_flags;
2869 sigset_t sigmask;
2870 #endif
2872 /* Emulate vfork() with fork() */
2873 if (flags & CLONE_VFORK)
2874 flags &= ~(CLONE_VFORK | CLONE_VM);
2876 if (flags & CLONE_VM) {
2877 #if defined(USE_NPTL)
2878 new_thread_info info;
2879 pthread_attr_t attr;
2880 #endif
2881 ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
2882 init_task_state(ts);
2883 new_stack = ts->stack;
2884 /* we create a new CPU instance. */
2885 new_env = cpu_copy(env);
2886 /* Init regs that differ from the parent. */
2887 cpu_clone_regs(new_env, newsp);
2888 new_env->opaque = ts;
2889 #if defined(USE_NPTL)
2890 nptl_flags = flags;
2891 flags &= ~CLONE_NPTL_FLAGS2;
2893 /* TODO: Implement CLONE_CHILD_CLEARTID. */
2894 if (nptl_flags & CLONE_SETTLS)
2895 cpu_set_tls (new_env, newtls);
2897 /* Grab a mutex so that thread setup appears atomic. */
2898 pthread_mutex_lock(&clone_lock);
2900 memset(&info, 0, sizeof(info));
2901 pthread_mutex_init(&info.mutex, NULL);
2902 pthread_mutex_lock(&info.mutex);
2903 pthread_cond_init(&info.cond, NULL);
2904 info.env = new_env;
2905 if (nptl_flags & CLONE_CHILD_SETTID)
2906 info.child_tidptr = child_tidptr;
2907 if (nptl_flags & CLONE_PARENT_SETTID)
2908 info.parent_tidptr = parent_tidptr;
2910 ret = pthread_attr_init(&attr);
2911 ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE);
2912 /* It is not safe to deliver signals until the child has finished
2913 initializing, so temporarily block all signals. */
2914 sigfillset(&sigmask);
2915 sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
2917 ret = pthread_create(&info.thread, &attr, clone_func, &info);
2919 sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
2920 pthread_attr_destroy(&attr);
2921 if (ret == 0) {
2922 /* Wait for the child to initialize. */
2923 pthread_cond_wait(&info.cond, &info.mutex);
2924 ret = info.tid;
2925 if (flags & CLONE_PARENT_SETTID)
2926 put_user_u32(ret, parent_tidptr);
2927 } else {
2928 ret = -1;
2930 pthread_mutex_unlock(&info.mutex);
2931 pthread_cond_destroy(&info.cond);
2932 pthread_mutex_destroy(&info.mutex);
2933 pthread_mutex_unlock(&clone_lock);
2934 #else
2935 if (flags & CLONE_NPTL_FLAGS2)
2936 return -EINVAL;
2937 /* This is probably going to die very quickly, but do it anyway. */
2938 #ifdef __ia64__
2939 ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
2940 #else
2941 ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
2942 #endif
2943 #endif
2944 } else {
2945 /* if no CLONE_VM, we consider it is a fork */
2946 if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
2947 return -EINVAL;
2948 fork_start();
2949 ret = fork();
2950 #if defined(USE_NPTL)
2951 /* There is a race condition here. The parent process could
2952 theoretically read the TID in the child process before the child
2953 tid is set. This would require using either ptrace
2954 (not implemented) or having *_tidptr to point at a shared memory
2955 mapping. We can't repeat the spinlock hack used above because
2956 the child process gets its own copy of the lock. */
2957 if (ret == 0) {
2958 cpu_clone_regs(env, newsp);
2959 fork_end(1);
2960 /* Child Process. */
2961 if (flags & CLONE_CHILD_SETTID)
2962 put_user_u32(gettid(), child_tidptr);
2963 if (flags & CLONE_PARENT_SETTID)
2964 put_user_u32(gettid(), parent_tidptr);
2965 ts = (TaskState *)env->opaque;
2966 if (flags & CLONE_SETTLS)
2967 cpu_set_tls (env, newtls);
2968 /* TODO: Implement CLONE_CHILD_CLEARTID. */
2969 } else {
2970 fork_end(0);
2972 #else
2973 if (ret == 0) {
2974 cpu_clone_regs(env, newsp);
2976 #endif
2978 return ret;
2981 static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
2983 struct flock fl;
2984 struct target_flock *target_fl;
2985 struct flock64 fl64;
2986 struct target_flock64 *target_fl64;
2987 abi_long ret;
2989 switch(cmd) {
2990 case TARGET_F_GETLK:
2991 if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
2992 return -TARGET_EFAULT;
2993 fl.l_type = tswap16(target_fl->l_type);
2994 fl.l_whence = tswap16(target_fl->l_whence);
2995 fl.l_start = tswapl(target_fl->l_start);
2996 fl.l_len = tswapl(target_fl->l_len);
2997 fl.l_pid = tswapl(target_fl->l_pid);
2998 unlock_user_struct(target_fl, arg, 0);
2999 ret = get_errno(fcntl(fd, cmd, &fl));
3000 if (ret == 0) {
3001 if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
3002 return -TARGET_EFAULT;
3003 target_fl->l_type = tswap16(fl.l_type);
3004 target_fl->l_whence = tswap16(fl.l_whence);
3005 target_fl->l_start = tswapl(fl.l_start);
3006 target_fl->l_len = tswapl(fl.l_len);
3007 target_fl->l_pid = tswapl(fl.l_pid);
3008 unlock_user_struct(target_fl, arg, 1);
3010 break;
3012 case TARGET_F_SETLK:
3013 case TARGET_F_SETLKW:
3014 if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3015 return -TARGET_EFAULT;
3016 fl.l_type = tswap16(target_fl->l_type);
3017 fl.l_whence = tswap16(target_fl->l_whence);
3018 fl.l_start = tswapl(target_fl->l_start);
3019 fl.l_len = tswapl(target_fl->l_len);
3020 fl.l_pid = tswapl(target_fl->l_pid);
3021 unlock_user_struct(target_fl, arg, 0);
3022 ret = get_errno(fcntl(fd, cmd, &fl));
3023 break;
3025 case TARGET_F_GETLK64:
3026 if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3027 return -TARGET_EFAULT;
3028 fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3029 fl64.l_whence = tswap16(target_fl64->l_whence);
3030 fl64.l_start = tswapl(target_fl64->l_start);
3031 fl64.l_len = tswapl(target_fl64->l_len);
3032 fl64.l_pid = tswap16(target_fl64->l_pid);
3033 unlock_user_struct(target_fl64, arg, 0);
3034 ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
3035 if (ret == 0) {
3036 if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
3037 return -TARGET_EFAULT;
3038 target_fl64->l_type = tswap16(fl64.l_type) >> 1;
3039 target_fl64->l_whence = tswap16(fl64.l_whence);
3040 target_fl64->l_start = tswapl(fl64.l_start);
3041 target_fl64->l_len = tswapl(fl64.l_len);
3042 target_fl64->l_pid = tswapl(fl64.l_pid);
3043 unlock_user_struct(target_fl64, arg, 1);
3045 break;
3046 case TARGET_F_SETLK64:
3047 case TARGET_F_SETLKW64:
3048 if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3049 return -TARGET_EFAULT;
3050 fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3051 fl64.l_whence = tswap16(target_fl64->l_whence);
3052 fl64.l_start = tswapl(target_fl64->l_start);
3053 fl64.l_len = tswapl(target_fl64->l_len);
3054 fl64.l_pid = tswap16(target_fl64->l_pid);
3055 unlock_user_struct(target_fl64, arg, 0);
3056 ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
3057 break;
3059 case F_GETFL:
3060 ret = get_errno(fcntl(fd, cmd, arg));
3061 if (ret >= 0) {
3062 ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
3064 break;
3066 case F_SETFL:
3067 ret = get_errno(fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
3068 break;
3070 default:
3071 ret = get_errno(fcntl(fd, cmd, arg));
3072 break;
3074 return ret;
3077 #ifdef USE_UID16
3079 static inline int high2lowuid(int uid)
3081 if (uid > 65535)
3082 return 65534;
3083 else
3084 return uid;
3087 static inline int high2lowgid(int gid)
3089 if (gid > 65535)
3090 return 65534;
3091 else
3092 return gid;
3095 static inline int low2highuid(int uid)
3097 if ((int16_t)uid == -1)
3098 return -1;
3099 else
3100 return uid;
3103 static inline int low2highgid(int gid)
3105 if ((int16_t)gid == -1)
3106 return -1;
3107 else
3108 return gid;
3111 #endif /* USE_UID16 */
3113 void syscall_init(void)
3115 IOCTLEntry *ie;
3116 const argtype *arg_type;
3117 int size;
3118 int i;
3120 #define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3121 #define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3122 #include "syscall_types.h"
3123 #undef STRUCT
3124 #undef STRUCT_SPECIAL
3126 /* we patch the ioctl size if necessary. We rely on the fact that
3127 no ioctl has all the bits at '1' in the size field */
3128 ie = ioctl_entries;
3129 while (ie->target_cmd != 0) {
3130 if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
3131 TARGET_IOC_SIZEMASK) {
3132 arg_type = ie->arg_type;
3133 if (arg_type[0] != TYPE_PTR) {
3134 fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
3135 ie->target_cmd);
3136 exit(1);
3138 arg_type++;
3139 size = thunk_type_size(arg_type, 0);
3140 ie->target_cmd = (ie->target_cmd &
3141 ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
3142 (size << TARGET_IOC_SIZESHIFT);
3145 /* Build target_to_host_errno_table[] table from
3146 * host_to_target_errno_table[]. */
3147 for (i=0; i < ERRNO_TABLE_SIZE; i++)
3148 target_to_host_errno_table[host_to_target_errno_table[i]] = i;
3150 /* automatic consistency check if same arch */
3151 #if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
3152 (defined(__x86_64__) && defined(TARGET_X86_64))
3153 if (unlikely(ie->target_cmd != ie->host_cmd)) {
3154 fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
3155 ie->name, ie->target_cmd, ie->host_cmd);
3157 #endif
3158 ie++;
3162 #if TARGET_ABI_BITS == 32
3163 static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
3165 #ifdef TARGET_WORDS_BIGENDIAN
3166 return ((uint64_t)word0 << 32) | word1;
3167 #else
3168 return ((uint64_t)word1 << 32) | word0;
3169 #endif
3171 #else /* TARGET_ABI_BITS == 32 */
3172 static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
3174 return word0;
3176 #endif /* TARGET_ABI_BITS != 32 */
3178 #ifdef TARGET_NR_truncate64
3179 static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
3180 abi_long arg2,
3181 abi_long arg3,
3182 abi_long arg4)
3184 #ifdef TARGET_ARM
3185 if (((CPUARMState *)cpu_env)->eabi)
3187 arg2 = arg3;
3188 arg3 = arg4;
3190 #endif
3191 return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
3193 #endif
3195 #ifdef TARGET_NR_ftruncate64
3196 static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
3197 abi_long arg2,
3198 abi_long arg3,
3199 abi_long arg4)
3201 #ifdef TARGET_ARM
3202 if (((CPUARMState *)cpu_env)->eabi)
3204 arg2 = arg3;
3205 arg3 = arg4;
3207 #endif
3208 return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
3210 #endif
3212 static inline abi_long target_to_host_timespec(struct timespec *host_ts,
3213 abi_ulong target_addr)
3215 struct target_timespec *target_ts;
3217 if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
3218 return -TARGET_EFAULT;
3219 host_ts->tv_sec = tswapl(target_ts->tv_sec);
3220 host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
3221 unlock_user_struct(target_ts, target_addr, 0);
3222 return 0;
3225 static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3226 struct timespec *host_ts)
3228 struct target_timespec *target_ts;
3230 if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
3231 return -TARGET_EFAULT;
3232 target_ts->tv_sec = tswapl(host_ts->tv_sec);
3233 target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
3234 unlock_user_struct(target_ts, target_addr, 1);
3235 return 0;
3238 #ifdef TARGET_NR_stat64
3239 static inline abi_long host_to_target_stat64(void *cpu_env,
3240 abi_ulong target_addr,
3241 struct stat *host_st)
3243 #ifdef TARGET_ARM
3244 if (((CPUARMState *)cpu_env)->eabi) {
3245 struct target_eabi_stat64 *target_st;
3247 if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3248 return -TARGET_EFAULT;
3249 memset(target_st, 0, sizeof(struct target_eabi_stat64));
3250 __put_user(host_st->st_dev, &target_st->st_dev);
3251 __put_user(host_st->st_ino, &target_st->st_ino);
3252 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3253 __put_user(host_st->st_ino, &target_st->__st_ino);
3254 #endif
3255 __put_user(host_st->st_mode, &target_st->st_mode);
3256 __put_user(host_st->st_nlink, &target_st->st_nlink);
3257 __put_user(host_st->st_uid, &target_st->st_uid);
3258 __put_user(host_st->st_gid, &target_st->st_gid);
3259 __put_user(host_st->st_rdev, &target_st->st_rdev);
3260 __put_user(host_st->st_size, &target_st->st_size);
3261 __put_user(host_st->st_blksize, &target_st->st_blksize);
3262 __put_user(host_st->st_blocks, &target_st->st_blocks);
3263 __put_user(host_st->st_atime, &target_st->target_st_atime);
3264 __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3265 __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3266 unlock_user_struct(target_st, target_addr, 1);
3267 } else
3268 #endif
3270 struct target_stat64 *target_st;
3272 if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3273 return -TARGET_EFAULT;
3274 memset(target_st, 0, sizeof(struct target_stat64));
3275 __put_user(host_st->st_dev, &target_st->st_dev);
3276 __put_user(host_st->st_ino, &target_st->st_ino);
3277 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3278 __put_user(host_st->st_ino, &target_st->__st_ino);
3279 #endif
3280 __put_user(host_st->st_mode, &target_st->st_mode);
3281 __put_user(host_st->st_nlink, &target_st->st_nlink);
3282 __put_user(host_st->st_uid, &target_st->st_uid);
3283 __put_user(host_st->st_gid, &target_st->st_gid);
3284 __put_user(host_st->st_rdev, &target_st->st_rdev);
3285 /* XXX: better use of kernel struct */
3286 __put_user(host_st->st_size, &target_st->st_size);
3287 __put_user(host_st->st_blksize, &target_st->st_blksize);
3288 __put_user(host_st->st_blocks, &target_st->st_blocks);
3289 __put_user(host_st->st_atime, &target_st->target_st_atime);
3290 __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3291 __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3292 unlock_user_struct(target_st, target_addr, 1);
3295 return 0;
3297 #endif
3299 #if defined(USE_NPTL)
3300 /* ??? Using host futex calls even when target atomic operations
3301 are not really atomic probably breaks things. However implementing
3302 futexes locally would make futexes shared between multiple processes
3303 tricky. However they're probably useless because guest atomic
3304 operations won't work either. */
3305 static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
3306 target_ulong uaddr2, int val3)
3308 struct timespec ts, *pts;
3310 /* ??? We assume FUTEX_* constants are the same on both host
3311 and target. */
3312 switch (op) {
3313 case FUTEX_WAIT:
3314 if (timeout) {
3315 pts = &ts;
3316 target_to_host_timespec(pts, timeout);
3317 } else {
3318 pts = NULL;
3320 return get_errno(sys_futex(g2h(uaddr), FUTEX_WAIT, tswap32(val),
3321 pts, NULL, 0));
3322 case FUTEX_WAKE:
3323 return get_errno(sys_futex(g2h(uaddr), FUTEX_WAKE, val, NULL, NULL, 0));
3324 case FUTEX_FD:
3325 return get_errno(sys_futex(g2h(uaddr), FUTEX_FD, val, NULL, NULL, 0));
3326 case FUTEX_REQUEUE:
3327 return get_errno(sys_futex(g2h(uaddr), FUTEX_REQUEUE, val,
3328 NULL, g2h(uaddr2), 0));
3329 case FUTEX_CMP_REQUEUE:
3330 return get_errno(sys_futex(g2h(uaddr), FUTEX_CMP_REQUEUE, val,
3331 NULL, g2h(uaddr2), tswap32(val3)));
3332 default:
3333 return -TARGET_ENOSYS;
3336 #endif
3338 int get_osversion(void)
3340 static int osversion;
3341 struct new_utsname buf;
3342 const char *s;
3343 int i, n, tmp;
3344 if (osversion)
3345 return osversion;
3346 if (qemu_uname_release && *qemu_uname_release) {
3347 s = qemu_uname_release;
3348 } else {
3349 if (sys_uname(&buf))
3350 return 0;
3351 s = buf.release;
3353 tmp = 0;
3354 for (i = 0; i < 3; i++) {
3355 n = 0;
3356 while (*s >= '0' && *s <= '9') {
3357 n *= 10;
3358 n += *s - '0';
3359 s++;
3361 tmp = (tmp << 8) + n;
3362 if (*s == '.')
3363 s++;
3365 osversion = tmp;
3366 return osversion;
3369 /* do_syscall() should always have a single exit point at the end so
3370 that actions, such as logging of syscall results, can be performed.
3371 All errnos that do_syscall() returns must be -TARGET_<errcode>. */
3372 abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3373 abi_long arg2, abi_long arg3, abi_long arg4,
3374 abi_long arg5, abi_long arg6)
3376 abi_long ret;
3377 struct stat st;
3378 struct statfs stfs;
3379 void *p;
3381 #ifdef DEBUG
3382 gemu_log("syscall %d", num);
3383 #endif
3384 if(do_strace)
3385 print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
3387 switch(num) {
3388 case TARGET_NR_exit:
3389 #ifdef HAVE_GPROF
3390 _mcleanup();
3391 #endif
3392 gdb_exit(cpu_env, arg1);
3393 /* XXX: should free thread stack and CPU env */
3394 sys_exit(arg1);
3395 ret = 0; /* avoid warning */
3396 break;
3397 case TARGET_NR_read:
3398 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
3399 goto efault;
3400 ret = get_errno(read(arg1, p, arg3));
3401 unlock_user(p, arg2, ret);
3402 break;
3403 case TARGET_NR_write:
3404 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
3405 goto efault;
3406 ret = get_errno(write(arg1, p, arg3));
3407 unlock_user(p, arg2, 0);
3408 break;
3409 case TARGET_NR_open:
3410 if (!(p = lock_user_string(arg1)))
3411 goto efault;
3412 ret = get_errno(open(path(p),
3413 target_to_host_bitmask(arg2, fcntl_flags_tbl),
3414 arg3));
3415 unlock_user(p, arg1, 0);
3416 break;
3417 #if defined(TARGET_NR_openat) && defined(__NR_openat)
3418 case TARGET_NR_openat:
3419 if (!(p = lock_user_string(arg2)))
3420 goto efault;
3421 ret = get_errno(sys_openat(arg1,
3422 path(p),
3423 target_to_host_bitmask(arg3, fcntl_flags_tbl),
3424 arg4));
3425 unlock_user(p, arg2, 0);
3426 break;
3427 #endif
3428 case TARGET_NR_close:
3429 ret = get_errno(close(arg1));
3430 break;
3431 case TARGET_NR_brk:
3432 ret = do_brk(arg1);
3433 break;
3434 case TARGET_NR_fork:
3435 ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
3436 break;
3437 #ifdef TARGET_NR_waitpid
3438 case TARGET_NR_waitpid:
3440 int status;
3441 ret = get_errno(waitpid(arg1, &status, arg3));
3442 if (!is_error(ret) && arg2
3443 && put_user_s32(status, arg2))
3444 goto efault;
3446 break;
3447 #endif
3448 #ifdef TARGET_NR_waitid
3449 case TARGET_NR_waitid:
3451 siginfo_t info;
3452 info.si_pid = 0;
3453 ret = get_errno(waitid(arg1, arg2, &info, arg4));
3454 if (!is_error(ret) && arg3 && info.si_pid != 0) {
3455 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
3456 goto efault;
3457 host_to_target_siginfo(p, &info);
3458 unlock_user(p, arg3, sizeof(target_siginfo_t));
3461 break;
3462 #endif
3463 #ifdef TARGET_NR_creat /* not on alpha */
3464 case TARGET_NR_creat:
3465 if (!(p = lock_user_string(arg1)))
3466 goto efault;
3467 ret = get_errno(creat(p, arg2));
3468 unlock_user(p, arg1, 0);
3469 break;
3470 #endif
3471 case TARGET_NR_link:
3473 void * p2;
3474 p = lock_user_string(arg1);
3475 p2 = lock_user_string(arg2);
3476 if (!p || !p2)
3477 ret = -TARGET_EFAULT;
3478 else
3479 ret = get_errno(link(p, p2));
3480 unlock_user(p2, arg2, 0);
3481 unlock_user(p, arg1, 0);
3483 break;
3484 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
3485 case TARGET_NR_linkat:
3487 void * p2 = NULL;
3488 if (!arg2 || !arg4)
3489 goto efault;
3490 p = lock_user_string(arg2);
3491 p2 = lock_user_string(arg4);
3492 if (!p || !p2)
3493 ret = -TARGET_EFAULT;
3494 else
3495 ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
3496 unlock_user(p, arg2, 0);
3497 unlock_user(p2, arg4, 0);
3499 break;
3500 #endif
3501 case TARGET_NR_unlink:
3502 if (!(p = lock_user_string(arg1)))
3503 goto efault;
3504 ret = get_errno(unlink(p));
3505 unlock_user(p, arg1, 0);
3506 break;
3507 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
3508 case TARGET_NR_unlinkat:
3509 if (!(p = lock_user_string(arg2)))
3510 goto efault;
3511 ret = get_errno(sys_unlinkat(arg1, p, arg3));
3512 unlock_user(p, arg2, 0);
3513 break;
3514 #endif
3515 case TARGET_NR_execve:
3517 char **argp, **envp;
3518 int argc, envc;
3519 abi_ulong gp;
3520 abi_ulong guest_argp;
3521 abi_ulong guest_envp;
3522 abi_ulong addr;
3523 char **q;
3525 argc = 0;
3526 guest_argp = arg2;
3527 for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
3528 if (get_user_ual(addr, gp))
3529 goto efault;
3530 if (!addr)
3531 break;
3532 argc++;
3534 envc = 0;
3535 guest_envp = arg3;
3536 for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
3537 if (get_user_ual(addr, gp))
3538 goto efault;
3539 if (!addr)
3540 break;
3541 envc++;
3544 argp = alloca((argc + 1) * sizeof(void *));
3545 envp = alloca((envc + 1) * sizeof(void *));
3547 for (gp = guest_argp, q = argp; gp;
3548 gp += sizeof(abi_ulong), q++) {
3549 if (get_user_ual(addr, gp))
3550 goto execve_efault;
3551 if (!addr)
3552 break;
3553 if (!(*q = lock_user_string(addr)))
3554 goto execve_efault;
3556 *q = NULL;
3558 for (gp = guest_envp, q = envp; gp;
3559 gp += sizeof(abi_ulong), q++) {
3560 if (get_user_ual(addr, gp))
3561 goto execve_efault;
3562 if (!addr)
3563 break;
3564 if (!(*q = lock_user_string(addr)))
3565 goto execve_efault;
3567 *q = NULL;
3569 if (!(p = lock_user_string(arg1)))
3570 goto execve_efault;
3571 ret = get_errno(execve(p, argp, envp));
3572 unlock_user(p, arg1, 0);
3574 goto execve_end;
3576 execve_efault:
3577 ret = -TARGET_EFAULT;
3579 execve_end:
3580 for (gp = guest_argp, q = argp; *q;
3581 gp += sizeof(abi_ulong), q++) {
3582 if (get_user_ual(addr, gp)
3583 || !addr)
3584 break;
3585 unlock_user(*q, addr, 0);
3587 for (gp = guest_envp, q = envp; *q;
3588 gp += sizeof(abi_ulong), q++) {
3589 if (get_user_ual(addr, gp)
3590 || !addr)
3591 break;
3592 unlock_user(*q, addr, 0);
3595 break;
3596 case TARGET_NR_chdir:
3597 if (!(p = lock_user_string(arg1)))
3598 goto efault;
3599 ret = get_errno(chdir(p));
3600 unlock_user(p, arg1, 0);
3601 break;
3602 #ifdef TARGET_NR_time
3603 case TARGET_NR_time:
3605 time_t host_time;
3606 ret = get_errno(time(&host_time));
3607 if (!is_error(ret)
3608 && arg1
3609 && put_user_sal(host_time, arg1))
3610 goto efault;
3612 break;
3613 #endif
3614 case TARGET_NR_mknod:
3615 if (!(p = lock_user_string(arg1)))
3616 goto efault;
3617 ret = get_errno(mknod(p, arg2, arg3));
3618 unlock_user(p, arg1, 0);
3619 break;
3620 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
3621 case TARGET_NR_mknodat:
3622 if (!(p = lock_user_string(arg2)))
3623 goto efault;
3624 ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
3625 unlock_user(p, arg2, 0);
3626 break;
3627 #endif
3628 case TARGET_NR_chmod:
3629 if (!(p = lock_user_string(arg1)))
3630 goto efault;
3631 ret = get_errno(chmod(p, arg2));
3632 unlock_user(p, arg1, 0);
3633 break;
3634 #ifdef TARGET_NR_break
3635 case TARGET_NR_break:
3636 goto unimplemented;
3637 #endif
3638 #ifdef TARGET_NR_oldstat
3639 case TARGET_NR_oldstat:
3640 goto unimplemented;
3641 #endif
3642 case TARGET_NR_lseek:
3643 ret = get_errno(lseek(arg1, arg2, arg3));
3644 break;
3645 #ifdef TARGET_NR_getxpid
3646 case TARGET_NR_getxpid:
3647 #else
3648 case TARGET_NR_getpid:
3649 #endif
3650 ret = get_errno(getpid());
3651 break;
3652 case TARGET_NR_mount:
3654 /* need to look at the data field */
3655 void *p2, *p3;
3656 p = lock_user_string(arg1);
3657 p2 = lock_user_string(arg2);
3658 p3 = lock_user_string(arg3);
3659 if (!p || !p2 || !p3)
3660 ret = -TARGET_EFAULT;
3661 else
3662 /* FIXME - arg5 should be locked, but it isn't clear how to
3663 * do that since it's not guaranteed to be a NULL-terminated
3664 * string.
3666 ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
3667 unlock_user(p, arg1, 0);
3668 unlock_user(p2, arg2, 0);
3669 unlock_user(p3, arg3, 0);
3670 break;
3672 #ifdef TARGET_NR_umount
3673 case TARGET_NR_umount:
3674 if (!(p = lock_user_string(arg1)))
3675 goto efault;
3676 ret = get_errno(umount(p));
3677 unlock_user(p, arg1, 0);
3678 break;
3679 #endif
3680 #ifdef TARGET_NR_stime /* not on alpha */
3681 case TARGET_NR_stime:
3683 time_t host_time;
3684 if (get_user_sal(host_time, arg1))
3685 goto efault;
3686 ret = get_errno(stime(&host_time));
3688 break;
3689 #endif
3690 case TARGET_NR_ptrace:
3691 goto unimplemented;
3692 #ifdef TARGET_NR_alarm /* not on alpha */
3693 case TARGET_NR_alarm:
3694 ret = alarm(arg1);
3695 break;
3696 #endif
3697 #ifdef TARGET_NR_oldfstat
3698 case TARGET_NR_oldfstat:
3699 goto unimplemented;
3700 #endif
3701 #ifdef TARGET_NR_pause /* not on alpha */
3702 case TARGET_NR_pause:
3703 ret = get_errno(pause());
3704 break;
3705 #endif
3706 #ifdef TARGET_NR_utime
3707 case TARGET_NR_utime:
3709 struct utimbuf tbuf, *host_tbuf;
3710 struct target_utimbuf *target_tbuf;
3711 if (arg2) {
3712 if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
3713 goto efault;
3714 tbuf.actime = tswapl(target_tbuf->actime);
3715 tbuf.modtime = tswapl(target_tbuf->modtime);
3716 unlock_user_struct(target_tbuf, arg2, 0);
3717 host_tbuf = &tbuf;
3718 } else {
3719 host_tbuf = NULL;
3721 if (!(p = lock_user_string(arg1)))
3722 goto efault;
3723 ret = get_errno(utime(p, host_tbuf));
3724 unlock_user(p, arg1, 0);
3726 break;
3727 #endif
3728 case TARGET_NR_utimes:
3730 struct timeval *tvp, tv[2];
3731 if (arg2) {
3732 if (copy_from_user_timeval(&tv[0], arg2)
3733 || copy_from_user_timeval(&tv[1],
3734 arg2 + sizeof(struct target_timeval)))
3735 goto efault;
3736 tvp = tv;
3737 } else {
3738 tvp = NULL;
3740 if (!(p = lock_user_string(arg1)))
3741 goto efault;
3742 ret = get_errno(utimes(p, tvp));
3743 unlock_user(p, arg1, 0);
3745 break;
3746 #if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
3747 case TARGET_NR_futimesat:
3749 struct timeval *tvp, tv[2];
3750 if (arg3) {
3751 if (copy_from_user_timeval(&tv[0], arg3)
3752 || copy_from_user_timeval(&tv[1],
3753 arg3 + sizeof(struct target_timeval)))
3754 goto efault;
3755 tvp = tv;
3756 } else {
3757 tvp = NULL;
3759 if (!(p = lock_user_string(arg2)))
3760 goto efault;
3761 ret = get_errno(sys_futimesat(arg1, path(p), tvp));
3762 unlock_user(p, arg2, 0);
3764 break;
3765 #endif
3766 #ifdef TARGET_NR_stty
3767 case TARGET_NR_stty:
3768 goto unimplemented;
3769 #endif
3770 #ifdef TARGET_NR_gtty
3771 case TARGET_NR_gtty:
3772 goto unimplemented;
3773 #endif
3774 case TARGET_NR_access:
3775 if (!(p = lock_user_string(arg1)))
3776 goto efault;
3777 ret = get_errno(access(p, arg2));
3778 unlock_user(p, arg1, 0);
3779 break;
3780 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
3781 case TARGET_NR_faccessat:
3782 if (!(p = lock_user_string(arg2)))
3783 goto efault;
3784 ret = get_errno(sys_faccessat(arg1, p, arg3, arg4));
3785 unlock_user(p, arg2, 0);
3786 break;
3787 #endif
3788 #ifdef TARGET_NR_nice /* not on alpha */
3789 case TARGET_NR_nice:
3790 ret = get_errno(nice(arg1));
3791 break;
3792 #endif
3793 #ifdef TARGET_NR_ftime
3794 case TARGET_NR_ftime:
3795 goto unimplemented;
3796 #endif
3797 case TARGET_NR_sync:
3798 sync();
3799 ret = 0;
3800 break;
3801 case TARGET_NR_kill:
3802 ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
3803 break;
3804 case TARGET_NR_rename:
3806 void *p2;
3807 p = lock_user_string(arg1);
3808 p2 = lock_user_string(arg2);
3809 if (!p || !p2)
3810 ret = -TARGET_EFAULT;
3811 else
3812 ret = get_errno(rename(p, p2));
3813 unlock_user(p2, arg2, 0);
3814 unlock_user(p, arg1, 0);
3816 break;
3817 #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
3818 case TARGET_NR_renameat:
3820 void *p2;
3821 p = lock_user_string(arg2);
3822 p2 = lock_user_string(arg4);
3823 if (!p || !p2)
3824 ret = -TARGET_EFAULT;
3825 else
3826 ret = get_errno(sys_renameat(arg1, p, arg3, p2));
3827 unlock_user(p2, arg4, 0);
3828 unlock_user(p, arg2, 0);
3830 break;
3831 #endif
3832 case TARGET_NR_mkdir:
3833 if (!(p = lock_user_string(arg1)))
3834 goto efault;
3835 ret = get_errno(mkdir(p, arg2));
3836 unlock_user(p, arg1, 0);
3837 break;
3838 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
3839 case TARGET_NR_mkdirat:
3840 if (!(p = lock_user_string(arg2)))
3841 goto efault;
3842 ret = get_errno(sys_mkdirat(arg1, p, arg3));
3843 unlock_user(p, arg2, 0);
3844 break;
3845 #endif
3846 case TARGET_NR_rmdir:
3847 if (!(p = lock_user_string(arg1)))
3848 goto efault;
3849 ret = get_errno(rmdir(p));
3850 unlock_user(p, arg1, 0);
3851 break;
3852 case TARGET_NR_dup:
3853 ret = get_errno(dup(arg1));
3854 break;
3855 case TARGET_NR_pipe:
3857 int host_pipe[2];
3858 ret = get_errno(pipe(host_pipe));
3859 if (!is_error(ret)) {
3860 #if defined(TARGET_MIPS)
3861 CPUMIPSState *env = (CPUMIPSState*)cpu_env;
3862 env->active_tc.gpr[3] = host_pipe[1];
3863 ret = host_pipe[0];
3864 #elif defined(TARGET_SH4)
3865 ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
3866 ret = host_pipe[0];
3867 #else
3868 if (put_user_s32(host_pipe[0], arg1)
3869 || put_user_s32(host_pipe[1], arg1 + sizeof(host_pipe[0])))
3870 goto efault;
3871 #endif
3874 break;
3875 case TARGET_NR_times:
3877 struct target_tms *tmsp;
3878 struct tms tms;
3879 ret = get_errno(times(&tms));
3880 if (arg1) {
3881 tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
3882 if (!tmsp)
3883 goto efault;
3884 tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
3885 tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
3886 tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
3887 tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime));
3889 if (!is_error(ret))
3890 ret = host_to_target_clock_t(ret);
3892 break;
3893 #ifdef TARGET_NR_prof
3894 case TARGET_NR_prof:
3895 goto unimplemented;
3896 #endif
3897 #ifdef TARGET_NR_signal
3898 case TARGET_NR_signal:
3899 goto unimplemented;
3900 #endif
3901 case TARGET_NR_acct:
3902 if (!(p = lock_user_string(arg1)))
3903 goto efault;
3904 ret = get_errno(acct(path(p)));
3905 unlock_user(p, arg1, 0);
3906 break;
3907 #ifdef TARGET_NR_umount2 /* not on alpha */
3908 case TARGET_NR_umount2:
3909 if (!(p = lock_user_string(arg1)))
3910 goto efault;
3911 ret = get_errno(umount2(p, arg2));
3912 unlock_user(p, arg1, 0);
3913 break;
3914 #endif
3915 #ifdef TARGET_NR_lock
3916 case TARGET_NR_lock:
3917 goto unimplemented;
3918 #endif
3919 case TARGET_NR_ioctl:
3920 ret = do_ioctl(arg1, arg2, arg3);
3921 break;
3922 case TARGET_NR_fcntl:
3923 ret = do_fcntl(arg1, arg2, arg3);
3924 break;
3925 #ifdef TARGET_NR_mpx
3926 case TARGET_NR_mpx:
3927 goto unimplemented;
3928 #endif
3929 case TARGET_NR_setpgid:
3930 ret = get_errno(setpgid(arg1, arg2));
3931 break;
3932 #ifdef TARGET_NR_ulimit
3933 case TARGET_NR_ulimit:
3934 goto unimplemented;
3935 #endif
3936 #ifdef TARGET_NR_oldolduname
3937 case TARGET_NR_oldolduname:
3938 goto unimplemented;
3939 #endif
3940 case TARGET_NR_umask:
3941 ret = get_errno(umask(arg1));
3942 break;
3943 case TARGET_NR_chroot:
3944 if (!(p = lock_user_string(arg1)))
3945 goto efault;
3946 ret = get_errno(chroot(p));
3947 unlock_user(p, arg1, 0);
3948 break;
3949 case TARGET_NR_ustat:
3950 goto unimplemented;
3951 case TARGET_NR_dup2:
3952 ret = get_errno(dup2(arg1, arg2));
3953 break;
3954 #ifdef TARGET_NR_getppid /* not on alpha */
3955 case TARGET_NR_getppid:
3956 ret = get_errno(getppid());
3957 break;
3958 #endif
3959 case TARGET_NR_getpgrp:
3960 ret = get_errno(getpgrp());
3961 break;
3962 case TARGET_NR_setsid:
3963 ret = get_errno(setsid());
3964 break;
3965 #ifdef TARGET_NR_sigaction
3966 case TARGET_NR_sigaction:
3968 #if !defined(TARGET_MIPS)
3969 struct target_old_sigaction *old_act;
3970 struct target_sigaction act, oact, *pact;
3971 if (arg2) {
3972 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
3973 goto efault;
3974 act._sa_handler = old_act->_sa_handler;
3975 target_siginitset(&act.sa_mask, old_act->sa_mask);
3976 act.sa_flags = old_act->sa_flags;
3977 act.sa_restorer = old_act->sa_restorer;
3978 unlock_user_struct(old_act, arg2, 0);
3979 pact = &act;
3980 } else {
3981 pact = NULL;
3983 ret = get_errno(do_sigaction(arg1, pact, &oact));
3984 if (!is_error(ret) && arg3) {
3985 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
3986 goto efault;
3987 old_act->_sa_handler = oact._sa_handler;
3988 old_act->sa_mask = oact.sa_mask.sig[0];
3989 old_act->sa_flags = oact.sa_flags;
3990 old_act->sa_restorer = oact.sa_restorer;
3991 unlock_user_struct(old_act, arg3, 1);
3993 #else
3994 struct target_sigaction act, oact, *pact, *old_act;
3996 if (arg2) {
3997 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
3998 goto efault;
3999 act._sa_handler = old_act->_sa_handler;
4000 target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
4001 act.sa_flags = old_act->sa_flags;
4002 unlock_user_struct(old_act, arg2, 0);
4003 pact = &act;
4004 } else {
4005 pact = NULL;
4008 ret = get_errno(do_sigaction(arg1, pact, &oact));
4010 if (!is_error(ret) && arg3) {
4011 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4012 goto efault;
4013 old_act->_sa_handler = oact._sa_handler;
4014 old_act->sa_flags = oact.sa_flags;
4015 old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
4016 old_act->sa_mask.sig[1] = 0;
4017 old_act->sa_mask.sig[2] = 0;
4018 old_act->sa_mask.sig[3] = 0;
4019 unlock_user_struct(old_act, arg3, 1);
4021 #endif
4023 break;
4024 #endif
4025 case TARGET_NR_rt_sigaction:
4027 struct target_sigaction *act;
4028 struct target_sigaction *oact;
4030 if (arg2) {
4031 if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
4032 goto efault;
4033 } else
4034 act = NULL;
4035 if (arg3) {
4036 if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
4037 ret = -TARGET_EFAULT;
4038 goto rt_sigaction_fail;
4040 } else
4041 oact = NULL;
4042 ret = get_errno(do_sigaction(arg1, act, oact));
4043 rt_sigaction_fail:
4044 if (act)
4045 unlock_user_struct(act, arg2, 0);
4046 if (oact)
4047 unlock_user_struct(oact, arg3, 1);
4049 break;
4050 #ifdef TARGET_NR_sgetmask /* not on alpha */
4051 case TARGET_NR_sgetmask:
4053 sigset_t cur_set;
4054 abi_ulong target_set;
4055 sigprocmask(0, NULL, &cur_set);
4056 host_to_target_old_sigset(&target_set, &cur_set);
4057 ret = target_set;
4059 break;
4060 #endif
4061 #ifdef TARGET_NR_ssetmask /* not on alpha */
4062 case TARGET_NR_ssetmask:
4064 sigset_t set, oset, cur_set;
4065 abi_ulong target_set = arg1;
4066 sigprocmask(0, NULL, &cur_set);
4067 target_to_host_old_sigset(&set, &target_set);
4068 sigorset(&set, &set, &cur_set);
4069 sigprocmask(SIG_SETMASK, &set, &oset);
4070 host_to_target_old_sigset(&target_set, &oset);
4071 ret = target_set;
4073 break;
4074 #endif
4075 #ifdef TARGET_NR_sigprocmask
4076 case TARGET_NR_sigprocmask:
4078 int how = arg1;
4079 sigset_t set, oldset, *set_ptr;
4081 if (arg2) {
4082 switch(how) {
4083 case TARGET_SIG_BLOCK:
4084 how = SIG_BLOCK;
4085 break;
4086 case TARGET_SIG_UNBLOCK:
4087 how = SIG_UNBLOCK;
4088 break;
4089 case TARGET_SIG_SETMASK:
4090 how = SIG_SETMASK;
4091 break;
4092 default:
4093 ret = -TARGET_EINVAL;
4094 goto fail;
4096 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4097 goto efault;
4098 target_to_host_old_sigset(&set, p);
4099 unlock_user(p, arg2, 0);
4100 set_ptr = &set;
4101 } else {
4102 how = 0;
4103 set_ptr = NULL;
4105 ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
4106 if (!is_error(ret) && arg3) {
4107 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4108 goto efault;
4109 host_to_target_old_sigset(p, &oldset);
4110 unlock_user(p, arg3, sizeof(target_sigset_t));
4113 break;
4114 #endif
4115 case TARGET_NR_rt_sigprocmask:
4117 int how = arg1;
4118 sigset_t set, oldset, *set_ptr;
4120 if (arg2) {
4121 switch(how) {
4122 case TARGET_SIG_BLOCK:
4123 how = SIG_BLOCK;
4124 break;
4125 case TARGET_SIG_UNBLOCK:
4126 how = SIG_UNBLOCK;
4127 break;
4128 case TARGET_SIG_SETMASK:
4129 how = SIG_SETMASK;
4130 break;
4131 default:
4132 ret = -TARGET_EINVAL;
4133 goto fail;
4135 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4136 goto efault;
4137 target_to_host_sigset(&set, p);
4138 unlock_user(p, arg2, 0);
4139 set_ptr = &set;
4140 } else {
4141 how = 0;
4142 set_ptr = NULL;
4144 ret = get_errno(sigprocmask(how, set_ptr, &oldset));
4145 if (!is_error(ret) && arg3) {
4146 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4147 goto efault;
4148 host_to_target_sigset(p, &oldset);
4149 unlock_user(p, arg3, sizeof(target_sigset_t));
4152 break;
4153 #ifdef TARGET_NR_sigpending
4154 case TARGET_NR_sigpending:
4156 sigset_t set;
4157 ret = get_errno(sigpending(&set));
4158 if (!is_error(ret)) {
4159 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4160 goto efault;
4161 host_to_target_old_sigset(p, &set);
4162 unlock_user(p, arg1, sizeof(target_sigset_t));
4165 break;
4166 #endif
4167 case TARGET_NR_rt_sigpending:
4169 sigset_t set;
4170 ret = get_errno(sigpending(&set));
4171 if (!is_error(ret)) {
4172 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4173 goto efault;
4174 host_to_target_sigset(p, &set);
4175 unlock_user(p, arg1, sizeof(target_sigset_t));
4178 break;
4179 #ifdef TARGET_NR_sigsuspend
4180 case TARGET_NR_sigsuspend:
4182 sigset_t set;
4183 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4184 goto efault;
4185 target_to_host_old_sigset(&set, p);
4186 unlock_user(p, arg1, 0);
4187 ret = get_errno(sigsuspend(&set));
4189 break;
4190 #endif
4191 case TARGET_NR_rt_sigsuspend:
4193 sigset_t set;
4194 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4195 goto efault;
4196 target_to_host_sigset(&set, p);
4197 unlock_user(p, arg1, 0);
4198 ret = get_errno(sigsuspend(&set));
4200 break;
4201 case TARGET_NR_rt_sigtimedwait:
4203 sigset_t set;
4204 struct timespec uts, *puts;
4205 siginfo_t uinfo;
4207 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4208 goto efault;
4209 target_to_host_sigset(&set, p);
4210 unlock_user(p, arg1, 0);
4211 if (arg3) {
4212 puts = &uts;
4213 target_to_host_timespec(puts, arg3);
4214 } else {
4215 puts = NULL;
4217 ret = get_errno(sigtimedwait(&set, &uinfo, puts));
4218 if (!is_error(ret) && arg2) {
4219 if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
4220 goto efault;
4221 host_to_target_siginfo(p, &uinfo);
4222 unlock_user(p, arg2, sizeof(target_siginfo_t));
4225 break;
4226 case TARGET_NR_rt_sigqueueinfo:
4228 siginfo_t uinfo;
4229 if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
4230 goto efault;
4231 target_to_host_siginfo(&uinfo, p);
4232 unlock_user(p, arg1, 0);
4233 ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
4235 break;
4236 #ifdef TARGET_NR_sigreturn
4237 case TARGET_NR_sigreturn:
4238 /* NOTE: ret is eax, so not transcoding must be done */
4239 ret = do_sigreturn(cpu_env);
4240 break;
4241 #endif
4242 case TARGET_NR_rt_sigreturn:
4243 /* NOTE: ret is eax, so not transcoding must be done */
4244 ret = do_rt_sigreturn(cpu_env);
4245 break;
4246 case TARGET_NR_sethostname:
4247 if (!(p = lock_user_string(arg1)))
4248 goto efault;
4249 ret = get_errno(sethostname(p, arg2));
4250 unlock_user(p, arg1, 0);
4251 break;
4252 case TARGET_NR_setrlimit:
4254 /* XXX: convert resource ? */
4255 int resource = arg1;
4256 struct target_rlimit *target_rlim;
4257 struct rlimit rlim;
4258 if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
4259 goto efault;
4260 rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4261 rlim.rlim_max = tswapl(target_rlim->rlim_max);
4262 unlock_user_struct(target_rlim, arg2, 0);
4263 ret = get_errno(setrlimit(resource, &rlim));
4265 break;
4266 case TARGET_NR_getrlimit:
4268 /* XXX: convert resource ? */
4269 int resource = arg1;
4270 struct target_rlimit *target_rlim;
4271 struct rlimit rlim;
4273 ret = get_errno(getrlimit(resource, &rlim));
4274 if (!is_error(ret)) {
4275 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
4276 goto efault;
4277 rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4278 rlim.rlim_max = tswapl(target_rlim->rlim_max);
4279 unlock_user_struct(target_rlim, arg2, 1);
4282 break;
4283 case TARGET_NR_getrusage:
4285 struct rusage rusage;
4286 ret = get_errno(getrusage(arg1, &rusage));
4287 if (!is_error(ret)) {
4288 host_to_target_rusage(arg2, &rusage);
4291 break;
4292 case TARGET_NR_gettimeofday:
4294 struct timeval tv;
4295 ret = get_errno(gettimeofday(&tv, NULL));
4296 if (!is_error(ret)) {
4297 if (copy_to_user_timeval(arg1, &tv))
4298 goto efault;
4301 break;
4302 case TARGET_NR_settimeofday:
4304 struct timeval tv;
4305 if (copy_from_user_timeval(&tv, arg1))
4306 goto efault;
4307 ret = get_errno(settimeofday(&tv, NULL));
4309 break;
4310 #ifdef TARGET_NR_select
4311 case TARGET_NR_select:
4313 struct target_sel_arg_struct *sel;
4314 abi_ulong inp, outp, exp, tvp;
4315 long nsel;
4317 if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
4318 goto efault;
4319 nsel = tswapl(sel->n);
4320 inp = tswapl(sel->inp);
4321 outp = tswapl(sel->outp);
4322 exp = tswapl(sel->exp);
4323 tvp = tswapl(sel->tvp);
4324 unlock_user_struct(sel, arg1, 0);
4325 ret = do_select(nsel, inp, outp, exp, tvp);
4327 break;
4328 #endif
4329 case TARGET_NR_symlink:
4331 void *p2;
4332 p = lock_user_string(arg1);
4333 p2 = lock_user_string(arg2);
4334 if (!p || !p2)
4335 ret = -TARGET_EFAULT;
4336 else
4337 ret = get_errno(symlink(p, p2));
4338 unlock_user(p2, arg2, 0);
4339 unlock_user(p, arg1, 0);
4341 break;
4342 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
4343 case TARGET_NR_symlinkat:
4345 void *p2;
4346 p = lock_user_string(arg1);
4347 p2 = lock_user_string(arg3);
4348 if (!p || !p2)
4349 ret = -TARGET_EFAULT;
4350 else
4351 ret = get_errno(sys_symlinkat(p, arg2, p2));
4352 unlock_user(p2, arg3, 0);
4353 unlock_user(p, arg1, 0);
4355 break;
4356 #endif
4357 #ifdef TARGET_NR_oldlstat
4358 case TARGET_NR_oldlstat:
4359 goto unimplemented;
4360 #endif
4361 case TARGET_NR_readlink:
4363 void *p2;
4364 p = lock_user_string(arg1);
4365 p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
4366 if (!p || !p2)
4367 ret = -TARGET_EFAULT;
4368 else
4369 ret = get_errno(readlink(path(p), p2, arg3));
4370 unlock_user(p2, arg2, ret);
4371 unlock_user(p, arg1, 0);
4373 break;
4374 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
4375 case TARGET_NR_readlinkat:
4377 void *p2;
4378 p = lock_user_string(arg2);
4379 p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
4380 if (!p || !p2)
4381 ret = -TARGET_EFAULT;
4382 else
4383 ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
4384 unlock_user(p2, arg3, ret);
4385 unlock_user(p, arg2, 0);
4387 break;
4388 #endif
4389 #ifdef TARGET_NR_uselib
4390 case TARGET_NR_uselib:
4391 goto unimplemented;
4392 #endif
4393 #ifdef TARGET_NR_swapon
4394 case TARGET_NR_swapon:
4395 if (!(p = lock_user_string(arg1)))
4396 goto efault;
4397 ret = get_errno(swapon(p, arg2));
4398 unlock_user(p, arg1, 0);
4399 break;
4400 #endif
4401 case TARGET_NR_reboot:
4402 goto unimplemented;
4403 #ifdef TARGET_NR_readdir
4404 case TARGET_NR_readdir:
4405 goto unimplemented;
4406 #endif
4407 #ifdef TARGET_NR_mmap
4408 case TARGET_NR_mmap:
4409 #if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS)
4411 abi_ulong *v;
4412 abi_ulong v1, v2, v3, v4, v5, v6;
4413 if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
4414 goto efault;
4415 v1 = tswapl(v[0]);
4416 v2 = tswapl(v[1]);
4417 v3 = tswapl(v[2]);
4418 v4 = tswapl(v[3]);
4419 v5 = tswapl(v[4]);
4420 v6 = tswapl(v[5]);
4421 unlock_user(v, arg1, 0);
4422 ret = get_errno(target_mmap(v1, v2, v3,
4423 target_to_host_bitmask(v4, mmap_flags_tbl),
4424 v5, v6));
4426 #else
4427 ret = get_errno(target_mmap(arg1, arg2, arg3,
4428 target_to_host_bitmask(arg4, mmap_flags_tbl),
4429 arg5,
4430 arg6));
4431 #endif
4432 break;
4433 #endif
4434 #ifdef TARGET_NR_mmap2
4435 case TARGET_NR_mmap2:
4436 #ifndef MMAP_SHIFT
4437 #define MMAP_SHIFT 12
4438 #endif
4439 ret = get_errno(target_mmap(arg1, arg2, arg3,
4440 target_to_host_bitmask(arg4, mmap_flags_tbl),
4441 arg5,
4442 arg6 << MMAP_SHIFT));
4443 break;
4444 #endif
4445 case TARGET_NR_munmap:
4446 ret = get_errno(target_munmap(arg1, arg2));
4447 break;
4448 case TARGET_NR_mprotect:
4449 ret = get_errno(target_mprotect(arg1, arg2, arg3));
4450 break;
4451 #ifdef TARGET_NR_mremap
4452 case TARGET_NR_mremap:
4453 ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
4454 break;
4455 #endif
4456 /* ??? msync/mlock/munlock are broken for softmmu. */
4457 #ifdef TARGET_NR_msync
4458 case TARGET_NR_msync:
4459 ret = get_errno(msync(g2h(arg1), arg2, arg3));
4460 break;
4461 #endif
4462 #ifdef TARGET_NR_mlock
4463 case TARGET_NR_mlock:
4464 ret = get_errno(mlock(g2h(arg1), arg2));
4465 break;
4466 #endif
4467 #ifdef TARGET_NR_munlock
4468 case TARGET_NR_munlock:
4469 ret = get_errno(munlock(g2h(arg1), arg2));
4470 break;
4471 #endif
4472 #ifdef TARGET_NR_mlockall
4473 case TARGET_NR_mlockall:
4474 ret = get_errno(mlockall(arg1));
4475 break;
4476 #endif
4477 #ifdef TARGET_NR_munlockall
4478 case TARGET_NR_munlockall:
4479 ret = get_errno(munlockall());
4480 break;
4481 #endif
4482 case TARGET_NR_truncate:
4483 if (!(p = lock_user_string(arg1)))
4484 goto efault;
4485 ret = get_errno(truncate(p, arg2));
4486 unlock_user(p, arg1, 0);
4487 break;
4488 case TARGET_NR_ftruncate:
4489 ret = get_errno(ftruncate(arg1, arg2));
4490 break;
4491 case TARGET_NR_fchmod:
4492 ret = get_errno(fchmod(arg1, arg2));
4493 break;
4494 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
4495 case TARGET_NR_fchmodat:
4496 if (!(p = lock_user_string(arg2)))
4497 goto efault;
4498 ret = get_errno(sys_fchmodat(arg1, p, arg3, arg4));
4499 unlock_user(p, arg2, 0);
4500 break;
4501 #endif
4502 case TARGET_NR_getpriority:
4503 /* libc does special remapping of the return value of
4504 * sys_getpriority() so it's just easiest to call
4505 * sys_getpriority() directly rather than through libc. */
4506 ret = sys_getpriority(arg1, arg2);
4507 break;
4508 case TARGET_NR_setpriority:
4509 ret = get_errno(setpriority(arg1, arg2, arg3));
4510 break;
4511 #ifdef TARGET_NR_profil
4512 case TARGET_NR_profil:
4513 goto unimplemented;
4514 #endif
4515 case TARGET_NR_statfs:
4516 if (!(p = lock_user_string(arg1)))
4517 goto efault;
4518 ret = get_errno(statfs(path(p), &stfs));
4519 unlock_user(p, arg1, 0);
4520 convert_statfs:
4521 if (!is_error(ret)) {
4522 struct target_statfs *target_stfs;
4524 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
4525 goto efault;
4526 __put_user(stfs.f_type, &target_stfs->f_type);
4527 __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4528 __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4529 __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4530 __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4531 __put_user(stfs.f_files, &target_stfs->f_files);
4532 __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4533 __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4534 __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4535 __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4536 unlock_user_struct(target_stfs, arg2, 1);
4538 break;
4539 case TARGET_NR_fstatfs:
4540 ret = get_errno(fstatfs(arg1, &stfs));
4541 goto convert_statfs;
4542 #ifdef TARGET_NR_statfs64
4543 case TARGET_NR_statfs64:
4544 if (!(p = lock_user_string(arg1)))
4545 goto efault;
4546 ret = get_errno(statfs(path(p), &stfs));
4547 unlock_user(p, arg1, 0);
4548 convert_statfs64:
4549 if (!is_error(ret)) {
4550 struct target_statfs64 *target_stfs;
4552 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
4553 goto efault;
4554 __put_user(stfs.f_type, &target_stfs->f_type);
4555 __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4556 __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4557 __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4558 __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4559 __put_user(stfs.f_files, &target_stfs->f_files);
4560 __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4561 __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4562 __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4563 __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4564 unlock_user_struct(target_stfs, arg3, 1);
4566 break;
4567 case TARGET_NR_fstatfs64:
4568 ret = get_errno(fstatfs(arg1, &stfs));
4569 goto convert_statfs64;
4570 #endif
4571 #ifdef TARGET_NR_ioperm
4572 case TARGET_NR_ioperm:
4573 goto unimplemented;
4574 #endif
4575 #ifdef TARGET_NR_socketcall
4576 case TARGET_NR_socketcall:
4577 ret = do_socketcall(arg1, arg2);
4578 break;
4579 #endif
4580 #ifdef TARGET_NR_accept
4581 case TARGET_NR_accept:
4582 ret = do_accept(arg1, arg2, arg3);
4583 break;
4584 #endif
4585 #ifdef TARGET_NR_bind
4586 case TARGET_NR_bind:
4587 ret = do_bind(arg1, arg2, arg3);
4588 break;
4589 #endif
4590 #ifdef TARGET_NR_connect
4591 case TARGET_NR_connect:
4592 ret = do_connect(arg1, arg2, arg3);
4593 break;
4594 #endif
4595 #ifdef TARGET_NR_getpeername
4596 case TARGET_NR_getpeername:
4597 ret = do_getpeername(arg1, arg2, arg3);
4598 break;
4599 #endif
4600 #ifdef TARGET_NR_getsockname
4601 case TARGET_NR_getsockname:
4602 ret = do_getsockname(arg1, arg2, arg3);
4603 break;
4604 #endif
4605 #ifdef TARGET_NR_getsockopt
4606 case TARGET_NR_getsockopt:
4607 ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
4608 break;
4609 #endif
4610 #ifdef TARGET_NR_listen
4611 case TARGET_NR_listen:
4612 ret = get_errno(listen(arg1, arg2));
4613 break;
4614 #endif
4615 #ifdef TARGET_NR_recv
4616 case TARGET_NR_recv:
4617 ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
4618 break;
4619 #endif
4620 #ifdef TARGET_NR_recvfrom
4621 case TARGET_NR_recvfrom:
4622 ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
4623 break;
4624 #endif
4625 #ifdef TARGET_NR_recvmsg
4626 case TARGET_NR_recvmsg:
4627 ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
4628 break;
4629 #endif
4630 #ifdef TARGET_NR_send
4631 case TARGET_NR_send:
4632 ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
4633 break;
4634 #endif
4635 #ifdef TARGET_NR_sendmsg
4636 case TARGET_NR_sendmsg:
4637 ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
4638 break;
4639 #endif
4640 #ifdef TARGET_NR_sendto
4641 case TARGET_NR_sendto:
4642 ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
4643 break;
4644 #endif
4645 #ifdef TARGET_NR_shutdown
4646 case TARGET_NR_shutdown:
4647 ret = get_errno(shutdown(arg1, arg2));
4648 break;
4649 #endif
4650 #ifdef TARGET_NR_socket
4651 case TARGET_NR_socket:
4652 ret = do_socket(arg1, arg2, arg3);
4653 break;
4654 #endif
4655 #ifdef TARGET_NR_socketpair
4656 case TARGET_NR_socketpair:
4657 ret = do_socketpair(arg1, arg2, arg3, arg4);
4658 break;
4659 #endif
4660 #ifdef TARGET_NR_setsockopt
4661 case TARGET_NR_setsockopt:
4662 ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
4663 break;
4664 #endif
4666 case TARGET_NR_syslog:
4667 if (!(p = lock_user_string(arg2)))
4668 goto efault;
4669 ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
4670 unlock_user(p, arg2, 0);
4671 break;
4673 case TARGET_NR_setitimer:
4675 struct itimerval value, ovalue, *pvalue;
4677 if (arg2) {
4678 pvalue = &value;
4679 if (copy_from_user_timeval(&pvalue->it_interval, arg2)
4680 || copy_from_user_timeval(&pvalue->it_value,
4681 arg2 + sizeof(struct target_timeval)))
4682 goto efault;
4683 } else {
4684 pvalue = NULL;
4686 ret = get_errno(setitimer(arg1, pvalue, &ovalue));
4687 if (!is_error(ret) && arg3) {
4688 if (copy_to_user_timeval(arg3,
4689 &ovalue.it_interval)
4690 || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
4691 &ovalue.it_value))
4692 goto efault;
4695 break;
4696 case TARGET_NR_getitimer:
4698 struct itimerval value;
4700 ret = get_errno(getitimer(arg1, &value));
4701 if (!is_error(ret) && arg2) {
4702 if (copy_to_user_timeval(arg2,
4703 &value.it_interval)
4704 || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
4705 &value.it_value))
4706 goto efault;
4709 break;
4710 case TARGET_NR_stat:
4711 if (!(p = lock_user_string(arg1)))
4712 goto efault;
4713 ret = get_errno(stat(path(p), &st));
4714 unlock_user(p, arg1, 0);
4715 goto do_stat;
4716 case TARGET_NR_lstat:
4717 if (!(p = lock_user_string(arg1)))
4718 goto efault;
4719 ret = get_errno(lstat(path(p), &st));
4720 unlock_user(p, arg1, 0);
4721 goto do_stat;
4722 case TARGET_NR_fstat:
4724 ret = get_errno(fstat(arg1, &st));
4725 do_stat:
4726 if (!is_error(ret)) {
4727 struct target_stat *target_st;
4729 if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
4730 goto efault;
4731 __put_user(st.st_dev, &target_st->st_dev);
4732 __put_user(st.st_ino, &target_st->st_ino);
4733 __put_user(st.st_mode, &target_st->st_mode);
4734 __put_user(st.st_uid, &target_st->st_uid);
4735 __put_user(st.st_gid, &target_st->st_gid);
4736 __put_user(st.st_nlink, &target_st->st_nlink);
4737 __put_user(st.st_rdev, &target_st->st_rdev);
4738 __put_user(st.st_size, &target_st->st_size);
4739 __put_user(st.st_blksize, &target_st->st_blksize);
4740 __put_user(st.st_blocks, &target_st->st_blocks);
4741 __put_user(st.st_atime, &target_st->target_st_atime);
4742 __put_user(st.st_mtime, &target_st->target_st_mtime);
4743 __put_user(st.st_ctime, &target_st->target_st_ctime);
4744 unlock_user_struct(target_st, arg2, 1);
4747 break;
4748 #ifdef TARGET_NR_olduname
4749 case TARGET_NR_olduname:
4750 goto unimplemented;
4751 #endif
4752 #ifdef TARGET_NR_iopl
4753 case TARGET_NR_iopl:
4754 goto unimplemented;
4755 #endif
4756 case TARGET_NR_vhangup:
4757 ret = get_errno(vhangup());
4758 break;
4759 #ifdef TARGET_NR_idle
4760 case TARGET_NR_idle:
4761 goto unimplemented;
4762 #endif
4763 #ifdef TARGET_NR_syscall
4764 case TARGET_NR_syscall:
4765 ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
4766 break;
4767 #endif
4768 case TARGET_NR_wait4:
4770 int status;
4771 abi_long status_ptr = arg2;
4772 struct rusage rusage, *rusage_ptr;
4773 abi_ulong target_rusage = arg4;
4774 if (target_rusage)
4775 rusage_ptr = &rusage;
4776 else
4777 rusage_ptr = NULL;
4778 ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
4779 if (!is_error(ret)) {
4780 if (status_ptr) {
4781 if (put_user_s32(status, status_ptr))
4782 goto efault;
4784 if (target_rusage)
4785 host_to_target_rusage(target_rusage, &rusage);
4788 break;
4789 #ifdef TARGET_NR_swapoff
4790 case TARGET_NR_swapoff:
4791 if (!(p = lock_user_string(arg1)))
4792 goto efault;
4793 ret = get_errno(swapoff(p));
4794 unlock_user(p, arg1, 0);
4795 break;
4796 #endif
4797 case TARGET_NR_sysinfo:
4799 struct target_sysinfo *target_value;
4800 struct sysinfo value;
4801 ret = get_errno(sysinfo(&value));
4802 if (!is_error(ret) && arg1)
4804 if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
4805 goto efault;
4806 __put_user(value.uptime, &target_value->uptime);
4807 __put_user(value.loads[0], &target_value->loads[0]);
4808 __put_user(value.loads[1], &target_value->loads[1]);
4809 __put_user(value.loads[2], &target_value->loads[2]);
4810 __put_user(value.totalram, &target_value->totalram);
4811 __put_user(value.freeram, &target_value->freeram);
4812 __put_user(value.sharedram, &target_value->sharedram);
4813 __put_user(value.bufferram, &target_value->bufferram);
4814 __put_user(value.totalswap, &target_value->totalswap);
4815 __put_user(value.freeswap, &target_value->freeswap);
4816 __put_user(value.procs, &target_value->procs);
4817 __put_user(value.totalhigh, &target_value->totalhigh);
4818 __put_user(value.freehigh, &target_value->freehigh);
4819 __put_user(value.mem_unit, &target_value->mem_unit);
4820 unlock_user_struct(target_value, arg1, 1);
4823 break;
4824 #ifdef TARGET_NR_ipc
4825 case TARGET_NR_ipc:
4826 ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
4827 break;
4828 #endif
4830 #ifdef TARGET_NR_msgctl
4831 case TARGET_NR_msgctl:
4832 ret = do_msgctl(arg1, arg2, arg3);
4833 break;
4834 #endif
4835 #ifdef TARGET_NR_msgget
4836 case TARGET_NR_msgget:
4837 ret = get_errno(msgget(arg1, arg2));
4838 break;
4839 #endif
4840 #ifdef TARGET_NR_msgrcv
4841 case TARGET_NR_msgrcv:
4842 ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
4843 break;
4844 #endif
4845 #ifdef TARGET_NR_msgsnd
4846 case TARGET_NR_msgsnd:
4847 ret = do_msgsnd(arg1, arg2, arg3, arg4);
4848 break;
4849 #endif
4850 case TARGET_NR_fsync:
4851 ret = get_errno(fsync(arg1));
4852 break;
4853 case TARGET_NR_clone:
4854 #if defined(TARGET_SH4)
4855 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
4856 #else
4857 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
4858 #endif
4859 break;
4860 #ifdef __NR_exit_group
4861 /* new thread calls */
4862 case TARGET_NR_exit_group:
4863 gdb_exit(cpu_env, arg1);
4864 ret = get_errno(exit_group(arg1));
4865 break;
4866 #endif
4867 case TARGET_NR_setdomainname:
4868 if (!(p = lock_user_string(arg1)))
4869 goto efault;
4870 ret = get_errno(setdomainname(p, arg2));
4871 unlock_user(p, arg1, 0);
4872 break;
4873 case TARGET_NR_uname:
4874 /* no need to transcode because we use the linux syscall */
4876 struct new_utsname * buf;
4878 if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
4879 goto efault;
4880 ret = get_errno(sys_uname(buf));
4881 if (!is_error(ret)) {
4882 /* Overrite the native machine name with whatever is being
4883 emulated. */
4884 strcpy (buf->machine, UNAME_MACHINE);
4885 /* Allow the user to override the reported release. */
4886 if (qemu_uname_release && *qemu_uname_release)
4887 strcpy (buf->release, qemu_uname_release);
4889 unlock_user_struct(buf, arg1, 1);
4891 break;
4892 #ifdef TARGET_I386
4893 case TARGET_NR_modify_ldt:
4894 ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
4895 break;
4896 #if !defined(TARGET_X86_64)
4897 case TARGET_NR_vm86old:
4898 goto unimplemented;
4899 case TARGET_NR_vm86:
4900 ret = do_vm86(cpu_env, arg1, arg2);
4901 break;
4902 #endif
4903 #endif
4904 case TARGET_NR_adjtimex:
4905 goto unimplemented;
4906 #ifdef TARGET_NR_create_module
4907 case TARGET_NR_create_module:
4908 #endif
4909 case TARGET_NR_init_module:
4910 case TARGET_NR_delete_module:
4911 #ifdef TARGET_NR_get_kernel_syms
4912 case TARGET_NR_get_kernel_syms:
4913 #endif
4914 goto unimplemented;
4915 case TARGET_NR_quotactl:
4916 goto unimplemented;
4917 case TARGET_NR_getpgid:
4918 ret = get_errno(getpgid(arg1));
4919 break;
4920 case TARGET_NR_fchdir:
4921 ret = get_errno(fchdir(arg1));
4922 break;
4923 #ifdef TARGET_NR_bdflush /* not on x86_64 */
4924 case TARGET_NR_bdflush:
4925 goto unimplemented;
4926 #endif
4927 #ifdef TARGET_NR_sysfs
4928 case TARGET_NR_sysfs:
4929 goto unimplemented;
4930 #endif
4931 case TARGET_NR_personality:
4932 ret = get_errno(personality(arg1));
4933 break;
4934 #ifdef TARGET_NR_afs_syscall
4935 case TARGET_NR_afs_syscall:
4936 goto unimplemented;
4937 #endif
4938 #ifdef TARGET_NR__llseek /* Not on alpha */
4939 case TARGET_NR__llseek:
4941 #if defined (__x86_64__)
4942 ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
4943 if (put_user_s64(ret, arg4))
4944 goto efault;
4945 #else
4946 int64_t res;
4947 ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
4948 if (put_user_s64(res, arg4))
4949 goto efault;
4950 #endif
4952 break;
4953 #endif
4954 case TARGET_NR_getdents:
4955 #if TARGET_ABI_BITS != 32
4956 goto unimplemented;
4957 #elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
4959 struct target_dirent *target_dirp;
4960 struct linux_dirent *dirp;
4961 abi_long count = arg3;
4963 dirp = malloc(count);
4964 if (!dirp) {
4965 ret = -TARGET_ENOMEM;
4966 goto fail;
4969 ret = get_errno(sys_getdents(arg1, dirp, count));
4970 if (!is_error(ret)) {
4971 struct linux_dirent *de;
4972 struct target_dirent *tde;
4973 int len = ret;
4974 int reclen, treclen;
4975 int count1, tnamelen;
4977 count1 = 0;
4978 de = dirp;
4979 if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4980 goto efault;
4981 tde = target_dirp;
4982 while (len > 0) {
4983 reclen = de->d_reclen;
4984 treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
4985 tde->d_reclen = tswap16(treclen);
4986 tde->d_ino = tswapl(de->d_ino);
4987 tde->d_off = tswapl(de->d_off);
4988 tnamelen = treclen - (2 * sizeof(abi_long) + 2);
4989 if (tnamelen > 256)
4990 tnamelen = 256;
4991 /* XXX: may not be correct */
4992 pstrcpy(tde->d_name, tnamelen, de->d_name);
4993 de = (struct linux_dirent *)((char *)de + reclen);
4994 len -= reclen;
4995 tde = (struct target_dirent *)((char *)tde + treclen);
4996 count1 += treclen;
4998 ret = count1;
4999 unlock_user(target_dirp, arg2, ret);
5001 free(dirp);
5003 #else
5005 struct linux_dirent *dirp;
5006 abi_long count = arg3;
5008 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5009 goto efault;
5010 ret = get_errno(sys_getdents(arg1, dirp, count));
5011 if (!is_error(ret)) {
5012 struct linux_dirent *de;
5013 int len = ret;
5014 int reclen;
5015 de = dirp;
5016 while (len > 0) {
5017 reclen = de->d_reclen;
5018 if (reclen > len)
5019 break;
5020 de->d_reclen = tswap16(reclen);
5021 tswapls(&de->d_ino);
5022 tswapls(&de->d_off);
5023 de = (struct linux_dirent *)((char *)de + reclen);
5024 len -= reclen;
5027 unlock_user(dirp, arg2, ret);
5029 #endif
5030 break;
5031 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
5032 case TARGET_NR_getdents64:
5034 struct linux_dirent64 *dirp;
5035 abi_long count = arg3;
5036 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5037 goto efault;
5038 ret = get_errno(sys_getdents64(arg1, dirp, count));
5039 if (!is_error(ret)) {
5040 struct linux_dirent64 *de;
5041 int len = ret;
5042 int reclen;
5043 de = dirp;
5044 while (len > 0) {
5045 reclen = de->d_reclen;
5046 if (reclen > len)
5047 break;
5048 de->d_reclen = tswap16(reclen);
5049 tswap64s((uint64_t *)&de->d_ino);
5050 tswap64s((uint64_t *)&de->d_off);
5051 de = (struct linux_dirent64 *)((char *)de + reclen);
5052 len -= reclen;
5055 unlock_user(dirp, arg2, ret);
5057 break;
5058 #endif /* TARGET_NR_getdents64 */
5059 #ifdef TARGET_NR__newselect
5060 case TARGET_NR__newselect:
5061 ret = do_select(arg1, arg2, arg3, arg4, arg5);
5062 break;
5063 #endif
5064 #ifdef TARGET_NR_poll
5065 case TARGET_NR_poll:
5067 struct target_pollfd *target_pfd;
5068 unsigned int nfds = arg2;
5069 int timeout = arg3;
5070 struct pollfd *pfd;
5071 unsigned int i;
5073 target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
5074 if (!target_pfd)
5075 goto efault;
5076 pfd = alloca(sizeof(struct pollfd) * nfds);
5077 for(i = 0; i < nfds; i++) {
5078 pfd[i].fd = tswap32(target_pfd[i].fd);
5079 pfd[i].events = tswap16(target_pfd[i].events);
5081 ret = get_errno(poll(pfd, nfds, timeout));
5082 if (!is_error(ret)) {
5083 for(i = 0; i < nfds; i++) {
5084 target_pfd[i].revents = tswap16(pfd[i].revents);
5086 ret += nfds * (sizeof(struct target_pollfd)
5087 - sizeof(struct pollfd));
5089 unlock_user(target_pfd, arg1, ret);
5091 break;
5092 #endif
5093 case TARGET_NR_flock:
5094 /* NOTE: the flock constant seems to be the same for every
5095 Linux platform */
5096 ret = get_errno(flock(arg1, arg2));
5097 break;
5098 case TARGET_NR_readv:
5100 int count = arg3;
5101 struct iovec *vec;
5103 vec = alloca(count * sizeof(struct iovec));
5104 if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
5105 goto efault;
5106 ret = get_errno(readv(arg1, vec, count));
5107 unlock_iovec(vec, arg2, count, 1);
5109 break;
5110 case TARGET_NR_writev:
5112 int count = arg3;
5113 struct iovec *vec;
5115 vec = alloca(count * sizeof(struct iovec));
5116 if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
5117 goto efault;
5118 ret = get_errno(writev(arg1, vec, count));
5119 unlock_iovec(vec, arg2, count, 0);
5121 break;
5122 case TARGET_NR_getsid:
5123 ret = get_errno(getsid(arg1));
5124 break;
5125 #if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
5126 case TARGET_NR_fdatasync:
5127 ret = get_errno(fdatasync(arg1));
5128 break;
5129 #endif
5130 case TARGET_NR__sysctl:
5131 /* We don't implement this, but ENOTDIR is always a safe
5132 return value. */
5133 ret = -TARGET_ENOTDIR;
5134 break;
5135 case TARGET_NR_sched_setparam:
5137 struct sched_param *target_schp;
5138 struct sched_param schp;
5140 if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
5141 goto efault;
5142 schp.sched_priority = tswap32(target_schp->sched_priority);
5143 unlock_user_struct(target_schp, arg2, 0);
5144 ret = get_errno(sched_setparam(arg1, &schp));
5146 break;
5147 case TARGET_NR_sched_getparam:
5149 struct sched_param *target_schp;
5150 struct sched_param schp;
5151 ret = get_errno(sched_getparam(arg1, &schp));
5152 if (!is_error(ret)) {
5153 if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
5154 goto efault;
5155 target_schp->sched_priority = tswap32(schp.sched_priority);
5156 unlock_user_struct(target_schp, arg2, 1);
5159 break;
5160 case TARGET_NR_sched_setscheduler:
5162 struct sched_param *target_schp;
5163 struct sched_param schp;
5164 if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
5165 goto efault;
5166 schp.sched_priority = tswap32(target_schp->sched_priority);
5167 unlock_user_struct(target_schp, arg3, 0);
5168 ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
5170 break;
5171 case TARGET_NR_sched_getscheduler:
5172 ret = get_errno(sched_getscheduler(arg1));
5173 break;
5174 case TARGET_NR_sched_yield:
5175 ret = get_errno(sched_yield());
5176 break;
5177 case TARGET_NR_sched_get_priority_max:
5178 ret = get_errno(sched_get_priority_max(arg1));
5179 break;
5180 case TARGET_NR_sched_get_priority_min:
5181 ret = get_errno(sched_get_priority_min(arg1));
5182 break;
5183 case TARGET_NR_sched_rr_get_interval:
5185 struct timespec ts;
5186 ret = get_errno(sched_rr_get_interval(arg1, &ts));
5187 if (!is_error(ret)) {
5188 host_to_target_timespec(arg2, &ts);
5191 break;
5192 case TARGET_NR_nanosleep:
5194 struct timespec req, rem;
5195 target_to_host_timespec(&req, arg1);
5196 ret = get_errno(nanosleep(&req, &rem));
5197 if (is_error(ret) && arg2) {
5198 host_to_target_timespec(arg2, &rem);
5201 break;
5202 #ifdef TARGET_NR_query_module
5203 case TARGET_NR_query_module:
5204 goto unimplemented;
5205 #endif
5206 #ifdef TARGET_NR_nfsservctl
5207 case TARGET_NR_nfsservctl:
5208 goto unimplemented;
5209 #endif
5210 case TARGET_NR_prctl:
5211 switch (arg1)
5213 case PR_GET_PDEATHSIG:
5215 int deathsig;
5216 ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
5217 if (!is_error(ret) && arg2
5218 && put_user_ual(deathsig, arg2))
5219 goto efault;
5221 break;
5222 default:
5223 ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
5224 break;
5226 break;
5227 #ifdef TARGET_NR_arch_prctl
5228 case TARGET_NR_arch_prctl:
5229 #if defined(TARGET_I386) && !defined(TARGET_ABI32)
5230 ret = do_arch_prctl(cpu_env, arg1, arg2);
5231 break;
5232 #else
5233 goto unimplemented;
5234 #endif
5235 #endif
5236 #ifdef TARGET_NR_pread
5237 case TARGET_NR_pread:
5238 #ifdef TARGET_ARM
5239 if (((CPUARMState *)cpu_env)->eabi)
5240 arg4 = arg5;
5241 #endif
5242 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5243 goto efault;
5244 ret = get_errno(pread(arg1, p, arg3, arg4));
5245 unlock_user(p, arg2, ret);
5246 break;
5247 case TARGET_NR_pwrite:
5248 #ifdef TARGET_ARM
5249 if (((CPUARMState *)cpu_env)->eabi)
5250 arg4 = arg5;
5251 #endif
5252 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5253 goto efault;
5254 ret = get_errno(pwrite(arg1, p, arg3, arg4));
5255 unlock_user(p, arg2, 0);
5256 break;
5257 #endif
5258 #ifdef TARGET_NR_pread64
5259 case TARGET_NR_pread64:
5260 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5261 goto efault;
5262 ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
5263 unlock_user(p, arg2, ret);
5264 break;
5265 case TARGET_NR_pwrite64:
5266 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5267 goto efault;
5268 ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
5269 unlock_user(p, arg2, 0);
5270 break;
5271 #endif
5272 case TARGET_NR_getcwd:
5273 if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
5274 goto efault;
5275 ret = get_errno(sys_getcwd1(p, arg2));
5276 unlock_user(p, arg1, ret);
5277 break;
5278 case TARGET_NR_capget:
5279 goto unimplemented;
5280 case TARGET_NR_capset:
5281 goto unimplemented;
5282 case TARGET_NR_sigaltstack:
5283 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
5284 defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA)
5285 ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env));
5286 break;
5287 #else
5288 goto unimplemented;
5289 #endif
5290 case TARGET_NR_sendfile:
5291 goto unimplemented;
5292 #ifdef TARGET_NR_getpmsg
5293 case TARGET_NR_getpmsg:
5294 goto unimplemented;
5295 #endif
5296 #ifdef TARGET_NR_putpmsg
5297 case TARGET_NR_putpmsg:
5298 goto unimplemented;
5299 #endif
5300 #ifdef TARGET_NR_vfork
5301 case TARGET_NR_vfork:
5302 ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
5303 0, 0, 0, 0));
5304 break;
5305 #endif
5306 #ifdef TARGET_NR_ugetrlimit
5307 case TARGET_NR_ugetrlimit:
5309 struct rlimit rlim;
5310 ret = get_errno(getrlimit(arg1, &rlim));
5311 if (!is_error(ret)) {
5312 struct target_rlimit *target_rlim;
5313 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
5314 goto efault;
5315 target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
5316 target_rlim->rlim_max = tswapl(rlim.rlim_max);
5317 unlock_user_struct(target_rlim, arg2, 1);
5319 break;
5321 #endif
5322 #ifdef TARGET_NR_truncate64
5323 case TARGET_NR_truncate64:
5324 if (!(p = lock_user_string(arg1)))
5325 goto efault;
5326 ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
5327 unlock_user(p, arg1, 0);
5328 break;
5329 #endif
5330 #ifdef TARGET_NR_ftruncate64
5331 case TARGET_NR_ftruncate64:
5332 ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
5333 break;
5334 #endif
5335 #ifdef TARGET_NR_stat64
5336 case TARGET_NR_stat64:
5337 if (!(p = lock_user_string(arg1)))
5338 goto efault;
5339 ret = get_errno(stat(path(p), &st));
5340 unlock_user(p, arg1, 0);
5341 if (!is_error(ret))
5342 ret = host_to_target_stat64(cpu_env, arg2, &st);
5343 break;
5344 #endif
5345 #ifdef TARGET_NR_lstat64
5346 case TARGET_NR_lstat64:
5347 if (!(p = lock_user_string(arg1)))
5348 goto efault;
5349 ret = get_errno(lstat(path(p), &st));
5350 unlock_user(p, arg1, 0);
5351 if (!is_error(ret))
5352 ret = host_to_target_stat64(cpu_env, arg2, &st);
5353 break;
5354 #endif
5355 #ifdef TARGET_NR_fstat64
5356 case TARGET_NR_fstat64:
5357 ret = get_errno(fstat(arg1, &st));
5358 if (!is_error(ret))
5359 ret = host_to_target_stat64(cpu_env, arg2, &st);
5360 break;
5361 #endif
5362 #if defined(TARGET_NR_fstatat64) && defined(__NR_fstatat64)
5363 case TARGET_NR_fstatat64:
5364 if (!(p = lock_user_string(arg2)))
5365 goto efault;
5366 ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
5367 if (!is_error(ret))
5368 ret = host_to_target_stat64(cpu_env, arg3, &st);
5369 break;
5370 #endif
5371 #ifdef USE_UID16
5372 case TARGET_NR_lchown:
5373 if (!(p = lock_user_string(arg1)))
5374 goto efault;
5375 ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
5376 unlock_user(p, arg1, 0);
5377 break;
5378 case TARGET_NR_getuid:
5379 ret = get_errno(high2lowuid(getuid()));
5380 break;
5381 case TARGET_NR_getgid:
5382 ret = get_errno(high2lowgid(getgid()));
5383 break;
5384 case TARGET_NR_geteuid:
5385 ret = get_errno(high2lowuid(geteuid()));
5386 break;
5387 case TARGET_NR_getegid:
5388 ret = get_errno(high2lowgid(getegid()));
5389 break;
5390 case TARGET_NR_setreuid:
5391 ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
5392 break;
5393 case TARGET_NR_setregid:
5394 ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
5395 break;
5396 case TARGET_NR_getgroups:
5398 int gidsetsize = arg1;
5399 uint16_t *target_grouplist;
5400 gid_t *grouplist;
5401 int i;
5403 grouplist = alloca(gidsetsize * sizeof(gid_t));
5404 ret = get_errno(getgroups(gidsetsize, grouplist));
5405 if (gidsetsize == 0)
5406 break;
5407 if (!is_error(ret)) {
5408 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
5409 if (!target_grouplist)
5410 goto efault;
5411 for(i = 0;i < ret; i++)
5412 target_grouplist[i] = tswap16(grouplist[i]);
5413 unlock_user(target_grouplist, arg2, gidsetsize * 2);
5416 break;
5417 case TARGET_NR_setgroups:
5419 int gidsetsize = arg1;
5420 uint16_t *target_grouplist;
5421 gid_t *grouplist;
5422 int i;
5424 grouplist = alloca(gidsetsize * sizeof(gid_t));
5425 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
5426 if (!target_grouplist) {
5427 ret = -TARGET_EFAULT;
5428 goto fail;
5430 for(i = 0;i < gidsetsize; i++)
5431 grouplist[i] = tswap16(target_grouplist[i]);
5432 unlock_user(target_grouplist, arg2, 0);
5433 ret = get_errno(setgroups(gidsetsize, grouplist));
5435 break;
5436 case TARGET_NR_fchown:
5437 ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
5438 break;
5439 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
5440 case TARGET_NR_fchownat:
5441 if (!(p = lock_user_string(arg2)))
5442 goto efault;
5443 ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
5444 unlock_user(p, arg2, 0);
5445 break;
5446 #endif
5447 #ifdef TARGET_NR_setresuid
5448 case TARGET_NR_setresuid:
5449 ret = get_errno(setresuid(low2highuid(arg1),
5450 low2highuid(arg2),
5451 low2highuid(arg3)));
5452 break;
5453 #endif
5454 #ifdef TARGET_NR_getresuid
5455 case TARGET_NR_getresuid:
5457 uid_t ruid, euid, suid;
5458 ret = get_errno(getresuid(&ruid, &euid, &suid));
5459 if (!is_error(ret)) {
5460 if (put_user_u16(high2lowuid(ruid), arg1)
5461 || put_user_u16(high2lowuid(euid), arg2)
5462 || put_user_u16(high2lowuid(suid), arg3))
5463 goto efault;
5466 break;
5467 #endif
5468 #ifdef TARGET_NR_getresgid
5469 case TARGET_NR_setresgid:
5470 ret = get_errno(setresgid(low2highgid(arg1),
5471 low2highgid(arg2),
5472 low2highgid(arg3)));
5473 break;
5474 #endif
5475 #ifdef TARGET_NR_getresgid
5476 case TARGET_NR_getresgid:
5478 gid_t rgid, egid, sgid;
5479 ret = get_errno(getresgid(&rgid, &egid, &sgid));
5480 if (!is_error(ret)) {
5481 if (put_user_u16(high2lowgid(rgid), arg1)
5482 || put_user_u16(high2lowgid(egid), arg2)
5483 || put_user_u16(high2lowgid(sgid), arg3))
5484 goto efault;
5487 break;
5488 #endif
5489 case TARGET_NR_chown:
5490 if (!(p = lock_user_string(arg1)))
5491 goto efault;
5492 ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
5493 unlock_user(p, arg1, 0);
5494 break;
5495 case TARGET_NR_setuid:
5496 ret = get_errno(setuid(low2highuid(arg1)));
5497 break;
5498 case TARGET_NR_setgid:
5499 ret = get_errno(setgid(low2highgid(arg1)));
5500 break;
5501 case TARGET_NR_setfsuid:
5502 ret = get_errno(setfsuid(arg1));
5503 break;
5504 case TARGET_NR_setfsgid:
5505 ret = get_errno(setfsgid(arg1));
5506 break;
5507 #endif /* USE_UID16 */
5509 #ifdef TARGET_NR_lchown32
5510 case TARGET_NR_lchown32:
5511 if (!(p = lock_user_string(arg1)))
5512 goto efault;
5513 ret = get_errno(lchown(p, arg2, arg3));
5514 unlock_user(p, arg1, 0);
5515 break;
5516 #endif
5517 #ifdef TARGET_NR_getuid32
5518 case TARGET_NR_getuid32:
5519 ret = get_errno(getuid());
5520 break;
5521 #endif
5522 #ifdef TARGET_NR_getgid32
5523 case TARGET_NR_getgid32:
5524 ret = get_errno(getgid());
5525 break;
5526 #endif
5527 #ifdef TARGET_NR_geteuid32
5528 case TARGET_NR_geteuid32:
5529 ret = get_errno(geteuid());
5530 break;
5531 #endif
5532 #ifdef TARGET_NR_getegid32
5533 case TARGET_NR_getegid32:
5534 ret = get_errno(getegid());
5535 break;
5536 #endif
5537 #ifdef TARGET_NR_setreuid32
5538 case TARGET_NR_setreuid32:
5539 ret = get_errno(setreuid(arg1, arg2));
5540 break;
5541 #endif
5542 #ifdef TARGET_NR_setregid32
5543 case TARGET_NR_setregid32:
5544 ret = get_errno(setregid(arg1, arg2));
5545 break;
5546 #endif
5547 #ifdef TARGET_NR_getgroups32
5548 case TARGET_NR_getgroups32:
5550 int gidsetsize = arg1;
5551 uint32_t *target_grouplist;
5552 gid_t *grouplist;
5553 int i;
5555 grouplist = alloca(gidsetsize * sizeof(gid_t));
5556 ret = get_errno(getgroups(gidsetsize, grouplist));
5557 if (gidsetsize == 0)
5558 break;
5559 if (!is_error(ret)) {
5560 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
5561 if (!target_grouplist) {
5562 ret = -TARGET_EFAULT;
5563 goto fail;
5565 for(i = 0;i < ret; i++)
5566 target_grouplist[i] = tswap32(grouplist[i]);
5567 unlock_user(target_grouplist, arg2, gidsetsize * 4);
5570 break;
5571 #endif
5572 #ifdef TARGET_NR_setgroups32
5573 case TARGET_NR_setgroups32:
5575 int gidsetsize = arg1;
5576 uint32_t *target_grouplist;
5577 gid_t *grouplist;
5578 int i;
5580 grouplist = alloca(gidsetsize * sizeof(gid_t));
5581 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
5582 if (!target_grouplist) {
5583 ret = -TARGET_EFAULT;
5584 goto fail;
5586 for(i = 0;i < gidsetsize; i++)
5587 grouplist[i] = tswap32(target_grouplist[i]);
5588 unlock_user(target_grouplist, arg2, 0);
5589 ret = get_errno(setgroups(gidsetsize, grouplist));
5591 break;
5592 #endif
5593 #ifdef TARGET_NR_fchown32
5594 case TARGET_NR_fchown32:
5595 ret = get_errno(fchown(arg1, arg2, arg3));
5596 break;
5597 #endif
5598 #ifdef TARGET_NR_setresuid32
5599 case TARGET_NR_setresuid32:
5600 ret = get_errno(setresuid(arg1, arg2, arg3));
5601 break;
5602 #endif
5603 #ifdef TARGET_NR_getresuid32
5604 case TARGET_NR_getresuid32:
5606 uid_t ruid, euid, suid;
5607 ret = get_errno(getresuid(&ruid, &euid, &suid));
5608 if (!is_error(ret)) {
5609 if (put_user_u32(ruid, arg1)
5610 || put_user_u32(euid, arg2)
5611 || put_user_u32(suid, arg3))
5612 goto efault;
5615 break;
5616 #endif
5617 #ifdef TARGET_NR_setresgid32
5618 case TARGET_NR_setresgid32:
5619 ret = get_errno(setresgid(arg1, arg2, arg3));
5620 break;
5621 #endif
5622 #ifdef TARGET_NR_getresgid32
5623 case TARGET_NR_getresgid32:
5625 gid_t rgid, egid, sgid;
5626 ret = get_errno(getresgid(&rgid, &egid, &sgid));
5627 if (!is_error(ret)) {
5628 if (put_user_u32(rgid, arg1)
5629 || put_user_u32(egid, arg2)
5630 || put_user_u32(sgid, arg3))
5631 goto efault;
5634 break;
5635 #endif
5636 #ifdef TARGET_NR_chown32
5637 case TARGET_NR_chown32:
5638 if (!(p = lock_user_string(arg1)))
5639 goto efault;
5640 ret = get_errno(chown(p, arg2, arg3));
5641 unlock_user(p, arg1, 0);
5642 break;
5643 #endif
5644 #ifdef TARGET_NR_setuid32
5645 case TARGET_NR_setuid32:
5646 ret = get_errno(setuid(arg1));
5647 break;
5648 #endif
5649 #ifdef TARGET_NR_setgid32
5650 case TARGET_NR_setgid32:
5651 ret = get_errno(setgid(arg1));
5652 break;
5653 #endif
5654 #ifdef TARGET_NR_setfsuid32
5655 case TARGET_NR_setfsuid32:
5656 ret = get_errno(setfsuid(arg1));
5657 break;
5658 #endif
5659 #ifdef TARGET_NR_setfsgid32
5660 case TARGET_NR_setfsgid32:
5661 ret = get_errno(setfsgid(arg1));
5662 break;
5663 #endif
5665 case TARGET_NR_pivot_root:
5666 goto unimplemented;
5667 #ifdef TARGET_NR_mincore
5668 case TARGET_NR_mincore:
5670 void *a;
5671 ret = -TARGET_EFAULT;
5672 if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
5673 goto efault;
5674 if (!(p = lock_user_string(arg3)))
5675 goto mincore_fail;
5676 ret = get_errno(mincore(a, arg2, p));
5677 unlock_user(p, arg3, ret);
5678 mincore_fail:
5679 unlock_user(a, arg1, 0);
5681 break;
5682 #endif
5683 #ifdef TARGET_NR_arm_fadvise64_64
5684 case TARGET_NR_arm_fadvise64_64:
5687 * arm_fadvise64_64 looks like fadvise64_64 but
5688 * with different argument order
5690 abi_long temp;
5691 temp = arg3;
5692 arg3 = arg4;
5693 arg4 = temp;
5695 #endif
5696 #if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64)
5697 #ifdef TARGET_NR_fadvise64_64
5698 case TARGET_NR_fadvise64_64:
5699 #endif
5700 /* This is a hint, so ignoring and returning success is ok. */
5701 ret = get_errno(0);
5702 break;
5703 #endif
5704 #ifdef TARGET_NR_madvise
5705 case TARGET_NR_madvise:
5706 /* A straight passthrough may not be safe because qemu sometimes
5707 turns private flie-backed mappings into anonymous mappings.
5708 This will break MADV_DONTNEED.
5709 This is a hint, so ignoring and returning success is ok. */
5710 ret = get_errno(0);
5711 break;
5712 #endif
5713 #if TARGET_ABI_BITS == 32
5714 case TARGET_NR_fcntl64:
5716 int cmd;
5717 struct flock64 fl;
5718 struct target_flock64 *target_fl;
5719 #ifdef TARGET_ARM
5720 struct target_eabi_flock64 *target_efl;
5721 #endif
5723 switch(arg2){
5724 case TARGET_F_GETLK64:
5725 cmd = F_GETLK64;
5726 break;
5727 case TARGET_F_SETLK64:
5728 cmd = F_SETLK64;
5729 break;
5730 case TARGET_F_SETLKW64:
5731 cmd = F_SETLK64;
5732 break;
5733 default:
5734 cmd = arg2;
5735 break;
5738 switch(arg2) {
5739 case TARGET_F_GETLK64:
5740 #ifdef TARGET_ARM
5741 if (((CPUARMState *)cpu_env)->eabi) {
5742 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1))
5743 goto efault;
5744 fl.l_type = tswap16(target_efl->l_type);
5745 fl.l_whence = tswap16(target_efl->l_whence);
5746 fl.l_start = tswap64(target_efl->l_start);
5747 fl.l_len = tswap64(target_efl->l_len);
5748 fl.l_pid = tswapl(target_efl->l_pid);
5749 unlock_user_struct(target_efl, arg3, 0);
5750 } else
5751 #endif
5753 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1))
5754 goto efault;
5755 fl.l_type = tswap16(target_fl->l_type);
5756 fl.l_whence = tswap16(target_fl->l_whence);
5757 fl.l_start = tswap64(target_fl->l_start);
5758 fl.l_len = tswap64(target_fl->l_len);
5759 fl.l_pid = tswapl(target_fl->l_pid);
5760 unlock_user_struct(target_fl, arg3, 0);
5762 ret = get_errno(fcntl(arg1, cmd, &fl));
5763 if (ret == 0) {
5764 #ifdef TARGET_ARM
5765 if (((CPUARMState *)cpu_env)->eabi) {
5766 if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0))
5767 goto efault;
5768 target_efl->l_type = tswap16(fl.l_type);
5769 target_efl->l_whence = tswap16(fl.l_whence);
5770 target_efl->l_start = tswap64(fl.l_start);
5771 target_efl->l_len = tswap64(fl.l_len);
5772 target_efl->l_pid = tswapl(fl.l_pid);
5773 unlock_user_struct(target_efl, arg3, 1);
5774 } else
5775 #endif
5777 if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0))
5778 goto efault;
5779 target_fl->l_type = tswap16(fl.l_type);
5780 target_fl->l_whence = tswap16(fl.l_whence);
5781 target_fl->l_start = tswap64(fl.l_start);
5782 target_fl->l_len = tswap64(fl.l_len);
5783 target_fl->l_pid = tswapl(fl.l_pid);
5784 unlock_user_struct(target_fl, arg3, 1);
5787 break;
5789 case TARGET_F_SETLK64:
5790 case TARGET_F_SETLKW64:
5791 #ifdef TARGET_ARM
5792 if (((CPUARMState *)cpu_env)->eabi) {
5793 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1))
5794 goto efault;
5795 fl.l_type = tswap16(target_efl->l_type);
5796 fl.l_whence = tswap16(target_efl->l_whence);
5797 fl.l_start = tswap64(target_efl->l_start);
5798 fl.l_len = tswap64(target_efl->l_len);
5799 fl.l_pid = tswapl(target_efl->l_pid);
5800 unlock_user_struct(target_efl, arg3, 0);
5801 } else
5802 #endif
5804 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1))
5805 goto efault;
5806 fl.l_type = tswap16(target_fl->l_type);
5807 fl.l_whence = tswap16(target_fl->l_whence);
5808 fl.l_start = tswap64(target_fl->l_start);
5809 fl.l_len = tswap64(target_fl->l_len);
5810 fl.l_pid = tswapl(target_fl->l_pid);
5811 unlock_user_struct(target_fl, arg3, 0);
5813 ret = get_errno(fcntl(arg1, cmd, &fl));
5814 break;
5815 default:
5816 ret = do_fcntl(arg1, cmd, arg3);
5817 break;
5819 break;
5821 #endif
5822 #ifdef TARGET_NR_cacheflush
5823 case TARGET_NR_cacheflush:
5824 /* self-modifying code is handled automatically, so nothing needed */
5825 ret = 0;
5826 break;
5827 #endif
5828 #ifdef TARGET_NR_security
5829 case TARGET_NR_security:
5830 goto unimplemented;
5831 #endif
5832 #ifdef TARGET_NR_getpagesize
5833 case TARGET_NR_getpagesize:
5834 ret = TARGET_PAGE_SIZE;
5835 break;
5836 #endif
5837 case TARGET_NR_gettid:
5838 ret = get_errno(gettid());
5839 break;
5840 #ifdef TARGET_NR_readahead
5841 case TARGET_NR_readahead:
5842 #if TARGET_ABI_BITS == 32
5843 #ifdef TARGET_ARM
5844 if (((CPUARMState *)cpu_env)->eabi)
5846 arg2 = arg3;
5847 arg3 = arg4;
5848 arg4 = arg5;
5850 #endif
5851 ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
5852 #else
5853 ret = get_errno(readahead(arg1, arg2, arg3));
5854 #endif
5855 break;
5856 #endif
5857 #ifdef TARGET_NR_setxattr
5858 case TARGET_NR_setxattr:
5859 case TARGET_NR_lsetxattr:
5860 case TARGET_NR_fsetxattr:
5861 case TARGET_NR_getxattr:
5862 case TARGET_NR_lgetxattr:
5863 case TARGET_NR_fgetxattr:
5864 case TARGET_NR_listxattr:
5865 case TARGET_NR_llistxattr:
5866 case TARGET_NR_flistxattr:
5867 case TARGET_NR_removexattr:
5868 case TARGET_NR_lremovexattr:
5869 case TARGET_NR_fremovexattr:
5870 goto unimplemented_nowarn;
5871 #endif
5872 #ifdef TARGET_NR_set_thread_area
5873 case TARGET_NR_set_thread_area:
5874 #if defined(TARGET_MIPS)
5875 ((CPUMIPSState *) cpu_env)->tls_value = arg1;
5876 ret = 0;
5877 break;
5878 #elif defined(TARGET_I386) && defined(TARGET_ABI32)
5879 ret = do_set_thread_area(cpu_env, arg1);
5880 break;
5881 #else
5882 goto unimplemented_nowarn;
5883 #endif
5884 #endif
5885 #ifdef TARGET_NR_get_thread_area
5886 case TARGET_NR_get_thread_area:
5887 #if defined(TARGET_I386) && defined(TARGET_ABI32)
5888 ret = do_get_thread_area(cpu_env, arg1);
5889 #else
5890 goto unimplemented_nowarn;
5891 #endif
5892 #endif
5893 #ifdef TARGET_NR_getdomainname
5894 case TARGET_NR_getdomainname:
5895 goto unimplemented_nowarn;
5896 #endif
5898 #ifdef TARGET_NR_clock_gettime
5899 case TARGET_NR_clock_gettime:
5901 struct timespec ts;
5902 ret = get_errno(clock_gettime(arg1, &ts));
5903 if (!is_error(ret)) {
5904 host_to_target_timespec(arg2, &ts);
5906 break;
5908 #endif
5909 #ifdef TARGET_NR_clock_getres
5910 case TARGET_NR_clock_getres:
5912 struct timespec ts;
5913 ret = get_errno(clock_getres(arg1, &ts));
5914 if (!is_error(ret)) {
5915 host_to_target_timespec(arg2, &ts);
5917 break;
5919 #endif
5920 #ifdef TARGET_NR_clock_nanosleep
5921 case TARGET_NR_clock_nanosleep:
5923 struct timespec ts;
5924 target_to_host_timespec(&ts, arg3);
5925 ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
5926 if (arg4)
5927 host_to_target_timespec(arg4, &ts);
5928 break;
5930 #endif
5932 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
5933 case TARGET_NR_set_tid_address:
5934 ret = get_errno(set_tid_address((int *)g2h(arg1)));
5935 break;
5936 #endif
5938 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
5939 case TARGET_NR_tkill:
5940 ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
5941 break;
5942 #endif
5944 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
5945 case TARGET_NR_tgkill:
5946 ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
5947 target_to_host_signal(arg3)));
5948 break;
5949 #endif
5951 #ifdef TARGET_NR_set_robust_list
5952 case TARGET_NR_set_robust_list:
5953 goto unimplemented_nowarn;
5954 #endif
5956 #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
5957 case TARGET_NR_utimensat:
5959 struct timespec ts[2];
5960 target_to_host_timespec(ts, arg3);
5961 target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
5962 if (!arg2)
5963 ret = get_errno(sys_utimensat(arg1, NULL, ts, arg4));
5964 else {
5965 if (!(p = lock_user_string(arg2))) {
5966 ret = -TARGET_EFAULT;
5967 goto fail;
5969 ret = get_errno(sys_utimensat(arg1, path(p), ts, arg4));
5970 unlock_user(p, arg2, 0);
5973 break;
5974 #endif
5975 #if defined(USE_NPTL)
5976 case TARGET_NR_futex:
5977 ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
5978 break;
5979 #endif
5980 #ifdef TARGET_NR_inotify_init
5981 case TARGET_NR_inotify_init:
5982 ret = get_errno(sys_inotify_init());
5983 break;
5984 #endif
5985 #ifdef TARGET_NR_inotify_add_watch
5986 case TARGET_NR_inotify_add_watch:
5987 p = lock_user_string(arg2);
5988 ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
5989 unlock_user(p, arg2, 0);
5990 break;
5991 #endif
5992 #ifdef TARGET_NR_inotify_rm_watch
5993 case TARGET_NR_inotify_rm_watch:
5994 ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
5995 break;
5996 #endif
5998 default:
5999 unimplemented:
6000 gemu_log("qemu: Unsupported syscall: %d\n", num);
6001 #if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
6002 unimplemented_nowarn:
6003 #endif
6004 ret = -TARGET_ENOSYS;
6005 break;
6007 fail:
6008 #ifdef DEBUG
6009 gemu_log(" = %ld\n", ret);
6010 #endif
6011 if(do_strace)
6012 print_syscall_ret(num, ret);
6013 return ret;
6014 efault:
6015 ret = -TARGET_EFAULT;
6016 goto fail;