Implement fstatat64() syscall (by Kirill Shutemov).
[qemu/mini2440.git] / linux-user / syscall.c
blob826511df5204f9f7dd3412e009287c37e8e55e90
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/dirent.h>
72 #include <linux/kd.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 dirent [2])
97 #define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct 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_uname __NR_uname
156 #define __NR_sys_faccessat __NR_faccessat
157 #define __NR_sys_fchmodat __NR_fchmodat
158 #define __NR_sys_fchownat __NR_fchownat
159 #define __NR_sys_fstatat64 __NR_fstatat64
160 #define __NR_sys_getcwd1 __NR_getcwd
161 #define __NR_sys_getdents __NR_getdents
162 #define __NR_sys_getdents64 __NR_getdents64
163 #define __NR_sys_getpriority __NR_getpriority
164 #define __NR_sys_linkat __NR_linkat
165 #define __NR_sys_mkdirat __NR_mkdirat
166 #define __NR_sys_mknodat __NR_mknodat
167 #define __NR_sys_openat __NR_openat
168 #define __NR_sys_readlinkat __NR_readlinkat
169 #define __NR_sys_renameat __NR_renameat
170 #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
171 #define __NR_sys_symlinkat __NR_symlinkat
172 #define __NR_sys_syslog __NR_syslog
173 #define __NR_sys_tgkill __NR_tgkill
174 #define __NR_sys_tkill __NR_tkill
175 #define __NR_sys_unlinkat __NR_unlinkat
176 #define __NR_sys_utimensat __NR_utimensat
177 #define __NR_sys_futex __NR_futex
179 #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
180 #define __NR__llseek __NR_lseek
181 #endif
183 #ifdef __NR_gettid
184 _syscall0(int, gettid)
185 #else
186 /* This is a replacement for the host gettid() and must return a host
187 errno. */
188 static int gettid(void) {
189 return -ENOSYS;
191 #endif
192 _syscall1(int,sys_uname,struct new_utsname *,buf)
193 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
194 _syscall4(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode,int,flags)
195 #endif
196 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
197 _syscall4(int,sys_fchmodat,int,dirfd,const char *,pathname,
198 mode_t,mode,int,flags)
199 #endif
200 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) && defined(USE_UID16)
201 _syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
202 uid_t,owner,gid_t,group,int,flags)
203 #endif
204 #if defined(TARGET_NR_fstatat64) && defined(__NR_fstatat64)
205 _syscall4(int,sys_fstatat64,int,dirfd,const char *,pathname,
206 struct stat *,buf,int,flags)
207 #endif
208 _syscall2(int,sys_getcwd1,char *,buf,size_t,size)
209 #if TARGET_ABI_BITS == 32
210 _syscall3(int, sys_getdents, uint, fd, struct dirent *, dirp, uint, count);
211 #endif
212 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
213 _syscall3(int, sys_getdents64, uint, fd, struct dirent64 *, dirp, uint, count);
214 #endif
215 _syscall2(int, sys_getpriority, int, which, int, who);
216 #if !defined (__x86_64__)
217 _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo,
218 loff_t *, res, uint, wh);
219 #endif
220 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
221 _syscall5(int,sys_linkat,int,olddirfd,const char *,oldpath,
222 int,newdirfd,const char *,newpath,int,flags)
223 #endif
224 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
225 _syscall3(int,sys_mkdirat,int,dirfd,const char *,pathname,mode_t,mode)
226 #endif
227 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
228 _syscall4(int,sys_mknodat,int,dirfd,const char *,pathname,
229 mode_t,mode,dev_t,dev)
230 #endif
231 #if defined(TARGET_NR_openat) && defined(__NR_openat)
232 _syscall4(int,sys_openat,int,dirfd,const char *,pathname,int,flags,mode_t,mode)
233 #endif
234 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
235 _syscall4(int,sys_readlinkat,int,dirfd,const char *,pathname,
236 char *,buf,size_t,bufsize)
237 #endif
238 #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
239 _syscall4(int,sys_renameat,int,olddirfd,const char *,oldpath,
240 int,newdirfd,const char *,newpath)
241 #endif
242 _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
243 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
244 _syscall3(int,sys_symlinkat,const char *,oldpath,
245 int,newdirfd,const char *,newpath)
246 #endif
247 _syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
248 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
249 _syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
250 #endif
251 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
252 _syscall2(int,sys_tkill,int,tid,int,sig)
253 #endif
254 #ifdef __NR_exit_group
255 _syscall1(int,exit_group,int,error_code)
256 #endif
257 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
258 _syscall1(int,set_tid_address,int *,tidptr)
259 #endif
260 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
261 _syscall3(int,sys_unlinkat,int,dirfd,const char *,pathname,int,flags)
262 #endif
263 #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
264 _syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
265 const struct timespec *,tsp,int,flags)
266 #endif
267 #if defined(USE_NPTL)
268 #if defined(TARGET_NR_futex) && defined(__NR_futex)
269 _syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
270 const struct timespec *,timeout,int *,uaddr2,int,val3)
271 #endif
272 #endif
274 extern int personality(int);
275 extern int flock(int, int);
276 extern int setfsuid(int);
277 extern int setfsgid(int);
278 extern int setgroups(int, gid_t *);
280 #define ERRNO_TABLE_SIZE 1200
282 /* target_to_host_errno_table[] is initialized from
283 * host_to_target_errno_table[] in syscall_init(). */
284 static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
288 * This list is the union of errno values overridden in asm-<arch>/errno.h
289 * minus the errnos that are not actually generic to all archs.
291 static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
292 [EIDRM] = TARGET_EIDRM,
293 [ECHRNG] = TARGET_ECHRNG,
294 [EL2NSYNC] = TARGET_EL2NSYNC,
295 [EL3HLT] = TARGET_EL3HLT,
296 [EL3RST] = TARGET_EL3RST,
297 [ELNRNG] = TARGET_ELNRNG,
298 [EUNATCH] = TARGET_EUNATCH,
299 [ENOCSI] = TARGET_ENOCSI,
300 [EL2HLT] = TARGET_EL2HLT,
301 [EDEADLK] = TARGET_EDEADLK,
302 [ENOLCK] = TARGET_ENOLCK,
303 [EBADE] = TARGET_EBADE,
304 [EBADR] = TARGET_EBADR,
305 [EXFULL] = TARGET_EXFULL,
306 [ENOANO] = TARGET_ENOANO,
307 [EBADRQC] = TARGET_EBADRQC,
308 [EBADSLT] = TARGET_EBADSLT,
309 [EBFONT] = TARGET_EBFONT,
310 [ENOSTR] = TARGET_ENOSTR,
311 [ENODATA] = TARGET_ENODATA,
312 [ETIME] = TARGET_ETIME,
313 [ENOSR] = TARGET_ENOSR,
314 [ENONET] = TARGET_ENONET,
315 [ENOPKG] = TARGET_ENOPKG,
316 [EREMOTE] = TARGET_EREMOTE,
317 [ENOLINK] = TARGET_ENOLINK,
318 [EADV] = TARGET_EADV,
319 [ESRMNT] = TARGET_ESRMNT,
320 [ECOMM] = TARGET_ECOMM,
321 [EPROTO] = TARGET_EPROTO,
322 [EDOTDOT] = TARGET_EDOTDOT,
323 [EMULTIHOP] = TARGET_EMULTIHOP,
324 [EBADMSG] = TARGET_EBADMSG,
325 [ENAMETOOLONG] = TARGET_ENAMETOOLONG,
326 [EOVERFLOW] = TARGET_EOVERFLOW,
327 [ENOTUNIQ] = TARGET_ENOTUNIQ,
328 [EBADFD] = TARGET_EBADFD,
329 [EREMCHG] = TARGET_EREMCHG,
330 [ELIBACC] = TARGET_ELIBACC,
331 [ELIBBAD] = TARGET_ELIBBAD,
332 [ELIBSCN] = TARGET_ELIBSCN,
333 [ELIBMAX] = TARGET_ELIBMAX,
334 [ELIBEXEC] = TARGET_ELIBEXEC,
335 [EILSEQ] = TARGET_EILSEQ,
336 [ENOSYS] = TARGET_ENOSYS,
337 [ELOOP] = TARGET_ELOOP,
338 [ERESTART] = TARGET_ERESTART,
339 [ESTRPIPE] = TARGET_ESTRPIPE,
340 [ENOTEMPTY] = TARGET_ENOTEMPTY,
341 [EUSERS] = TARGET_EUSERS,
342 [ENOTSOCK] = TARGET_ENOTSOCK,
343 [EDESTADDRREQ] = TARGET_EDESTADDRREQ,
344 [EMSGSIZE] = TARGET_EMSGSIZE,
345 [EPROTOTYPE] = TARGET_EPROTOTYPE,
346 [ENOPROTOOPT] = TARGET_ENOPROTOOPT,
347 [EPROTONOSUPPORT] = TARGET_EPROTONOSUPPORT,
348 [ESOCKTNOSUPPORT] = TARGET_ESOCKTNOSUPPORT,
349 [EOPNOTSUPP] = TARGET_EOPNOTSUPP,
350 [EPFNOSUPPORT] = TARGET_EPFNOSUPPORT,
351 [EAFNOSUPPORT] = TARGET_EAFNOSUPPORT,
352 [EADDRINUSE] = TARGET_EADDRINUSE,
353 [EADDRNOTAVAIL] = TARGET_EADDRNOTAVAIL,
354 [ENETDOWN] = TARGET_ENETDOWN,
355 [ENETUNREACH] = TARGET_ENETUNREACH,
356 [ENETRESET] = TARGET_ENETRESET,
357 [ECONNABORTED] = TARGET_ECONNABORTED,
358 [ECONNRESET] = TARGET_ECONNRESET,
359 [ENOBUFS] = TARGET_ENOBUFS,
360 [EISCONN] = TARGET_EISCONN,
361 [ENOTCONN] = TARGET_ENOTCONN,
362 [EUCLEAN] = TARGET_EUCLEAN,
363 [ENOTNAM] = TARGET_ENOTNAM,
364 [ENAVAIL] = TARGET_ENAVAIL,
365 [EISNAM] = TARGET_EISNAM,
366 [EREMOTEIO] = TARGET_EREMOTEIO,
367 [ESHUTDOWN] = TARGET_ESHUTDOWN,
368 [ETOOMANYREFS] = TARGET_ETOOMANYREFS,
369 [ETIMEDOUT] = TARGET_ETIMEDOUT,
370 [ECONNREFUSED] = TARGET_ECONNREFUSED,
371 [EHOSTDOWN] = TARGET_EHOSTDOWN,
372 [EHOSTUNREACH] = TARGET_EHOSTUNREACH,
373 [EALREADY] = TARGET_EALREADY,
374 [EINPROGRESS] = TARGET_EINPROGRESS,
375 [ESTALE] = TARGET_ESTALE,
376 [ECANCELED] = TARGET_ECANCELED,
377 [ENOMEDIUM] = TARGET_ENOMEDIUM,
378 [EMEDIUMTYPE] = TARGET_EMEDIUMTYPE,
379 #ifdef ENOKEY
380 [ENOKEY] = TARGET_ENOKEY,
381 #endif
382 #ifdef EKEYEXPIRED
383 [EKEYEXPIRED] = TARGET_EKEYEXPIRED,
384 #endif
385 #ifdef EKEYREVOKED
386 [EKEYREVOKED] = TARGET_EKEYREVOKED,
387 #endif
388 #ifdef EKEYREJECTED
389 [EKEYREJECTED] = TARGET_EKEYREJECTED,
390 #endif
391 #ifdef EOWNERDEAD
392 [EOWNERDEAD] = TARGET_EOWNERDEAD,
393 #endif
394 #ifdef ENOTRECOVERABLE
395 [ENOTRECOVERABLE] = TARGET_ENOTRECOVERABLE,
396 #endif
399 static inline int host_to_target_errno(int err)
401 if(host_to_target_errno_table[err])
402 return host_to_target_errno_table[err];
403 return err;
406 static inline int target_to_host_errno(int err)
408 if (target_to_host_errno_table[err])
409 return target_to_host_errno_table[err];
410 return err;
413 static inline abi_long get_errno(abi_long ret)
415 if (ret == -1)
416 return -host_to_target_errno(errno);
417 else
418 return ret;
421 static inline int is_error(abi_long ret)
423 return (abi_ulong)ret >= (abi_ulong)(-4096);
426 char *target_strerror(int err)
428 return strerror(target_to_host_errno(err));
431 static abi_ulong target_brk;
432 static abi_ulong target_original_brk;
434 void target_set_brk(abi_ulong new_brk)
436 target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
439 /* do_brk() must return target values and target errnos. */
440 abi_long do_brk(abi_ulong new_brk)
442 abi_ulong brk_page;
443 abi_long mapped_addr;
444 int new_alloc_size;
446 if (!new_brk)
447 return target_brk;
448 if (new_brk < target_original_brk)
449 return target_brk;
451 brk_page = HOST_PAGE_ALIGN(target_brk);
453 /* If the new brk is less than this, set it and we're done... */
454 if (new_brk < brk_page) {
455 target_brk = new_brk;
456 return target_brk;
459 /* We need to allocate more memory after the brk... */
460 new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
461 mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
462 PROT_READ|PROT_WRITE,
463 MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
465 if (!is_error(mapped_addr))
466 target_brk = new_brk;
468 return target_brk;
471 static inline abi_long copy_from_user_fdset(fd_set *fds,
472 abi_ulong target_fds_addr,
473 int n)
475 int i, nw, j, k;
476 abi_ulong b, *target_fds;
478 nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
479 if (!(target_fds = lock_user(VERIFY_READ,
480 target_fds_addr,
481 sizeof(abi_ulong) * nw,
482 1)))
483 return -TARGET_EFAULT;
485 FD_ZERO(fds);
486 k = 0;
487 for (i = 0; i < nw; i++) {
488 /* grab the abi_ulong */
489 __get_user(b, &target_fds[i]);
490 for (j = 0; j < TARGET_ABI_BITS; j++) {
491 /* check the bit inside the abi_ulong */
492 if ((b >> j) & 1)
493 FD_SET(k, fds);
494 k++;
498 unlock_user(target_fds, target_fds_addr, 0);
500 return 0;
503 static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
504 const fd_set *fds,
505 int n)
507 int i, nw, j, k;
508 abi_long v;
509 abi_ulong *target_fds;
511 nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
512 if (!(target_fds = lock_user(VERIFY_WRITE,
513 target_fds_addr,
514 sizeof(abi_ulong) * nw,
515 0)))
516 return -TARGET_EFAULT;
518 k = 0;
519 for (i = 0; i < nw; i++) {
520 v = 0;
521 for (j = 0; j < TARGET_ABI_BITS; j++) {
522 v |= ((FD_ISSET(k, fds) != 0) << j);
523 k++;
525 __put_user(v, &target_fds[i]);
528 unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
530 return 0;
533 #if defined(__alpha__)
534 #define HOST_HZ 1024
535 #else
536 #define HOST_HZ 100
537 #endif
539 static inline abi_long host_to_target_clock_t(long ticks)
541 #if HOST_HZ == TARGET_HZ
542 return ticks;
543 #else
544 return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
545 #endif
548 static inline abi_long host_to_target_rusage(abi_ulong target_addr,
549 const struct rusage *rusage)
551 struct target_rusage *target_rusage;
553 if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
554 return -TARGET_EFAULT;
555 target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
556 target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
557 target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
558 target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec);
559 target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss);
560 target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss);
561 target_rusage->ru_idrss = tswapl(rusage->ru_idrss);
562 target_rusage->ru_isrss = tswapl(rusage->ru_isrss);
563 target_rusage->ru_minflt = tswapl(rusage->ru_minflt);
564 target_rusage->ru_majflt = tswapl(rusage->ru_majflt);
565 target_rusage->ru_nswap = tswapl(rusage->ru_nswap);
566 target_rusage->ru_inblock = tswapl(rusage->ru_inblock);
567 target_rusage->ru_oublock = tswapl(rusage->ru_oublock);
568 target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd);
569 target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv);
570 target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);
571 target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
572 target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
573 unlock_user_struct(target_rusage, target_addr, 1);
575 return 0;
578 static inline abi_long copy_from_user_timeval(struct timeval *tv,
579 abi_ulong target_tv_addr)
581 struct target_timeval *target_tv;
583 if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
584 return -TARGET_EFAULT;
586 __get_user(tv->tv_sec, &target_tv->tv_sec);
587 __get_user(tv->tv_usec, &target_tv->tv_usec);
589 unlock_user_struct(target_tv, target_tv_addr, 0);
591 return 0;
594 static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
595 const struct timeval *tv)
597 struct target_timeval *target_tv;
599 if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
600 return -TARGET_EFAULT;
602 __put_user(tv->tv_sec, &target_tv->tv_sec);
603 __put_user(tv->tv_usec, &target_tv->tv_usec);
605 unlock_user_struct(target_tv, target_tv_addr, 1);
607 return 0;
611 /* do_select() must return target values and target errnos. */
612 static abi_long do_select(int n,
613 abi_ulong rfd_addr, abi_ulong wfd_addr,
614 abi_ulong efd_addr, abi_ulong target_tv_addr)
616 fd_set rfds, wfds, efds;
617 fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
618 struct timeval tv, *tv_ptr;
619 abi_long ret;
621 if (rfd_addr) {
622 if (copy_from_user_fdset(&rfds, rfd_addr, n))
623 return -TARGET_EFAULT;
624 rfds_ptr = &rfds;
625 } else {
626 rfds_ptr = NULL;
628 if (wfd_addr) {
629 if (copy_from_user_fdset(&wfds, wfd_addr, n))
630 return -TARGET_EFAULT;
631 wfds_ptr = &wfds;
632 } else {
633 wfds_ptr = NULL;
635 if (efd_addr) {
636 if (copy_from_user_fdset(&efds, efd_addr, n))
637 return -TARGET_EFAULT;
638 efds_ptr = &efds;
639 } else {
640 efds_ptr = NULL;
643 if (target_tv_addr) {
644 if (copy_from_user_timeval(&tv, target_tv_addr))
645 return -TARGET_EFAULT;
646 tv_ptr = &tv;
647 } else {
648 tv_ptr = NULL;
651 ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
653 if (!is_error(ret)) {
654 if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
655 return -TARGET_EFAULT;
656 if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
657 return -TARGET_EFAULT;
658 if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
659 return -TARGET_EFAULT;
661 if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
662 return -TARGET_EFAULT;
665 return ret;
668 static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
669 abi_ulong target_addr,
670 socklen_t len)
672 struct target_sockaddr *target_saddr;
674 target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
675 if (!target_saddr)
676 return -TARGET_EFAULT;
677 memcpy(addr, target_saddr, len);
678 addr->sa_family = tswap16(target_saddr->sa_family);
679 unlock_user(target_saddr, target_addr, 0);
681 return 0;
684 static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
685 struct sockaddr *addr,
686 socklen_t len)
688 struct target_sockaddr *target_saddr;
690 target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
691 if (!target_saddr)
692 return -TARGET_EFAULT;
693 memcpy(target_saddr, addr, len);
694 target_saddr->sa_family = tswap16(addr->sa_family);
695 unlock_user(target_saddr, target_addr, len);
697 return 0;
700 /* ??? Should this also swap msgh->name? */
701 static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
702 struct target_msghdr *target_msgh)
704 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
705 abi_long msg_controllen;
706 abi_ulong target_cmsg_addr;
707 struct target_cmsghdr *target_cmsg;
708 socklen_t space = 0;
710 msg_controllen = tswapl(target_msgh->msg_controllen);
711 if (msg_controllen < sizeof (struct target_cmsghdr))
712 goto the_end;
713 target_cmsg_addr = tswapl(target_msgh->msg_control);
714 target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
715 if (!target_cmsg)
716 return -TARGET_EFAULT;
718 while (cmsg && target_cmsg) {
719 void *data = CMSG_DATA(cmsg);
720 void *target_data = TARGET_CMSG_DATA(target_cmsg);
722 int len = tswapl(target_cmsg->cmsg_len)
723 - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
725 space += CMSG_SPACE(len);
726 if (space > msgh->msg_controllen) {
727 space -= CMSG_SPACE(len);
728 gemu_log("Host cmsg overflow\n");
729 break;
732 cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
733 cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
734 cmsg->cmsg_len = CMSG_LEN(len);
736 if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
737 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
738 memcpy(data, target_data, len);
739 } else {
740 int *fd = (int *)data;
741 int *target_fd = (int *)target_data;
742 int i, numfds = len / sizeof(int);
744 for (i = 0; i < numfds; i++)
745 fd[i] = tswap32(target_fd[i]);
748 cmsg = CMSG_NXTHDR(msgh, cmsg);
749 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
751 unlock_user(target_cmsg, target_cmsg_addr, 0);
752 the_end:
753 msgh->msg_controllen = space;
754 return 0;
757 /* ??? Should this also swap msgh->name? */
758 static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
759 struct msghdr *msgh)
761 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
762 abi_long msg_controllen;
763 abi_ulong target_cmsg_addr;
764 struct target_cmsghdr *target_cmsg;
765 socklen_t space = 0;
767 msg_controllen = tswapl(target_msgh->msg_controllen);
768 if (msg_controllen < sizeof (struct target_cmsghdr))
769 goto the_end;
770 target_cmsg_addr = tswapl(target_msgh->msg_control);
771 target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
772 if (!target_cmsg)
773 return -TARGET_EFAULT;
775 while (cmsg && target_cmsg) {
776 void *data = CMSG_DATA(cmsg);
777 void *target_data = TARGET_CMSG_DATA(target_cmsg);
779 int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
781 space += TARGET_CMSG_SPACE(len);
782 if (space > msg_controllen) {
783 space -= TARGET_CMSG_SPACE(len);
784 gemu_log("Target cmsg overflow\n");
785 break;
788 target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
789 target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
790 target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
792 if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
793 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
794 memcpy(target_data, data, len);
795 } else {
796 int *fd = (int *)data;
797 int *target_fd = (int *)target_data;
798 int i, numfds = len / sizeof(int);
800 for (i = 0; i < numfds; i++)
801 target_fd[i] = tswap32(fd[i]);
804 cmsg = CMSG_NXTHDR(msgh, cmsg);
805 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
807 unlock_user(target_cmsg, target_cmsg_addr, space);
808 the_end:
809 target_msgh->msg_controllen = tswapl(space);
810 return 0;
813 /* do_setsockopt() Must return target values and target errnos. */
814 static abi_long do_setsockopt(int sockfd, int level, int optname,
815 abi_ulong optval_addr, socklen_t optlen)
817 abi_long ret;
818 int val;
820 switch(level) {
821 case SOL_TCP:
822 /* TCP options all take an 'int' value. */
823 if (optlen < sizeof(uint32_t))
824 return -TARGET_EINVAL;
826 if (get_user_u32(val, optval_addr))
827 return -TARGET_EFAULT;
828 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
829 break;
830 case SOL_IP:
831 switch(optname) {
832 case IP_TOS:
833 case IP_TTL:
834 case IP_HDRINCL:
835 case IP_ROUTER_ALERT:
836 case IP_RECVOPTS:
837 case IP_RETOPTS:
838 case IP_PKTINFO:
839 case IP_MTU_DISCOVER:
840 case IP_RECVERR:
841 case IP_RECVTOS:
842 #ifdef IP_FREEBIND
843 case IP_FREEBIND:
844 #endif
845 case IP_MULTICAST_TTL:
846 case IP_MULTICAST_LOOP:
847 val = 0;
848 if (optlen >= sizeof(uint32_t)) {
849 if (get_user_u32(val, optval_addr))
850 return -TARGET_EFAULT;
851 } else if (optlen >= 1) {
852 if (get_user_u8(val, optval_addr))
853 return -TARGET_EFAULT;
855 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
856 break;
857 default:
858 goto unimplemented;
860 break;
861 case TARGET_SOL_SOCKET:
862 switch (optname) {
863 /* Options with 'int' argument. */
864 case TARGET_SO_DEBUG:
865 optname = SO_DEBUG;
866 break;
867 case TARGET_SO_REUSEADDR:
868 optname = SO_REUSEADDR;
869 break;
870 case TARGET_SO_TYPE:
871 optname = SO_TYPE;
872 break;
873 case TARGET_SO_ERROR:
874 optname = SO_ERROR;
875 break;
876 case TARGET_SO_DONTROUTE:
877 optname = SO_DONTROUTE;
878 break;
879 case TARGET_SO_BROADCAST:
880 optname = SO_BROADCAST;
881 break;
882 case TARGET_SO_SNDBUF:
883 optname = SO_SNDBUF;
884 break;
885 case TARGET_SO_RCVBUF:
886 optname = SO_RCVBUF;
887 break;
888 case TARGET_SO_KEEPALIVE:
889 optname = SO_KEEPALIVE;
890 break;
891 case TARGET_SO_OOBINLINE:
892 optname = SO_OOBINLINE;
893 break;
894 case TARGET_SO_NO_CHECK:
895 optname = SO_NO_CHECK;
896 break;
897 case TARGET_SO_PRIORITY:
898 optname = SO_PRIORITY;
899 break;
900 #ifdef SO_BSDCOMPAT
901 case TARGET_SO_BSDCOMPAT:
902 optname = SO_BSDCOMPAT;
903 break;
904 #endif
905 case TARGET_SO_PASSCRED:
906 optname = SO_PASSCRED;
907 break;
908 case TARGET_SO_TIMESTAMP:
909 optname = SO_TIMESTAMP;
910 break;
911 case TARGET_SO_RCVLOWAT:
912 optname = SO_RCVLOWAT;
913 break;
914 case TARGET_SO_RCVTIMEO:
915 optname = SO_RCVTIMEO;
916 break;
917 case TARGET_SO_SNDTIMEO:
918 optname = SO_SNDTIMEO;
919 break;
920 break;
921 default:
922 goto unimplemented;
924 if (optlen < sizeof(uint32_t))
925 return -TARGET_EINVAL;
927 if (get_user_u32(val, optval_addr))
928 return -TARGET_EFAULT;
929 ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
930 break;
931 default:
932 unimplemented:
933 gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
934 ret = -TARGET_ENOPROTOOPT;
936 return ret;
939 /* do_getsockopt() Must return target values and target errnos. */
940 static abi_long do_getsockopt(int sockfd, int level, int optname,
941 abi_ulong optval_addr, abi_ulong optlen)
943 abi_long ret;
944 int len, lv, val;
946 switch(level) {
947 case TARGET_SOL_SOCKET:
948 level = SOL_SOCKET;
949 switch (optname) {
950 case TARGET_SO_LINGER:
951 case TARGET_SO_RCVTIMEO:
952 case TARGET_SO_SNDTIMEO:
953 case TARGET_SO_PEERCRED:
954 case TARGET_SO_PEERNAME:
955 /* These don't just return a single integer */
956 goto unimplemented;
957 default:
958 goto int_case;
960 break;
961 case SOL_TCP:
962 /* TCP options all take an 'int' value. */
963 int_case:
964 if (get_user_u32(len, optlen))
965 return -TARGET_EFAULT;
966 if (len < 0)
967 return -TARGET_EINVAL;
968 lv = sizeof(int);
969 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
970 if (ret < 0)
971 return ret;
972 val = tswap32(val);
973 if (len > lv)
974 len = lv;
975 if (len == 4) {
976 if (put_user_u32(val, optval_addr))
977 return -TARGET_EFAULT;
978 } else {
979 if (put_user_u8(val, optval_addr))
980 return -TARGET_EFAULT;
982 if (put_user_u32(len, optlen))
983 return -TARGET_EFAULT;
984 break;
985 case SOL_IP:
986 switch(optname) {
987 case IP_TOS:
988 case IP_TTL:
989 case IP_HDRINCL:
990 case IP_ROUTER_ALERT:
991 case IP_RECVOPTS:
992 case IP_RETOPTS:
993 case IP_PKTINFO:
994 case IP_MTU_DISCOVER:
995 case IP_RECVERR:
996 case IP_RECVTOS:
997 #ifdef IP_FREEBIND
998 case IP_FREEBIND:
999 #endif
1000 case IP_MULTICAST_TTL:
1001 case IP_MULTICAST_LOOP:
1002 if (get_user_u32(len, optlen))
1003 return -TARGET_EFAULT;
1004 if (len < 0)
1005 return -TARGET_EINVAL;
1006 lv = sizeof(int);
1007 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1008 if (ret < 0)
1009 return ret;
1010 if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
1011 len = 1;
1012 if (put_user_u32(len, optlen)
1013 || put_user_u8(val, optval_addr))
1014 return -TARGET_EFAULT;
1015 } else {
1016 if (len > sizeof(int))
1017 len = sizeof(int);
1018 if (put_user_u32(len, optlen)
1019 || put_user_u32(val, optval_addr))
1020 return -TARGET_EFAULT;
1022 break;
1023 default:
1024 ret = -TARGET_ENOPROTOOPT;
1025 break;
1027 break;
1028 default:
1029 unimplemented:
1030 gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1031 level, optname);
1032 ret = -TARGET_EOPNOTSUPP;
1033 break;
1035 return ret;
1038 /* FIXME
1039 * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1040 * other lock functions have a return code of 0 for failure.
1042 static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1043 int count, int copy)
1045 struct target_iovec *target_vec;
1046 abi_ulong base;
1047 int i, j;
1049 target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1050 if (!target_vec)
1051 return -TARGET_EFAULT;
1052 for(i = 0;i < count; i++) {
1053 base = tswapl(target_vec[i].iov_base);
1054 vec[i].iov_len = tswapl(target_vec[i].iov_len);
1055 if (vec[i].iov_len != 0) {
1056 vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
1057 if (!vec[i].iov_base && vec[i].iov_len)
1058 goto fail;
1059 } else {
1060 /* zero length pointer is ignored */
1061 vec[i].iov_base = NULL;
1064 unlock_user (target_vec, target_addr, 0);
1065 return 0;
1066 fail:
1067 /* failure - unwind locks */
1068 for (j = 0; j < i; j++) {
1069 base = tswapl(target_vec[j].iov_base);
1070 unlock_user(vec[j].iov_base, base, 0);
1072 unlock_user (target_vec, target_addr, 0);
1073 return -TARGET_EFAULT;
1076 static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1077 int count, int copy)
1079 struct target_iovec *target_vec;
1080 abi_ulong base;
1081 int i;
1083 target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1084 if (!target_vec)
1085 return -TARGET_EFAULT;
1086 for(i = 0;i < count; i++) {
1087 base = tswapl(target_vec[i].iov_base);
1088 unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1090 unlock_user (target_vec, target_addr, 0);
1092 return 0;
1095 /* do_socket() Must return target values and target errnos. */
1096 static abi_long do_socket(int domain, int type, int protocol)
1098 #if defined(TARGET_MIPS)
1099 switch(type) {
1100 case TARGET_SOCK_DGRAM:
1101 type = SOCK_DGRAM;
1102 break;
1103 case TARGET_SOCK_STREAM:
1104 type = SOCK_STREAM;
1105 break;
1106 case TARGET_SOCK_RAW:
1107 type = SOCK_RAW;
1108 break;
1109 case TARGET_SOCK_RDM:
1110 type = SOCK_RDM;
1111 break;
1112 case TARGET_SOCK_SEQPACKET:
1113 type = SOCK_SEQPACKET;
1114 break;
1115 case TARGET_SOCK_PACKET:
1116 type = SOCK_PACKET;
1117 break;
1119 #endif
1120 if (domain == PF_NETLINK)
1121 return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1122 return get_errno(socket(domain, type, protocol));
1125 /* do_bind() Must return target values and target errnos. */
1126 static abi_long do_bind(int sockfd, abi_ulong target_addr,
1127 socklen_t addrlen)
1129 void *addr = alloca(addrlen);
1131 target_to_host_sockaddr(addr, target_addr, addrlen);
1132 return get_errno(bind(sockfd, addr, addrlen));
1135 /* do_connect() Must return target values and target errnos. */
1136 static abi_long do_connect(int sockfd, abi_ulong target_addr,
1137 socklen_t addrlen)
1139 void *addr = alloca(addrlen);
1141 target_to_host_sockaddr(addr, target_addr, addrlen);
1142 return get_errno(connect(sockfd, addr, addrlen));
1145 /* do_sendrecvmsg() Must return target values and target errnos. */
1146 static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1147 int flags, int send)
1149 abi_long ret;
1150 struct target_msghdr *msgp;
1151 struct msghdr msg;
1152 int count;
1153 struct iovec *vec;
1154 abi_ulong target_vec;
1156 /* FIXME */
1157 if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1158 msgp,
1159 target_msg,
1160 send ? 1 : 0))
1161 return -TARGET_EFAULT;
1162 if (msgp->msg_name) {
1163 msg.msg_namelen = tswap32(msgp->msg_namelen);
1164 msg.msg_name = alloca(msg.msg_namelen);
1165 target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
1166 msg.msg_namelen);
1167 } else {
1168 msg.msg_name = NULL;
1169 msg.msg_namelen = 0;
1171 msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
1172 msg.msg_control = alloca(msg.msg_controllen);
1173 msg.msg_flags = tswap32(msgp->msg_flags);
1175 count = tswapl(msgp->msg_iovlen);
1176 vec = alloca(count * sizeof(struct iovec));
1177 target_vec = tswapl(msgp->msg_iov);
1178 lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1179 msg.msg_iovlen = count;
1180 msg.msg_iov = vec;
1182 if (send) {
1183 ret = target_to_host_cmsg(&msg, msgp);
1184 if (ret == 0)
1185 ret = get_errno(sendmsg(fd, &msg, flags));
1186 } else {
1187 ret = get_errno(recvmsg(fd, &msg, flags));
1188 if (!is_error(ret))
1189 ret = host_to_target_cmsg(msgp, &msg);
1191 unlock_iovec(vec, target_vec, count, !send);
1192 unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1193 return ret;
1196 /* do_accept() Must return target values and target errnos. */
1197 static abi_long do_accept(int fd, abi_ulong target_addr,
1198 abi_ulong target_addrlen_addr)
1200 socklen_t addrlen;
1201 void *addr;
1202 abi_long ret;
1204 if (get_user_u32(addrlen, target_addrlen_addr))
1205 return -TARGET_EFAULT;
1207 addr = alloca(addrlen);
1209 ret = get_errno(accept(fd, addr, &addrlen));
1210 if (!is_error(ret)) {
1211 host_to_target_sockaddr(target_addr, addr, addrlen);
1212 if (put_user_u32(addrlen, target_addrlen_addr))
1213 ret = -TARGET_EFAULT;
1215 return ret;
1218 /* do_getpeername() Must return target values and target errnos. */
1219 static abi_long do_getpeername(int fd, abi_ulong target_addr,
1220 abi_ulong target_addrlen_addr)
1222 socklen_t addrlen;
1223 void *addr;
1224 abi_long ret;
1226 if (get_user_u32(addrlen, target_addrlen_addr))
1227 return -TARGET_EFAULT;
1229 addr = alloca(addrlen);
1231 ret = get_errno(getpeername(fd, addr, &addrlen));
1232 if (!is_error(ret)) {
1233 host_to_target_sockaddr(target_addr, addr, addrlen);
1234 if (put_user_u32(addrlen, target_addrlen_addr))
1235 ret = -TARGET_EFAULT;
1237 return ret;
1240 /* do_getsockname() Must return target values and target errnos. */
1241 static abi_long do_getsockname(int fd, abi_ulong target_addr,
1242 abi_ulong target_addrlen_addr)
1244 socklen_t addrlen;
1245 void *addr;
1246 abi_long ret;
1248 if (get_user_u32(addrlen, target_addrlen_addr))
1249 return -TARGET_EFAULT;
1251 addr = alloca(addrlen);
1253 ret = get_errno(getsockname(fd, addr, &addrlen));
1254 if (!is_error(ret)) {
1255 host_to_target_sockaddr(target_addr, addr, addrlen);
1256 if (put_user_u32(addrlen, target_addrlen_addr))
1257 ret = -TARGET_EFAULT;
1259 return ret;
1262 /* do_socketpair() Must return target values and target errnos. */
1263 static abi_long do_socketpair(int domain, int type, int protocol,
1264 abi_ulong target_tab_addr)
1266 int tab[2];
1267 abi_long ret;
1269 ret = get_errno(socketpair(domain, type, protocol, tab));
1270 if (!is_error(ret)) {
1271 if (put_user_s32(tab[0], target_tab_addr)
1272 || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1273 ret = -TARGET_EFAULT;
1275 return ret;
1278 /* do_sendto() Must return target values and target errnos. */
1279 static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
1280 abi_ulong target_addr, socklen_t addrlen)
1282 void *addr;
1283 void *host_msg;
1284 abi_long ret;
1286 host_msg = lock_user(VERIFY_READ, msg, len, 1);
1287 if (!host_msg)
1288 return -TARGET_EFAULT;
1289 if (target_addr) {
1290 addr = alloca(addrlen);
1291 target_to_host_sockaddr(addr, target_addr, addrlen);
1292 ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
1293 } else {
1294 ret = get_errno(send(fd, host_msg, len, flags));
1296 unlock_user(host_msg, msg, 0);
1297 return ret;
1300 /* do_recvfrom() Must return target values and target errnos. */
1301 static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
1302 abi_ulong target_addr,
1303 abi_ulong target_addrlen)
1305 socklen_t addrlen;
1306 void *addr;
1307 void *host_msg;
1308 abi_long ret;
1310 host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
1311 if (!host_msg)
1312 return -TARGET_EFAULT;
1313 if (target_addr) {
1314 if (get_user_u32(addrlen, target_addrlen)) {
1315 ret = -TARGET_EFAULT;
1316 goto fail;
1318 addr = alloca(addrlen);
1319 ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
1320 } else {
1321 addr = NULL; /* To keep compiler quiet. */
1322 ret = get_errno(recv(fd, host_msg, len, flags));
1324 if (!is_error(ret)) {
1325 if (target_addr) {
1326 host_to_target_sockaddr(target_addr, addr, addrlen);
1327 if (put_user_u32(addrlen, target_addrlen)) {
1328 ret = -TARGET_EFAULT;
1329 goto fail;
1332 unlock_user(host_msg, msg, len);
1333 } else {
1334 fail:
1335 unlock_user(host_msg, msg, 0);
1337 return ret;
1340 #ifdef TARGET_NR_socketcall
1341 /* do_socketcall() Must return target values and target errnos. */
1342 static abi_long do_socketcall(int num, abi_ulong vptr)
1344 abi_long ret;
1345 const int n = sizeof(abi_ulong);
1347 switch(num) {
1348 case SOCKOP_socket:
1350 int domain, type, protocol;
1352 if (get_user_s32(domain, vptr)
1353 || get_user_s32(type, vptr + n)
1354 || get_user_s32(protocol, vptr + 2 * n))
1355 return -TARGET_EFAULT;
1357 ret = do_socket(domain, type, protocol);
1359 break;
1360 case SOCKOP_bind:
1362 int sockfd;
1363 abi_ulong target_addr;
1364 socklen_t addrlen;
1366 if (get_user_s32(sockfd, vptr)
1367 || get_user_ual(target_addr, vptr + n)
1368 || get_user_u32(addrlen, vptr + 2 * n))
1369 return -TARGET_EFAULT;
1371 ret = do_bind(sockfd, target_addr, addrlen);
1373 break;
1374 case SOCKOP_connect:
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_connect(sockfd, target_addr, addrlen);
1387 break;
1388 case SOCKOP_listen:
1390 int sockfd, backlog;
1392 if (get_user_s32(sockfd, vptr)
1393 || get_user_s32(backlog, vptr + n))
1394 return -TARGET_EFAULT;
1396 ret = get_errno(listen(sockfd, backlog));
1398 break;
1399 case SOCKOP_accept:
1401 int sockfd;
1402 abi_ulong target_addr, target_addrlen;
1404 if (get_user_s32(sockfd, vptr)
1405 || get_user_ual(target_addr, vptr + n)
1406 || get_user_u32(target_addrlen, vptr + 2 * n))
1407 return -TARGET_EFAULT;
1409 ret = do_accept(sockfd, target_addr, target_addrlen);
1411 break;
1412 case SOCKOP_getsockname:
1414 int sockfd;
1415 abi_ulong target_addr, target_addrlen;
1417 if (get_user_s32(sockfd, vptr)
1418 || get_user_ual(target_addr, vptr + n)
1419 || get_user_u32(target_addrlen, vptr + 2 * n))
1420 return -TARGET_EFAULT;
1422 ret = do_getsockname(sockfd, target_addr, target_addrlen);
1424 break;
1425 case SOCKOP_getpeername:
1427 int sockfd;
1428 abi_ulong target_addr, target_addrlen;
1430 if (get_user_s32(sockfd, vptr)
1431 || get_user_ual(target_addr, vptr + n)
1432 || get_user_u32(target_addrlen, vptr + 2 * n))
1433 return -TARGET_EFAULT;
1435 ret = do_getpeername(sockfd, target_addr, target_addrlen);
1437 break;
1438 case SOCKOP_socketpair:
1440 int domain, type, protocol;
1441 abi_ulong tab;
1443 if (get_user_s32(domain, vptr)
1444 || get_user_s32(type, vptr + n)
1445 || get_user_s32(protocol, vptr + 2 * n)
1446 || get_user_ual(tab, vptr + 3 * n))
1447 return -TARGET_EFAULT;
1449 ret = do_socketpair(domain, type, protocol, tab);
1451 break;
1452 case SOCKOP_send:
1454 int sockfd;
1455 abi_ulong msg;
1456 size_t len;
1457 int flags;
1459 if (get_user_s32(sockfd, vptr)
1460 || get_user_ual(msg, vptr + n)
1461 || get_user_ual(len, vptr + 2 * n)
1462 || get_user_s32(flags, vptr + 3 * n))
1463 return -TARGET_EFAULT;
1465 ret = do_sendto(sockfd, msg, len, flags, 0, 0);
1467 break;
1468 case SOCKOP_recv:
1470 int sockfd;
1471 abi_ulong msg;
1472 size_t len;
1473 int flags;
1475 if (get_user_s32(sockfd, vptr)
1476 || get_user_ual(msg, vptr + n)
1477 || get_user_ual(len, vptr + 2 * n)
1478 || get_user_s32(flags, vptr + 3 * n))
1479 return -TARGET_EFAULT;
1481 ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
1483 break;
1484 case SOCKOP_sendto:
1486 int sockfd;
1487 abi_ulong msg;
1488 size_t len;
1489 int flags;
1490 abi_ulong addr;
1491 socklen_t addrlen;
1493 if (get_user_s32(sockfd, vptr)
1494 || get_user_ual(msg, vptr + n)
1495 || get_user_ual(len, vptr + 2 * n)
1496 || get_user_s32(flags, vptr + 3 * n)
1497 || get_user_ual(addr, vptr + 4 * n)
1498 || get_user_u32(addrlen, vptr + 5 * n))
1499 return -TARGET_EFAULT;
1501 ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
1503 break;
1504 case SOCKOP_recvfrom:
1506 int sockfd;
1507 abi_ulong msg;
1508 size_t len;
1509 int flags;
1510 abi_ulong addr;
1511 socklen_t addrlen;
1513 if (get_user_s32(sockfd, vptr)
1514 || get_user_ual(msg, vptr + n)
1515 || get_user_ual(len, vptr + 2 * n)
1516 || get_user_s32(flags, vptr + 3 * n)
1517 || get_user_ual(addr, vptr + 4 * n)
1518 || get_user_u32(addrlen, vptr + 5 * n))
1519 return -TARGET_EFAULT;
1521 ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
1523 break;
1524 case SOCKOP_shutdown:
1526 int sockfd, how;
1528 if (get_user_s32(sockfd, vptr)
1529 || get_user_s32(how, vptr + n))
1530 return -TARGET_EFAULT;
1532 ret = get_errno(shutdown(sockfd, how));
1534 break;
1535 case SOCKOP_sendmsg:
1536 case SOCKOP_recvmsg:
1538 int fd;
1539 abi_ulong target_msg;
1540 int flags;
1542 if (get_user_s32(fd, vptr)
1543 || get_user_ual(target_msg, vptr + n)
1544 || get_user_s32(flags, vptr + 2 * n))
1545 return -TARGET_EFAULT;
1547 ret = do_sendrecvmsg(fd, target_msg, flags,
1548 (num == SOCKOP_sendmsg));
1550 break;
1551 case SOCKOP_setsockopt:
1553 int sockfd;
1554 int level;
1555 int optname;
1556 abi_ulong optval;
1557 socklen_t optlen;
1559 if (get_user_s32(sockfd, vptr)
1560 || get_user_s32(level, vptr + n)
1561 || get_user_s32(optname, vptr + 2 * n)
1562 || get_user_ual(optval, vptr + 3 * n)
1563 || get_user_u32(optlen, vptr + 4 * n))
1564 return -TARGET_EFAULT;
1566 ret = do_setsockopt(sockfd, level, optname, optval, optlen);
1568 break;
1569 case SOCKOP_getsockopt:
1571 int sockfd;
1572 int level;
1573 int optname;
1574 abi_ulong optval;
1575 socklen_t optlen;
1577 if (get_user_s32(sockfd, vptr)
1578 || get_user_s32(level, vptr + n)
1579 || get_user_s32(optname, vptr + 2 * n)
1580 || get_user_ual(optval, vptr + 3 * n)
1581 || get_user_u32(optlen, vptr + 4 * n))
1582 return -TARGET_EFAULT;
1584 ret = do_getsockopt(sockfd, level, optname, optval, optlen);
1586 break;
1587 default:
1588 gemu_log("Unsupported socketcall: %d\n", num);
1589 ret = -TARGET_ENOSYS;
1590 break;
1592 return ret;
1594 #endif
1596 #ifdef TARGET_NR_ipc
1597 #define N_SHM_REGIONS 32
1599 static struct shm_region {
1600 abi_ulong start;
1601 abi_ulong size;
1602 } shm_regions[N_SHM_REGIONS];
1604 struct target_ipc_perm
1606 abi_long __key;
1607 abi_ulong uid;
1608 abi_ulong gid;
1609 abi_ulong cuid;
1610 abi_ulong cgid;
1611 unsigned short int mode;
1612 unsigned short int __pad1;
1613 unsigned short int __seq;
1614 unsigned short int __pad2;
1615 abi_ulong __unused1;
1616 abi_ulong __unused2;
1619 struct target_semid_ds
1621 struct target_ipc_perm sem_perm;
1622 abi_ulong sem_otime;
1623 abi_ulong __unused1;
1624 abi_ulong sem_ctime;
1625 abi_ulong __unused2;
1626 abi_ulong sem_nsems;
1627 abi_ulong __unused3;
1628 abi_ulong __unused4;
1631 static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
1632 abi_ulong target_addr)
1634 struct target_ipc_perm *target_ip;
1635 struct target_semid_ds *target_sd;
1637 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
1638 return -TARGET_EFAULT;
1639 target_ip=&(target_sd->sem_perm);
1640 host_ip->__key = tswapl(target_ip->__key);
1641 host_ip->uid = tswapl(target_ip->uid);
1642 host_ip->gid = tswapl(target_ip->gid);
1643 host_ip->cuid = tswapl(target_ip->cuid);
1644 host_ip->cgid = tswapl(target_ip->cgid);
1645 host_ip->mode = tswapl(target_ip->mode);
1646 unlock_user_struct(target_sd, target_addr, 0);
1647 return 0;
1650 static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
1651 struct ipc_perm *host_ip)
1653 struct target_ipc_perm *target_ip;
1654 struct target_semid_ds *target_sd;
1656 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
1657 return -TARGET_EFAULT;
1658 target_ip = &(target_sd->sem_perm);
1659 target_ip->__key = tswapl(host_ip->__key);
1660 target_ip->uid = tswapl(host_ip->uid);
1661 target_ip->gid = tswapl(host_ip->gid);
1662 target_ip->cuid = tswapl(host_ip->cuid);
1663 target_ip->cgid = tswapl(host_ip->cgid);
1664 target_ip->mode = tswapl(host_ip->mode);
1665 unlock_user_struct(target_sd, target_addr, 1);
1666 return 0;
1669 static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
1670 abi_ulong target_addr)
1672 struct target_semid_ds *target_sd;
1674 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
1675 return -TARGET_EFAULT;
1676 target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr);
1677 host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
1678 host_sd->sem_otime = tswapl(target_sd->sem_otime);
1679 host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
1680 unlock_user_struct(target_sd, target_addr, 0);
1681 return 0;
1684 static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
1685 struct semid_ds *host_sd)
1687 struct target_semid_ds *target_sd;
1689 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
1690 return -TARGET_EFAULT;
1691 host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm));
1692 target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
1693 target_sd->sem_otime = tswapl(host_sd->sem_otime);
1694 target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
1695 unlock_user_struct(target_sd, target_addr, 1);
1696 return 0;
1699 union semun {
1700 int val;
1701 struct semid_ds *buf;
1702 unsigned short *array;
1705 union target_semun {
1706 int val;
1707 abi_long buf;
1708 unsigned short int *array;
1711 static inline abi_long target_to_host_semun(int cmd,
1712 union semun *host_su,
1713 abi_ulong target_addr,
1714 struct semid_ds *ds)
1716 union target_semun *target_su;
1718 switch( cmd ) {
1719 case IPC_STAT:
1720 case IPC_SET:
1721 if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1722 return -TARGET_EFAULT;
1723 target_to_host_semid_ds(ds,target_su->buf);
1724 host_su->buf = ds;
1725 unlock_user_struct(target_su, target_addr, 0);
1726 break;
1727 case GETVAL:
1728 case SETVAL:
1729 if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1730 return -TARGET_EFAULT;
1731 host_su->val = tswapl(target_su->val);
1732 unlock_user_struct(target_su, target_addr, 0);
1733 break;
1734 case GETALL:
1735 case SETALL:
1736 if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1737 return -TARGET_EFAULT;
1738 *host_su->array = tswap16(*target_su->array);
1739 unlock_user_struct(target_su, target_addr, 0);
1740 break;
1741 default:
1742 gemu_log("semun operation not fully supported: %d\n", (int)cmd);
1744 return 0;
1747 static inline abi_long host_to_target_semun(int cmd,
1748 abi_ulong target_addr,
1749 union semun *host_su,
1750 struct semid_ds *ds)
1752 union target_semun *target_su;
1754 switch( cmd ) {
1755 case IPC_STAT:
1756 case IPC_SET:
1757 if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1758 return -TARGET_EFAULT;
1759 host_to_target_semid_ds(target_su->buf,ds);
1760 unlock_user_struct(target_su, target_addr, 1);
1761 break;
1762 case GETVAL:
1763 case SETVAL:
1764 if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1765 return -TARGET_EFAULT;
1766 target_su->val = tswapl(host_su->val);
1767 unlock_user_struct(target_su, target_addr, 1);
1768 break;
1769 case GETALL:
1770 case SETALL:
1771 if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1772 return -TARGET_EFAULT;
1773 *target_su->array = tswap16(*host_su->array);
1774 unlock_user_struct(target_su, target_addr, 1);
1775 break;
1776 default:
1777 gemu_log("semun operation not fully supported: %d\n", (int)cmd);
1779 return 0;
1782 static inline abi_long do_semctl(int first, int second, int third,
1783 abi_long ptr)
1785 union semun arg;
1786 struct semid_ds dsarg;
1787 int cmd = third&0xff;
1788 abi_long ret = 0;
1790 switch( cmd ) {
1791 case GETVAL:
1792 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1793 ret = get_errno(semctl(first, second, cmd, arg));
1794 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1795 break;
1796 case SETVAL:
1797 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1798 ret = get_errno(semctl(first, second, cmd, arg));
1799 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1800 break;
1801 case GETALL:
1802 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1803 ret = get_errno(semctl(first, second, cmd, arg));
1804 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1805 break;
1806 case SETALL:
1807 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1808 ret = get_errno(semctl(first, second, cmd, arg));
1809 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1810 break;
1811 case IPC_STAT:
1812 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1813 ret = get_errno(semctl(first, second, cmd, arg));
1814 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1815 break;
1816 case IPC_SET:
1817 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1818 ret = get_errno(semctl(first, second, cmd, arg));
1819 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1820 break;
1821 default:
1822 ret = get_errno(semctl(first, second, cmd, arg));
1825 return ret;
1828 struct target_msqid_ds
1830 struct target_ipc_perm msg_perm;
1831 abi_ulong msg_stime;
1832 abi_ulong __unused1;
1833 abi_ulong msg_rtime;
1834 abi_ulong __unused2;
1835 abi_ulong msg_ctime;
1836 abi_ulong __unused3;
1837 abi_ulong __msg_cbytes;
1838 abi_ulong msg_qnum;
1839 abi_ulong msg_qbytes;
1840 abi_ulong msg_lspid;
1841 abi_ulong msg_lrpid;
1842 abi_ulong __unused4;
1843 abi_ulong __unused5;
1846 static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
1847 abi_ulong target_addr)
1849 struct target_msqid_ds *target_md;
1851 if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
1852 return -TARGET_EFAULT;
1853 target_to_host_ipc_perm(&(host_md->msg_perm),target_addr);
1854 host_md->msg_stime = tswapl(target_md->msg_stime);
1855 host_md->msg_rtime = tswapl(target_md->msg_rtime);
1856 host_md->msg_ctime = tswapl(target_md->msg_ctime);
1857 host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
1858 host_md->msg_qnum = tswapl(target_md->msg_qnum);
1859 host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
1860 host_md->msg_lspid = tswapl(target_md->msg_lspid);
1861 host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
1862 unlock_user_struct(target_md, target_addr, 0);
1863 return 0;
1866 static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
1867 struct msqid_ds *host_md)
1869 struct target_msqid_ds *target_md;
1871 if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
1872 return -TARGET_EFAULT;
1873 host_to_target_ipc_perm(target_addr,&(host_md->msg_perm));
1874 target_md->msg_stime = tswapl(host_md->msg_stime);
1875 target_md->msg_rtime = tswapl(host_md->msg_rtime);
1876 target_md->msg_ctime = tswapl(host_md->msg_ctime);
1877 target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
1878 target_md->msg_qnum = tswapl(host_md->msg_qnum);
1879 target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
1880 target_md->msg_lspid = tswapl(host_md->msg_lspid);
1881 target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
1882 unlock_user_struct(target_md, target_addr, 1);
1883 return 0;
1886 static inline abi_long do_msgctl(int first, int second, abi_long ptr)
1888 struct msqid_ds dsarg;
1889 int cmd = second&0xff;
1890 abi_long ret = 0;
1891 switch( cmd ) {
1892 case IPC_STAT:
1893 case IPC_SET:
1894 target_to_host_msqid_ds(&dsarg,ptr);
1895 ret = get_errno(msgctl(first, cmd, &dsarg));
1896 host_to_target_msqid_ds(ptr,&dsarg);
1897 default:
1898 ret = get_errno(msgctl(first, cmd, &dsarg));
1900 return ret;
1903 struct target_msgbuf {
1904 abi_ulong mtype;
1905 char mtext[1];
1908 static inline abi_long do_msgsnd(int msqid, abi_long msgp,
1909 unsigned int msgsz, int msgflg)
1911 struct target_msgbuf *target_mb;
1912 struct msgbuf *host_mb;
1913 abi_long ret = 0;
1915 if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
1916 return -TARGET_EFAULT;
1917 host_mb = malloc(msgsz+sizeof(long));
1918 host_mb->mtype = tswapl(target_mb->mtype);
1919 memcpy(host_mb->mtext,target_mb->mtext,msgsz);
1920 ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
1921 free(host_mb);
1922 unlock_user_struct(target_mb, msgp, 0);
1924 return ret;
1927 static inline abi_long do_msgrcv(int msqid, abi_long msgp,
1928 unsigned int msgsz, int msgtype,
1929 int msgflg)
1931 struct target_msgbuf *target_mb;
1932 char *target_mtext;
1933 struct msgbuf *host_mb;
1934 abi_long ret = 0;
1936 if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
1937 return -TARGET_EFAULT;
1938 host_mb = malloc(msgsz+sizeof(long));
1939 ret = get_errno(msgrcv(msqid, host_mb, msgsz, 1, msgflg));
1940 if (ret > 0) {
1941 abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
1942 target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
1943 if (!target_mtext) {
1944 ret = -TARGET_EFAULT;
1945 goto end;
1947 memcpy(target_mb->mtext, host_mb->mtext, ret);
1948 unlock_user(target_mtext, target_mtext_addr, ret);
1950 target_mb->mtype = tswapl(host_mb->mtype);
1951 free(host_mb);
1953 end:
1954 if (target_mb)
1955 unlock_user_struct(target_mb, msgp, 1);
1956 return ret;
1959 /* ??? This only works with linear mappings. */
1960 /* do_ipc() must return target values and target errnos. */
1961 static abi_long do_ipc(unsigned int call, int first,
1962 int second, int third,
1963 abi_long ptr, abi_long fifth)
1965 int version;
1966 abi_long ret = 0;
1967 struct shmid_ds shm_info;
1968 int i;
1970 version = call >> 16;
1971 call &= 0xffff;
1973 switch (call) {
1974 case IPCOP_semop:
1975 ret = get_errno(semop(first,(struct sembuf *)g2h(ptr), second));
1976 break;
1978 case IPCOP_semget:
1979 ret = get_errno(semget(first, second, third));
1980 break;
1982 case IPCOP_semctl:
1983 ret = do_semctl(first, second, third, ptr);
1984 break;
1986 case IPCOP_semtimedop:
1987 gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
1988 ret = -TARGET_ENOSYS;
1989 break;
1991 case IPCOP_msgget:
1992 ret = get_errno(msgget(first, second));
1993 break;
1995 case IPCOP_msgsnd:
1996 ret = do_msgsnd(first, ptr, second, third);
1997 break;
1999 case IPCOP_msgctl:
2000 ret = do_msgctl(first, second, ptr);
2001 break;
2003 case IPCOP_msgrcv:
2005 /* XXX: this code is not correct */
2006 struct ipc_kludge
2008 void *__unbounded msgp;
2009 long int msgtyp;
2012 struct ipc_kludge *foo = (struct ipc_kludge *)g2h(ptr);
2013 struct msgbuf *msgp = (struct msgbuf *) foo->msgp;
2015 ret = do_msgrcv(first, (long)msgp, second, 0, third);
2018 break;
2020 case IPCOP_shmat:
2022 abi_ulong raddr;
2023 void *host_addr;
2024 /* SHM_* flags are the same on all linux platforms */
2025 host_addr = shmat(first, (void *)g2h(ptr), second);
2026 if (host_addr == (void *)-1) {
2027 ret = get_errno((long)host_addr);
2028 break;
2030 raddr = h2g((unsigned long)host_addr);
2031 /* find out the length of the shared memory segment */
2033 ret = get_errno(shmctl(first, IPC_STAT, &shm_info));
2034 if (is_error(ret)) {
2035 /* can't get length, bail out */
2036 shmdt(host_addr);
2037 break;
2039 page_set_flags(raddr, raddr + shm_info.shm_segsz,
2040 PAGE_VALID | PAGE_READ |
2041 ((second & SHM_RDONLY)? 0: PAGE_WRITE));
2042 for (i = 0; i < N_SHM_REGIONS; ++i) {
2043 if (shm_regions[i].start == 0) {
2044 shm_regions[i].start = raddr;
2045 shm_regions[i].size = shm_info.shm_segsz;
2046 break;
2049 if (put_user_ual(raddr, third))
2050 return -TARGET_EFAULT;
2051 ret = 0;
2053 break;
2054 case IPCOP_shmdt:
2055 for (i = 0; i < N_SHM_REGIONS; ++i) {
2056 if (shm_regions[i].start == ptr) {
2057 shm_regions[i].start = 0;
2058 page_set_flags(ptr, shm_regions[i].size, 0);
2059 break;
2062 ret = get_errno(shmdt((void *)g2h(ptr)));
2063 break;
2065 case IPCOP_shmget:
2066 /* IPC_* flag values are the same on all linux platforms */
2067 ret = get_errno(shmget(first, second, third));
2068 break;
2070 /* IPC_* and SHM_* command values are the same on all linux platforms */
2071 case IPCOP_shmctl:
2072 switch(second) {
2073 case IPC_RMID:
2074 case SHM_LOCK:
2075 case SHM_UNLOCK:
2076 ret = get_errno(shmctl(first, second, NULL));
2077 break;
2078 default:
2079 goto unimplemented;
2081 break;
2082 default:
2083 unimplemented:
2084 gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2085 ret = -TARGET_ENOSYS;
2086 break;
2088 return ret;
2090 #endif
2092 /* kernel structure types definitions */
2093 #define IFNAMSIZ 16
2095 #define STRUCT(name, list...) STRUCT_ ## name,
2096 #define STRUCT_SPECIAL(name) STRUCT_ ## name,
2097 enum {
2098 #include "syscall_types.h"
2100 #undef STRUCT
2101 #undef STRUCT_SPECIAL
2103 #define STRUCT(name, list...) const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };
2104 #define STRUCT_SPECIAL(name)
2105 #include "syscall_types.h"
2106 #undef STRUCT
2107 #undef STRUCT_SPECIAL
2109 typedef struct IOCTLEntry {
2110 unsigned int target_cmd;
2111 unsigned int host_cmd;
2112 const char *name;
2113 int access;
2114 const argtype arg_type[5];
2115 } IOCTLEntry;
2117 #define IOC_R 0x0001
2118 #define IOC_W 0x0002
2119 #define IOC_RW (IOC_R | IOC_W)
2121 #define MAX_STRUCT_SIZE 4096
2123 IOCTLEntry ioctl_entries[] = {
2124 #define IOCTL(cmd, access, types...) \
2125 { TARGET_ ## cmd, cmd, #cmd, access, { types } },
2126 #include "ioctls.h"
2127 { 0, 0, },
2130 /* ??? Implement proper locking for ioctls. */
2131 /* do_ioctl() Must return target values and target errnos. */
2132 static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
2134 const IOCTLEntry *ie;
2135 const argtype *arg_type;
2136 abi_long ret;
2137 uint8_t buf_temp[MAX_STRUCT_SIZE];
2138 int target_size;
2139 void *argptr;
2141 ie = ioctl_entries;
2142 for(;;) {
2143 if (ie->target_cmd == 0) {
2144 gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
2145 return -TARGET_ENOSYS;
2147 if (ie->target_cmd == cmd)
2148 break;
2149 ie++;
2151 arg_type = ie->arg_type;
2152 #if defined(DEBUG)
2153 gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
2154 #endif
2155 switch(arg_type[0]) {
2156 case TYPE_NULL:
2157 /* no argument */
2158 ret = get_errno(ioctl(fd, ie->host_cmd));
2159 break;
2160 case TYPE_PTRVOID:
2161 case TYPE_INT:
2162 /* int argment */
2163 ret = get_errno(ioctl(fd, ie->host_cmd, arg));
2164 break;
2165 case TYPE_PTR:
2166 arg_type++;
2167 target_size = thunk_type_size(arg_type, 0);
2168 switch(ie->access) {
2169 case IOC_R:
2170 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2171 if (!is_error(ret)) {
2172 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2173 if (!argptr)
2174 return -TARGET_EFAULT;
2175 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2176 unlock_user(argptr, arg, target_size);
2178 break;
2179 case IOC_W:
2180 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2181 if (!argptr)
2182 return -TARGET_EFAULT;
2183 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2184 unlock_user(argptr, arg, 0);
2185 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2186 break;
2187 default:
2188 case IOC_RW:
2189 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2190 if (!argptr)
2191 return -TARGET_EFAULT;
2192 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2193 unlock_user(argptr, arg, 0);
2194 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2195 if (!is_error(ret)) {
2196 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2197 if (!argptr)
2198 return -TARGET_EFAULT;
2199 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2200 unlock_user(argptr, arg, target_size);
2202 break;
2204 break;
2205 default:
2206 gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
2207 (long)cmd, arg_type[0]);
2208 ret = -TARGET_ENOSYS;
2209 break;
2211 return ret;
2214 bitmask_transtbl iflag_tbl[] = {
2215 { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
2216 { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
2217 { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
2218 { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
2219 { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
2220 { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
2221 { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
2222 { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
2223 { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
2224 { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
2225 { TARGET_IXON, TARGET_IXON, IXON, IXON },
2226 { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
2227 { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
2228 { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
2229 { 0, 0, 0, 0 }
2232 bitmask_transtbl oflag_tbl[] = {
2233 { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
2234 { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
2235 { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
2236 { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
2237 { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
2238 { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
2239 { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
2240 { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
2241 { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
2242 { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
2243 { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
2244 { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
2245 { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
2246 { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
2247 { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
2248 { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
2249 { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
2250 { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
2251 { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
2252 { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
2253 { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
2254 { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
2255 { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
2256 { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
2257 { 0, 0, 0, 0 }
2260 bitmask_transtbl cflag_tbl[] = {
2261 { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
2262 { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
2263 { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
2264 { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
2265 { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
2266 { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
2267 { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
2268 { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
2269 { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
2270 { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
2271 { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
2272 { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
2273 { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
2274 { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
2275 { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
2276 { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
2277 { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
2278 { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
2279 { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
2280 { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
2281 { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
2282 { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
2283 { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
2284 { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
2285 { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
2286 { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
2287 { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
2288 { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
2289 { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
2290 { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
2291 { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
2292 { 0, 0, 0, 0 }
2295 bitmask_transtbl lflag_tbl[] = {
2296 { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
2297 { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
2298 { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
2299 { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
2300 { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
2301 { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
2302 { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
2303 { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
2304 { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
2305 { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
2306 { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
2307 { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
2308 { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
2309 { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
2310 { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
2311 { 0, 0, 0, 0 }
2314 static void target_to_host_termios (void *dst, const void *src)
2316 struct host_termios *host = dst;
2317 const struct target_termios *target = src;
2319 host->c_iflag =
2320 target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
2321 host->c_oflag =
2322 target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
2323 host->c_cflag =
2324 target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
2325 host->c_lflag =
2326 target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
2327 host->c_line = target->c_line;
2329 host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
2330 host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
2331 host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
2332 host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
2333 host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
2334 host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
2335 host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
2336 host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
2337 host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
2338 host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
2339 host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
2340 host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
2341 host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
2342 host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
2343 host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
2344 host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
2345 host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
2348 static void host_to_target_termios (void *dst, const void *src)
2350 struct target_termios *target = dst;
2351 const struct host_termios *host = src;
2353 target->c_iflag =
2354 tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
2355 target->c_oflag =
2356 tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
2357 target->c_cflag =
2358 tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
2359 target->c_lflag =
2360 tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
2361 target->c_line = host->c_line;
2363 target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
2364 target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
2365 target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
2366 target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
2367 target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
2368 target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
2369 target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
2370 target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
2371 target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
2372 target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
2373 target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
2374 target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
2375 target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
2376 target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
2377 target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
2378 target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
2379 target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
2382 StructEntry struct_termios_def = {
2383 .convert = { host_to_target_termios, target_to_host_termios },
2384 .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
2385 .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
2388 static bitmask_transtbl mmap_flags_tbl[] = {
2389 { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
2390 { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
2391 { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
2392 { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
2393 { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
2394 { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
2395 { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
2396 { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
2397 { 0, 0, 0, 0 }
2400 static bitmask_transtbl fcntl_flags_tbl[] = {
2401 { TARGET_O_ACCMODE, TARGET_O_WRONLY, O_ACCMODE, O_WRONLY, },
2402 { TARGET_O_ACCMODE, TARGET_O_RDWR, O_ACCMODE, O_RDWR, },
2403 { TARGET_O_CREAT, TARGET_O_CREAT, O_CREAT, O_CREAT, },
2404 { TARGET_O_EXCL, TARGET_O_EXCL, O_EXCL, O_EXCL, },
2405 { TARGET_O_NOCTTY, TARGET_O_NOCTTY, O_NOCTTY, O_NOCTTY, },
2406 { TARGET_O_TRUNC, TARGET_O_TRUNC, O_TRUNC, O_TRUNC, },
2407 { TARGET_O_APPEND, TARGET_O_APPEND, O_APPEND, O_APPEND, },
2408 { TARGET_O_NONBLOCK, TARGET_O_NONBLOCK, O_NONBLOCK, O_NONBLOCK, },
2409 { TARGET_O_SYNC, TARGET_O_SYNC, O_SYNC, O_SYNC, },
2410 { TARGET_FASYNC, TARGET_FASYNC, FASYNC, FASYNC, },
2411 { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
2412 { TARGET_O_NOFOLLOW, TARGET_O_NOFOLLOW, O_NOFOLLOW, O_NOFOLLOW, },
2413 { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
2414 #if defined(O_DIRECT)
2415 { TARGET_O_DIRECT, TARGET_O_DIRECT, O_DIRECT, O_DIRECT, },
2416 #endif
2417 { 0, 0, 0, 0 }
2420 #if defined(TARGET_I386)
2422 /* NOTE: there is really one LDT for all the threads */
2423 uint8_t *ldt_table;
2425 static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
2427 int size;
2428 void *p;
2430 if (!ldt_table)
2431 return 0;
2432 size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
2433 if (size > bytecount)
2434 size = bytecount;
2435 p = lock_user(VERIFY_WRITE, ptr, size, 0);
2436 if (!p)
2437 return -TARGET_EFAULT;
2438 /* ??? Should this by byteswapped? */
2439 memcpy(p, ldt_table, size);
2440 unlock_user(p, ptr, size);
2441 return size;
2444 /* XXX: add locking support */
2445 static abi_long write_ldt(CPUX86State *env,
2446 abi_ulong ptr, unsigned long bytecount, int oldmode)
2448 struct target_modify_ldt_ldt_s ldt_info;
2449 struct target_modify_ldt_ldt_s *target_ldt_info;
2450 int seg_32bit, contents, read_exec_only, limit_in_pages;
2451 int seg_not_present, useable, lm;
2452 uint32_t *lp, entry_1, entry_2;
2454 if (bytecount != sizeof(ldt_info))
2455 return -TARGET_EINVAL;
2456 if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
2457 return -TARGET_EFAULT;
2458 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2459 ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2460 ldt_info.limit = tswap32(target_ldt_info->limit);
2461 ldt_info.flags = tswap32(target_ldt_info->flags);
2462 unlock_user_struct(target_ldt_info, ptr, 0);
2464 if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
2465 return -TARGET_EINVAL;
2466 seg_32bit = ldt_info.flags & 1;
2467 contents = (ldt_info.flags >> 1) & 3;
2468 read_exec_only = (ldt_info.flags >> 3) & 1;
2469 limit_in_pages = (ldt_info.flags >> 4) & 1;
2470 seg_not_present = (ldt_info.flags >> 5) & 1;
2471 useable = (ldt_info.flags >> 6) & 1;
2472 #ifdef TARGET_ABI32
2473 lm = 0;
2474 #else
2475 lm = (ldt_info.flags >> 7) & 1;
2476 #endif
2477 if (contents == 3) {
2478 if (oldmode)
2479 return -TARGET_EINVAL;
2480 if (seg_not_present == 0)
2481 return -TARGET_EINVAL;
2483 /* allocate the LDT */
2484 if (!ldt_table) {
2485 ldt_table = malloc(TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
2486 if (!ldt_table)
2487 return -TARGET_ENOMEM;
2488 memset(ldt_table, 0, TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
2489 env->ldt.base = h2g((unsigned long)ldt_table);
2490 env->ldt.limit = 0xffff;
2493 /* NOTE: same code as Linux kernel */
2494 /* Allow LDTs to be cleared by the user. */
2495 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2496 if (oldmode ||
2497 (contents == 0 &&
2498 read_exec_only == 1 &&
2499 seg_32bit == 0 &&
2500 limit_in_pages == 0 &&
2501 seg_not_present == 1 &&
2502 useable == 0 )) {
2503 entry_1 = 0;
2504 entry_2 = 0;
2505 goto install;
2509 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2510 (ldt_info.limit & 0x0ffff);
2511 entry_2 = (ldt_info.base_addr & 0xff000000) |
2512 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2513 (ldt_info.limit & 0xf0000) |
2514 ((read_exec_only ^ 1) << 9) |
2515 (contents << 10) |
2516 ((seg_not_present ^ 1) << 15) |
2517 (seg_32bit << 22) |
2518 (limit_in_pages << 23) |
2519 (lm << 21) |
2520 0x7000;
2521 if (!oldmode)
2522 entry_2 |= (useable << 20);
2524 /* Install the new entry ... */
2525 install:
2526 lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
2527 lp[0] = tswap32(entry_1);
2528 lp[1] = tswap32(entry_2);
2529 return 0;
2532 /* specific and weird i386 syscalls */
2533 static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
2534 unsigned long bytecount)
2536 abi_long ret;
2538 switch (func) {
2539 case 0:
2540 ret = read_ldt(ptr, bytecount);
2541 break;
2542 case 1:
2543 ret = write_ldt(env, ptr, bytecount, 1);
2544 break;
2545 case 0x11:
2546 ret = write_ldt(env, ptr, bytecount, 0);
2547 break;
2548 default:
2549 ret = -TARGET_ENOSYS;
2550 break;
2552 return ret;
2555 #if defined(TARGET_I386) && defined(TARGET_ABI32)
2556 static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
2558 uint64_t *gdt_table = g2h(env->gdt.base);
2559 struct target_modify_ldt_ldt_s ldt_info;
2560 struct target_modify_ldt_ldt_s *target_ldt_info;
2561 int seg_32bit, contents, read_exec_only, limit_in_pages;
2562 int seg_not_present, useable, lm;
2563 uint32_t *lp, entry_1, entry_2;
2564 int i;
2566 lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
2567 if (!target_ldt_info)
2568 return -TARGET_EFAULT;
2569 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2570 ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2571 ldt_info.limit = tswap32(target_ldt_info->limit);
2572 ldt_info.flags = tswap32(target_ldt_info->flags);
2573 if (ldt_info.entry_number == -1) {
2574 for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
2575 if (gdt_table[i] == 0) {
2576 ldt_info.entry_number = i;
2577 target_ldt_info->entry_number = tswap32(i);
2578 break;
2582 unlock_user_struct(target_ldt_info, ptr, 1);
2584 if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN ||
2585 ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
2586 return -TARGET_EINVAL;
2587 seg_32bit = ldt_info.flags & 1;
2588 contents = (ldt_info.flags >> 1) & 3;
2589 read_exec_only = (ldt_info.flags >> 3) & 1;
2590 limit_in_pages = (ldt_info.flags >> 4) & 1;
2591 seg_not_present = (ldt_info.flags >> 5) & 1;
2592 useable = (ldt_info.flags >> 6) & 1;
2593 #ifdef TARGET_ABI32
2594 lm = 0;
2595 #else
2596 lm = (ldt_info.flags >> 7) & 1;
2597 #endif
2599 if (contents == 3) {
2600 if (seg_not_present == 0)
2601 return -TARGET_EINVAL;
2604 /* NOTE: same code as Linux kernel */
2605 /* Allow LDTs to be cleared by the user. */
2606 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2607 if ((contents == 0 &&
2608 read_exec_only == 1 &&
2609 seg_32bit == 0 &&
2610 limit_in_pages == 0 &&
2611 seg_not_present == 1 &&
2612 useable == 0 )) {
2613 entry_1 = 0;
2614 entry_2 = 0;
2615 goto install;
2619 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2620 (ldt_info.limit & 0x0ffff);
2621 entry_2 = (ldt_info.base_addr & 0xff000000) |
2622 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2623 (ldt_info.limit & 0xf0000) |
2624 ((read_exec_only ^ 1) << 9) |
2625 (contents << 10) |
2626 ((seg_not_present ^ 1) << 15) |
2627 (seg_32bit << 22) |
2628 (limit_in_pages << 23) |
2629 (useable << 20) |
2630 (lm << 21) |
2631 0x7000;
2633 /* Install the new entry ... */
2634 install:
2635 lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
2636 lp[0] = tswap32(entry_1);
2637 lp[1] = tswap32(entry_2);
2638 return 0;
2641 static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
2643 struct target_modify_ldt_ldt_s *target_ldt_info;
2644 uint64_t *gdt_table = g2h(env->gdt.base);
2645 uint32_t base_addr, limit, flags;
2646 int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
2647 int seg_not_present, useable, lm;
2648 uint32_t *lp, entry_1, entry_2;
2650 lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
2651 if (!target_ldt_info)
2652 return -TARGET_EFAULT;
2653 idx = tswap32(target_ldt_info->entry_number);
2654 if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
2655 idx > TARGET_GDT_ENTRY_TLS_MAX) {
2656 unlock_user_struct(target_ldt_info, ptr, 1);
2657 return -TARGET_EINVAL;
2659 lp = (uint32_t *)(gdt_table + idx);
2660 entry_1 = tswap32(lp[0]);
2661 entry_2 = tswap32(lp[1]);
2663 read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
2664 contents = (entry_2 >> 10) & 3;
2665 seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
2666 seg_32bit = (entry_2 >> 22) & 1;
2667 limit_in_pages = (entry_2 >> 23) & 1;
2668 useable = (entry_2 >> 20) & 1;
2669 #ifdef TARGET_ABI32
2670 lm = 0;
2671 #else
2672 lm = (entry_2 >> 21) & 1;
2673 #endif
2674 flags = (seg_32bit << 0) | (contents << 1) |
2675 (read_exec_only << 3) | (limit_in_pages << 4) |
2676 (seg_not_present << 5) | (useable << 6) | (lm << 7);
2677 limit = (entry_1 & 0xffff) | (entry_2 & 0xf0000);
2678 base_addr = (entry_1 >> 16) |
2679 (entry_2 & 0xff000000) |
2680 ((entry_2 & 0xff) << 16);
2681 target_ldt_info->base_addr = tswapl(base_addr);
2682 target_ldt_info->limit = tswap32(limit);
2683 target_ldt_info->flags = tswap32(flags);
2684 unlock_user_struct(target_ldt_info, ptr, 1);
2685 return 0;
2687 #endif /* TARGET_I386 && TARGET_ABI32 */
2689 #ifndef TARGET_ABI32
2690 static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
2692 abi_long ret;
2693 abi_ulong val;
2694 int idx;
2696 switch(code) {
2697 case TARGET_ARCH_SET_GS:
2698 case TARGET_ARCH_SET_FS:
2699 if (code == TARGET_ARCH_SET_GS)
2700 idx = R_GS;
2701 else
2702 idx = R_FS;
2703 cpu_x86_load_seg(env, idx, 0);
2704 env->segs[idx].base = addr;
2705 break;
2706 case TARGET_ARCH_GET_GS:
2707 case TARGET_ARCH_GET_FS:
2708 if (code == TARGET_ARCH_GET_GS)
2709 idx = R_GS;
2710 else
2711 idx = R_FS;
2712 val = env->segs[idx].base;
2713 if (put_user(val, addr, abi_ulong))
2714 return -TARGET_EFAULT;
2715 break;
2716 default:
2717 ret = -TARGET_EINVAL;
2718 break;
2720 return 0;
2722 #endif
2724 #endif /* defined(TARGET_I386) */
2726 #if defined(USE_NPTL)
2728 #define NEW_STACK_SIZE PTHREAD_STACK_MIN
2730 static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
2731 typedef struct {
2732 CPUState *env;
2733 pthread_mutex_t mutex;
2734 pthread_cond_t cond;
2735 pthread_t thread;
2736 uint32_t tid;
2737 abi_ulong child_tidptr;
2738 abi_ulong parent_tidptr;
2739 sigset_t sigmask;
2740 } new_thread_info;
2742 static void *clone_func(void *arg)
2744 new_thread_info *info = arg;
2745 CPUState *env;
2747 env = info->env;
2748 thread_env = env;
2749 info->tid = gettid();
2750 if (info->child_tidptr)
2751 put_user_u32(info->tid, info->child_tidptr);
2752 if (info->parent_tidptr)
2753 put_user_u32(info->tid, info->parent_tidptr);
2754 /* Enable signals. */
2755 sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
2756 /* Signal to the parent that we're ready. */
2757 pthread_mutex_lock(&info->mutex);
2758 pthread_cond_broadcast(&info->cond);
2759 pthread_mutex_unlock(&info->mutex);
2760 /* Wait until the parent has finshed initializing the tls state. */
2761 pthread_mutex_lock(&clone_lock);
2762 pthread_mutex_unlock(&clone_lock);
2763 cpu_loop(env);
2764 /* never exits */
2765 return NULL;
2767 #else
2768 /* this stack is the equivalent of the kernel stack associated with a
2769 thread/process */
2770 #define NEW_STACK_SIZE 8192
2772 static int clone_func(void *arg)
2774 CPUState *env = arg;
2775 cpu_loop(env);
2776 /* never exits */
2777 return 0;
2779 #endif
2781 /* do_fork() Must return host values and target errnos (unlike most
2782 do_*() functions). */
2783 static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
2784 abi_ulong parent_tidptr, target_ulong newtls,
2785 abi_ulong child_tidptr)
2787 int ret;
2788 TaskState *ts;
2789 uint8_t *new_stack;
2790 CPUState *new_env;
2791 #if defined(USE_NPTL)
2792 unsigned int nptl_flags;
2793 sigset_t sigmask;
2794 #endif
2796 if (flags & CLONE_VM) {
2797 #if defined(USE_NPTL)
2798 new_thread_info info;
2799 pthread_attr_t attr;
2800 #endif
2801 ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
2802 init_task_state(ts);
2803 new_stack = ts->stack;
2804 /* we create a new CPU instance. */
2805 new_env = cpu_copy(env);
2806 /* Init regs that differ from the parent. */
2807 cpu_clone_regs(new_env, newsp);
2808 new_env->opaque = ts;
2809 #if defined(USE_NPTL)
2810 nptl_flags = flags;
2811 flags &= ~CLONE_NPTL_FLAGS2;
2813 /* TODO: Implement CLONE_CHILD_CLEARTID. */
2814 if (nptl_flags & CLONE_SETTLS)
2815 cpu_set_tls (new_env, newtls);
2817 /* Grab a mutex so that thread setup appears atomic. */
2818 pthread_mutex_lock(&clone_lock);
2820 memset(&info, 0, sizeof(info));
2821 pthread_mutex_init(&info.mutex, NULL);
2822 pthread_mutex_lock(&info.mutex);
2823 pthread_cond_init(&info.cond, NULL);
2824 info.env = new_env;
2825 if (nptl_flags & CLONE_CHILD_SETTID)
2826 info.child_tidptr = child_tidptr;
2827 if (nptl_flags & CLONE_PARENT_SETTID)
2828 info.parent_tidptr = parent_tidptr;
2830 ret = pthread_attr_init(&attr);
2831 ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE);
2832 /* It is not safe to deliver signals until the child has finished
2833 initializing, so temporarily block all signals. */
2834 sigfillset(&sigmask);
2835 sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
2837 ret = pthread_create(&info.thread, &attr, clone_func, &info);
2839 sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
2840 pthread_attr_destroy(&attr);
2841 if (ret == 0) {
2842 /* Wait for the child to initialize. */
2843 pthread_cond_wait(&info.cond, &info.mutex);
2844 ret = info.tid;
2845 if (flags & CLONE_PARENT_SETTID)
2846 put_user_u32(ret, parent_tidptr);
2847 } else {
2848 ret = -1;
2850 pthread_mutex_unlock(&info.mutex);
2851 pthread_cond_destroy(&info.cond);
2852 pthread_mutex_destroy(&info.mutex);
2853 pthread_mutex_unlock(&clone_lock);
2854 #else
2855 if (flags & CLONE_NPTL_FLAGS2)
2856 return -EINVAL;
2857 /* This is probably going to die very quickly, but do it anyway. */
2858 #ifdef __ia64__
2859 ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
2860 #else
2861 ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
2862 #endif
2863 #endif
2864 } else {
2865 /* if no CLONE_VM, we consider it is a fork */
2866 if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
2867 return -EINVAL;
2868 fork_start();
2869 ret = fork();
2870 #if defined(USE_NPTL)
2871 /* There is a race condition here. The parent process could
2872 theoretically read the TID in the child process before the child
2873 tid is set. This would require using either ptrace
2874 (not implemented) or having *_tidptr to point at a shared memory
2875 mapping. We can't repeat the spinlock hack used above because
2876 the child process gets its own copy of the lock. */
2877 if (ret == 0) {
2878 cpu_clone_regs(env, newsp);
2879 fork_end(1);
2880 /* Child Process. */
2881 if (flags & CLONE_CHILD_SETTID)
2882 put_user_u32(gettid(), child_tidptr);
2883 if (flags & CLONE_PARENT_SETTID)
2884 put_user_u32(gettid(), parent_tidptr);
2885 ts = (TaskState *)env->opaque;
2886 if (flags & CLONE_SETTLS)
2887 cpu_set_tls (env, newtls);
2888 /* TODO: Implement CLONE_CHILD_CLEARTID. */
2889 } else {
2890 fork_end(0);
2892 #else
2893 if (ret == 0) {
2894 cpu_clone_regs(env, newsp);
2896 #endif
2898 return ret;
2901 static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
2903 struct flock fl;
2904 struct target_flock *target_fl;
2905 struct flock64 fl64;
2906 struct target_flock64 *target_fl64;
2907 abi_long ret;
2909 switch(cmd) {
2910 case TARGET_F_GETLK:
2911 if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
2912 return -TARGET_EFAULT;
2913 fl.l_type = tswap16(target_fl->l_type);
2914 fl.l_whence = tswap16(target_fl->l_whence);
2915 fl.l_start = tswapl(target_fl->l_start);
2916 fl.l_len = tswapl(target_fl->l_len);
2917 fl.l_pid = tswapl(target_fl->l_pid);
2918 unlock_user_struct(target_fl, arg, 0);
2919 ret = get_errno(fcntl(fd, cmd, &fl));
2920 if (ret == 0) {
2921 if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
2922 return -TARGET_EFAULT;
2923 target_fl->l_type = tswap16(fl.l_type);
2924 target_fl->l_whence = tswap16(fl.l_whence);
2925 target_fl->l_start = tswapl(fl.l_start);
2926 target_fl->l_len = tswapl(fl.l_len);
2927 target_fl->l_pid = tswapl(fl.l_pid);
2928 unlock_user_struct(target_fl, arg, 1);
2930 break;
2932 case TARGET_F_SETLK:
2933 case TARGET_F_SETLKW:
2934 if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
2935 return -TARGET_EFAULT;
2936 fl.l_type = tswap16(target_fl->l_type);
2937 fl.l_whence = tswap16(target_fl->l_whence);
2938 fl.l_start = tswapl(target_fl->l_start);
2939 fl.l_len = tswapl(target_fl->l_len);
2940 fl.l_pid = tswapl(target_fl->l_pid);
2941 unlock_user_struct(target_fl, arg, 0);
2942 ret = get_errno(fcntl(fd, cmd, &fl));
2943 break;
2945 case TARGET_F_GETLK64:
2946 if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
2947 return -TARGET_EFAULT;
2948 fl64.l_type = tswap16(target_fl64->l_type) >> 1;
2949 fl64.l_whence = tswap16(target_fl64->l_whence);
2950 fl64.l_start = tswapl(target_fl64->l_start);
2951 fl64.l_len = tswapl(target_fl64->l_len);
2952 fl64.l_pid = tswap16(target_fl64->l_pid);
2953 unlock_user_struct(target_fl64, arg, 0);
2954 ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
2955 if (ret == 0) {
2956 if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
2957 return -TARGET_EFAULT;
2958 target_fl64->l_type = tswap16(fl64.l_type) >> 1;
2959 target_fl64->l_whence = tswap16(fl64.l_whence);
2960 target_fl64->l_start = tswapl(fl64.l_start);
2961 target_fl64->l_len = tswapl(fl64.l_len);
2962 target_fl64->l_pid = tswapl(fl64.l_pid);
2963 unlock_user_struct(target_fl64, arg, 1);
2965 break;
2966 case TARGET_F_SETLK64:
2967 case TARGET_F_SETLKW64:
2968 if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
2969 return -TARGET_EFAULT;
2970 fl64.l_type = tswap16(target_fl64->l_type) >> 1;
2971 fl64.l_whence = tswap16(target_fl64->l_whence);
2972 fl64.l_start = tswapl(target_fl64->l_start);
2973 fl64.l_len = tswapl(target_fl64->l_len);
2974 fl64.l_pid = tswap16(target_fl64->l_pid);
2975 unlock_user_struct(target_fl64, arg, 0);
2976 ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
2977 break;
2979 case F_GETFL:
2980 ret = get_errno(fcntl(fd, cmd, arg));
2981 if (ret >= 0) {
2982 ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
2984 break;
2986 case F_SETFL:
2987 ret = get_errno(fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
2988 break;
2990 default:
2991 ret = get_errno(fcntl(fd, cmd, arg));
2992 break;
2994 return ret;
2997 #ifdef USE_UID16
2999 static inline int high2lowuid(int uid)
3001 if (uid > 65535)
3002 return 65534;
3003 else
3004 return uid;
3007 static inline int high2lowgid(int gid)
3009 if (gid > 65535)
3010 return 65534;
3011 else
3012 return gid;
3015 static inline int low2highuid(int uid)
3017 if ((int16_t)uid == -1)
3018 return -1;
3019 else
3020 return uid;
3023 static inline int low2highgid(int gid)
3025 if ((int16_t)gid == -1)
3026 return -1;
3027 else
3028 return gid;
3031 #endif /* USE_UID16 */
3033 void syscall_init(void)
3035 IOCTLEntry *ie;
3036 const argtype *arg_type;
3037 int size;
3038 int i;
3040 #define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3041 #define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3042 #include "syscall_types.h"
3043 #undef STRUCT
3044 #undef STRUCT_SPECIAL
3046 /* we patch the ioctl size if necessary. We rely on the fact that
3047 no ioctl has all the bits at '1' in the size field */
3048 ie = ioctl_entries;
3049 while (ie->target_cmd != 0) {
3050 if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
3051 TARGET_IOC_SIZEMASK) {
3052 arg_type = ie->arg_type;
3053 if (arg_type[0] != TYPE_PTR) {
3054 fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
3055 ie->target_cmd);
3056 exit(1);
3058 arg_type++;
3059 size = thunk_type_size(arg_type, 0);
3060 ie->target_cmd = (ie->target_cmd &
3061 ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
3062 (size << TARGET_IOC_SIZESHIFT);
3065 /* Build target_to_host_errno_table[] table from
3066 * host_to_target_errno_table[]. */
3067 for (i=0; i < ERRNO_TABLE_SIZE; i++)
3068 target_to_host_errno_table[host_to_target_errno_table[i]] = i;
3070 /* automatic consistency check if same arch */
3071 #if defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)
3072 if (ie->target_cmd != ie->host_cmd) {
3073 fprintf(stderr, "ERROR: ioctl: target=0x%x host=0x%x\n",
3074 ie->target_cmd, ie->host_cmd);
3076 #endif
3077 ie++;
3081 #if TARGET_ABI_BITS == 32
3082 static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
3084 #ifdef TARGET_WORDS_BIGENDIAN
3085 return ((uint64_t)word0 << 32) | word1;
3086 #else
3087 return ((uint64_t)word1 << 32) | word0;
3088 #endif
3090 #else /* TARGET_ABI_BITS == 32 */
3091 static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
3093 return word0;
3095 #endif /* TARGET_ABI_BITS != 32 */
3097 #ifdef TARGET_NR_truncate64
3098 static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
3099 abi_long arg2,
3100 abi_long arg3,
3101 abi_long arg4)
3103 #ifdef TARGET_ARM
3104 if (((CPUARMState *)cpu_env)->eabi)
3106 arg2 = arg3;
3107 arg3 = arg4;
3109 #endif
3110 return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
3112 #endif
3114 #ifdef TARGET_NR_ftruncate64
3115 static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
3116 abi_long arg2,
3117 abi_long arg3,
3118 abi_long arg4)
3120 #ifdef TARGET_ARM
3121 if (((CPUARMState *)cpu_env)->eabi)
3123 arg2 = arg3;
3124 arg3 = arg4;
3126 #endif
3127 return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
3129 #endif
3131 static inline abi_long target_to_host_timespec(struct timespec *host_ts,
3132 abi_ulong target_addr)
3134 struct target_timespec *target_ts;
3136 if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
3137 return -TARGET_EFAULT;
3138 host_ts->tv_sec = tswapl(target_ts->tv_sec);
3139 host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
3140 unlock_user_struct(target_ts, target_addr, 0);
3141 return 0;
3144 static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3145 struct timespec *host_ts)
3147 struct target_timespec *target_ts;
3149 if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
3150 return -TARGET_EFAULT;
3151 target_ts->tv_sec = tswapl(host_ts->tv_sec);
3152 target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
3153 unlock_user_struct(target_ts, target_addr, 1);
3154 return 0;
3157 #ifdef TARGET_NR_stat64
3158 static inline abi_long host_to_target_stat64(void *cpu_env,
3159 abi_ulong target_addr,
3160 struct stat *host_st)
3162 #ifdef TARGET_ARM
3163 if (((CPUARMState *)cpu_env)->eabi) {
3164 struct target_eabi_stat64 *target_st;
3166 if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3167 return -TARGET_EFAULT;
3168 memset(target_st, 0, sizeof(struct target_eabi_stat64));
3169 __put_user(host_st->st_dev, &target_st->st_dev);
3170 __put_user(host_st->st_ino, &target_st->st_ino);
3171 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3172 __put_user(host_st->st_ino, &target_st->__st_ino);
3173 #endif
3174 __put_user(host_st->st_mode, &target_st->st_mode);
3175 __put_user(host_st->st_nlink, &target_st->st_nlink);
3176 __put_user(host_st->st_uid, &target_st->st_uid);
3177 __put_user(host_st->st_gid, &target_st->st_gid);
3178 __put_user(host_st->st_rdev, &target_st->st_rdev);
3179 __put_user(host_st->st_size, &target_st->st_size);
3180 __put_user(host_st->st_blksize, &target_st->st_blksize);
3181 __put_user(host_st->st_blocks, &target_st->st_blocks);
3182 __put_user(host_st->st_atime, &target_st->target_st_atime);
3183 __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3184 __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3185 unlock_user_struct(target_st, target_addr, 1);
3186 } else
3187 #endif
3189 struct target_stat64 *target_st;
3191 if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3192 return -TARGET_EFAULT;
3193 memset(target_st, 0, sizeof(struct target_stat64));
3194 __put_user(host_st->st_dev, &target_st->st_dev);
3195 __put_user(host_st->st_ino, &target_st->st_ino);
3196 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3197 __put_user(host_st->st_ino, &target_st->__st_ino);
3198 #endif
3199 __put_user(host_st->st_mode, &target_st->st_mode);
3200 __put_user(host_st->st_nlink, &target_st->st_nlink);
3201 __put_user(host_st->st_uid, &target_st->st_uid);
3202 __put_user(host_st->st_gid, &target_st->st_gid);
3203 __put_user(host_st->st_rdev, &target_st->st_rdev);
3204 /* XXX: better use of kernel struct */
3205 __put_user(host_st->st_size, &target_st->st_size);
3206 __put_user(host_st->st_blksize, &target_st->st_blksize);
3207 __put_user(host_st->st_blocks, &target_st->st_blocks);
3208 __put_user(host_st->st_atime, &target_st->target_st_atime);
3209 __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3210 __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3211 unlock_user_struct(target_st, target_addr, 1);
3214 return 0;
3216 #endif
3218 #if defined(USE_NPTL)
3219 /* ??? Using host futex calls even when target atomic operations
3220 are not really atomic probably breaks things. However implementing
3221 futexes locally would make futexes shared between multiple processes
3222 tricky. However they're probably useless because guest atomic
3223 operations won't work either. */
3224 static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
3225 target_ulong uaddr2, int val3)
3227 struct timespec ts, *pts;
3229 /* ??? We assume FUTEX_* constants are the same on both host
3230 and target. */
3231 switch (op) {
3232 case FUTEX_WAIT:
3233 if (timeout) {
3234 pts = &ts;
3235 target_to_host_timespec(pts, timeout);
3236 } else {
3237 pts = NULL;
3239 return get_errno(sys_futex(g2h(uaddr), FUTEX_WAIT, tswap32(val),
3240 pts, NULL, 0));
3241 case FUTEX_WAKE:
3242 return get_errno(sys_futex(g2h(uaddr), FUTEX_WAKE, val, NULL, NULL, 0));
3243 case FUTEX_FD:
3244 return get_errno(sys_futex(g2h(uaddr), FUTEX_FD, val, NULL, NULL, 0));
3245 case FUTEX_REQUEUE:
3246 return get_errno(sys_futex(g2h(uaddr), FUTEX_REQUEUE, val,
3247 NULL, g2h(uaddr2), 0));
3248 case FUTEX_CMP_REQUEUE:
3249 return get_errno(sys_futex(g2h(uaddr), FUTEX_CMP_REQUEUE, val,
3250 NULL, g2h(uaddr2), tswap32(val3)));
3251 default:
3252 return -TARGET_ENOSYS;
3255 #endif
3257 int get_osversion(void)
3259 static int osversion;
3260 struct new_utsname buf;
3261 const char *s;
3262 int i, n, tmp;
3263 if (osversion)
3264 return osversion;
3265 if (qemu_uname_release && *qemu_uname_release) {
3266 s = qemu_uname_release;
3267 } else {
3268 if (sys_uname(&buf))
3269 return 0;
3270 s = buf.release;
3272 tmp = 0;
3273 for (i = 0; i < 3; i++) {
3274 n = 0;
3275 while (*s >= '0' && *s <= '9') {
3276 n *= 10;
3277 n += *s - '0';
3278 s++;
3280 tmp = (tmp << 8) + n;
3281 if (*s == '.')
3282 s++;
3284 osversion = tmp;
3285 return osversion;
3288 /* do_syscall() should always have a single exit point at the end so
3289 that actions, such as logging of syscall results, can be performed.
3290 All errnos that do_syscall() returns must be -TARGET_<errcode>. */
3291 abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3292 abi_long arg2, abi_long arg3, abi_long arg4,
3293 abi_long arg5, abi_long arg6)
3295 abi_long ret;
3296 struct stat st;
3297 struct statfs stfs;
3298 void *p;
3300 #ifdef DEBUG
3301 gemu_log("syscall %d", num);
3302 #endif
3303 if(do_strace)
3304 print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
3306 switch(num) {
3307 case TARGET_NR_exit:
3308 #ifdef HAVE_GPROF
3309 _mcleanup();
3310 #endif
3311 gdb_exit(cpu_env, arg1);
3312 /* XXX: should free thread stack and CPU env */
3313 _exit(arg1);
3314 ret = 0; /* avoid warning */
3315 break;
3316 case TARGET_NR_read:
3317 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
3318 goto efault;
3319 ret = get_errno(read(arg1, p, arg3));
3320 unlock_user(p, arg2, ret);
3321 break;
3322 case TARGET_NR_write:
3323 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
3324 goto efault;
3325 ret = get_errno(write(arg1, p, arg3));
3326 unlock_user(p, arg2, 0);
3327 break;
3328 case TARGET_NR_open:
3329 if (!(p = lock_user_string(arg1)))
3330 goto efault;
3331 ret = get_errno(open(path(p),
3332 target_to_host_bitmask(arg2, fcntl_flags_tbl),
3333 arg3));
3334 unlock_user(p, arg1, 0);
3335 break;
3336 #if defined(TARGET_NR_openat) && defined(__NR_openat)
3337 case TARGET_NR_openat:
3338 if (!(p = lock_user_string(arg2)))
3339 goto efault;
3340 ret = get_errno(sys_openat(arg1,
3341 path(p),
3342 target_to_host_bitmask(arg3, fcntl_flags_tbl),
3343 arg4));
3344 unlock_user(p, arg2, 0);
3345 break;
3346 #endif
3347 case TARGET_NR_close:
3348 ret = get_errno(close(arg1));
3349 break;
3350 case TARGET_NR_brk:
3351 ret = do_brk(arg1);
3352 break;
3353 case TARGET_NR_fork:
3354 ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
3355 break;
3356 #ifdef TARGET_NR_waitpid
3357 case TARGET_NR_waitpid:
3359 int status;
3360 ret = get_errno(waitpid(arg1, &status, arg3));
3361 if (!is_error(ret) && arg2
3362 && put_user_s32(status, arg2))
3363 goto efault;
3365 break;
3366 #endif
3367 #ifdef TARGET_NR_waitid
3368 case TARGET_NR_waitid:
3370 siginfo_t info;
3371 info.si_pid = 0;
3372 ret = get_errno(waitid(arg1, arg2, &info, arg4));
3373 if (!is_error(ret) && arg3 && info.si_pid != 0) {
3374 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
3375 goto efault;
3376 host_to_target_siginfo(p, &info);
3377 unlock_user(p, arg3, sizeof(target_siginfo_t));
3380 break;
3381 #endif
3382 #ifdef TARGET_NR_creat /* not on alpha */
3383 case TARGET_NR_creat:
3384 if (!(p = lock_user_string(arg1)))
3385 goto efault;
3386 ret = get_errno(creat(p, arg2));
3387 unlock_user(p, arg1, 0);
3388 break;
3389 #endif
3390 case TARGET_NR_link:
3392 void * p2;
3393 p = lock_user_string(arg1);
3394 p2 = lock_user_string(arg2);
3395 if (!p || !p2)
3396 ret = -TARGET_EFAULT;
3397 else
3398 ret = get_errno(link(p, p2));
3399 unlock_user(p2, arg2, 0);
3400 unlock_user(p, arg1, 0);
3402 break;
3403 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
3404 case TARGET_NR_linkat:
3406 void * p2 = NULL;
3407 if (!arg2 || !arg4)
3408 goto efault;
3409 p = lock_user_string(arg2);
3410 p2 = lock_user_string(arg4);
3411 if (!p || !p2)
3412 ret = -TARGET_EFAULT;
3413 else
3414 ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
3415 unlock_user(p, arg2, 0);
3416 unlock_user(p2, arg4, 0);
3418 break;
3419 #endif
3420 case TARGET_NR_unlink:
3421 if (!(p = lock_user_string(arg1)))
3422 goto efault;
3423 ret = get_errno(unlink(p));
3424 unlock_user(p, arg1, 0);
3425 break;
3426 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
3427 case TARGET_NR_unlinkat:
3428 if (!(p = lock_user_string(arg2)))
3429 goto efault;
3430 ret = get_errno(sys_unlinkat(arg1, p, arg3));
3431 unlock_user(p, arg2, 0);
3432 break;
3433 #endif
3434 case TARGET_NR_execve:
3436 char **argp, **envp;
3437 int argc, envc;
3438 abi_ulong gp;
3439 abi_ulong guest_argp;
3440 abi_ulong guest_envp;
3441 abi_ulong addr;
3442 char **q;
3444 argc = 0;
3445 guest_argp = arg2;
3446 for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
3447 if (get_user_ual(addr, gp))
3448 goto efault;
3449 if (!addr)
3450 break;
3451 argc++;
3453 envc = 0;
3454 guest_envp = arg3;
3455 for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
3456 if (get_user_ual(addr, gp))
3457 goto efault;
3458 if (!addr)
3459 break;
3460 envc++;
3463 argp = alloca((argc + 1) * sizeof(void *));
3464 envp = alloca((envc + 1) * sizeof(void *));
3466 for (gp = guest_argp, q = argp; gp;
3467 gp += sizeof(abi_ulong), q++) {
3468 if (get_user_ual(addr, gp))
3469 goto execve_efault;
3470 if (!addr)
3471 break;
3472 if (!(*q = lock_user_string(addr)))
3473 goto execve_efault;
3475 *q = NULL;
3477 for (gp = guest_envp, q = envp; gp;
3478 gp += sizeof(abi_ulong), q++) {
3479 if (get_user_ual(addr, gp))
3480 goto execve_efault;
3481 if (!addr)
3482 break;
3483 if (!(*q = lock_user_string(addr)))
3484 goto execve_efault;
3486 *q = NULL;
3488 if (!(p = lock_user_string(arg1)))
3489 goto execve_efault;
3490 ret = get_errno(execve(p, argp, envp));
3491 unlock_user(p, arg1, 0);
3493 goto execve_end;
3495 execve_efault:
3496 ret = -TARGET_EFAULT;
3498 execve_end:
3499 for (gp = guest_argp, q = argp; *q;
3500 gp += sizeof(abi_ulong), q++) {
3501 if (get_user_ual(addr, gp)
3502 || !addr)
3503 break;
3504 unlock_user(*q, addr, 0);
3506 for (gp = guest_envp, q = envp; *q;
3507 gp += sizeof(abi_ulong), q++) {
3508 if (get_user_ual(addr, gp)
3509 || !addr)
3510 break;
3511 unlock_user(*q, addr, 0);
3514 break;
3515 case TARGET_NR_chdir:
3516 if (!(p = lock_user_string(arg1)))
3517 goto efault;
3518 ret = get_errno(chdir(p));
3519 unlock_user(p, arg1, 0);
3520 break;
3521 #ifdef TARGET_NR_time
3522 case TARGET_NR_time:
3524 time_t host_time;
3525 ret = get_errno(time(&host_time));
3526 if (!is_error(ret)
3527 && arg1
3528 && put_user_sal(host_time, arg1))
3529 goto efault;
3531 break;
3532 #endif
3533 case TARGET_NR_mknod:
3534 if (!(p = lock_user_string(arg1)))
3535 goto efault;
3536 ret = get_errno(mknod(p, arg2, arg3));
3537 unlock_user(p, arg1, 0);
3538 break;
3539 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
3540 case TARGET_NR_mknodat:
3541 if (!(p = lock_user_string(arg2)))
3542 goto efault;
3543 ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
3544 unlock_user(p, arg2, 0);
3545 break;
3546 #endif
3547 case TARGET_NR_chmod:
3548 if (!(p = lock_user_string(arg1)))
3549 goto efault;
3550 ret = get_errno(chmod(p, arg2));
3551 unlock_user(p, arg1, 0);
3552 break;
3553 #ifdef TARGET_NR_break
3554 case TARGET_NR_break:
3555 goto unimplemented;
3556 #endif
3557 #ifdef TARGET_NR_oldstat
3558 case TARGET_NR_oldstat:
3559 goto unimplemented;
3560 #endif
3561 case TARGET_NR_lseek:
3562 ret = get_errno(lseek(arg1, arg2, arg3));
3563 break;
3564 #ifdef TARGET_NR_getxpid
3565 case TARGET_NR_getxpid:
3566 #else
3567 case TARGET_NR_getpid:
3568 #endif
3569 ret = get_errno(getpid());
3570 break;
3571 case TARGET_NR_mount:
3573 /* need to look at the data field */
3574 void *p2, *p3;
3575 p = lock_user_string(arg1);
3576 p2 = lock_user_string(arg2);
3577 p3 = lock_user_string(arg3);
3578 if (!p || !p2 || !p3)
3579 ret = -TARGET_EFAULT;
3580 else
3581 /* FIXME - arg5 should be locked, but it isn't clear how to
3582 * do that since it's not guaranteed to be a NULL-terminated
3583 * string.
3585 ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
3586 unlock_user(p, arg1, 0);
3587 unlock_user(p2, arg2, 0);
3588 unlock_user(p3, arg3, 0);
3589 break;
3591 #ifdef TARGET_NR_umount
3592 case TARGET_NR_umount:
3593 if (!(p = lock_user_string(arg1)))
3594 goto efault;
3595 ret = get_errno(umount(p));
3596 unlock_user(p, arg1, 0);
3597 break;
3598 #endif
3599 #ifdef TARGET_NR_stime /* not on alpha */
3600 case TARGET_NR_stime:
3602 time_t host_time;
3603 if (get_user_sal(host_time, arg1))
3604 goto efault;
3605 ret = get_errno(stime(&host_time));
3607 break;
3608 #endif
3609 case TARGET_NR_ptrace:
3610 goto unimplemented;
3611 #ifdef TARGET_NR_alarm /* not on alpha */
3612 case TARGET_NR_alarm:
3613 ret = alarm(arg1);
3614 break;
3615 #endif
3616 #ifdef TARGET_NR_oldfstat
3617 case TARGET_NR_oldfstat:
3618 goto unimplemented;
3619 #endif
3620 #ifdef TARGET_NR_pause /* not on alpha */
3621 case TARGET_NR_pause:
3622 ret = get_errno(pause());
3623 break;
3624 #endif
3625 #ifdef TARGET_NR_utime
3626 case TARGET_NR_utime:
3628 struct utimbuf tbuf, *host_tbuf;
3629 struct target_utimbuf *target_tbuf;
3630 if (arg2) {
3631 if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
3632 goto efault;
3633 tbuf.actime = tswapl(target_tbuf->actime);
3634 tbuf.modtime = tswapl(target_tbuf->modtime);
3635 unlock_user_struct(target_tbuf, arg2, 0);
3636 host_tbuf = &tbuf;
3637 } else {
3638 host_tbuf = NULL;
3640 if (!(p = lock_user_string(arg1)))
3641 goto efault;
3642 ret = get_errno(utime(p, host_tbuf));
3643 unlock_user(p, arg1, 0);
3645 break;
3646 #endif
3647 case TARGET_NR_utimes:
3649 struct timeval *tvp, tv[2];
3650 if (arg2) {
3651 if (copy_from_user_timeval(&tv[0], arg2)
3652 || copy_from_user_timeval(&tv[1],
3653 arg2 + sizeof(struct target_timeval)))
3654 goto efault;
3655 tvp = tv;
3656 } else {
3657 tvp = NULL;
3659 if (!(p = lock_user_string(arg1)))
3660 goto efault;
3661 ret = get_errno(utimes(p, tvp));
3662 unlock_user(p, arg1, 0);
3664 break;
3665 #ifdef TARGET_NR_stty
3666 case TARGET_NR_stty:
3667 goto unimplemented;
3668 #endif
3669 #ifdef TARGET_NR_gtty
3670 case TARGET_NR_gtty:
3671 goto unimplemented;
3672 #endif
3673 case TARGET_NR_access:
3674 if (!(p = lock_user_string(arg1)))
3675 goto efault;
3676 ret = get_errno(access(p, arg2));
3677 unlock_user(p, arg1, 0);
3678 break;
3679 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
3680 case TARGET_NR_faccessat:
3681 if (!(p = lock_user_string(arg2)))
3682 goto efault;
3683 ret = get_errno(sys_faccessat(arg1, p, arg3, arg4));
3684 unlock_user(p, arg2, 0);
3685 break;
3686 #endif
3687 #ifdef TARGET_NR_nice /* not on alpha */
3688 case TARGET_NR_nice:
3689 ret = get_errno(nice(arg1));
3690 break;
3691 #endif
3692 #ifdef TARGET_NR_ftime
3693 case TARGET_NR_ftime:
3694 goto unimplemented;
3695 #endif
3696 case TARGET_NR_sync:
3697 sync();
3698 ret = 0;
3699 break;
3700 case TARGET_NR_kill:
3701 ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
3702 break;
3703 case TARGET_NR_rename:
3705 void *p2;
3706 p = lock_user_string(arg1);
3707 p2 = lock_user_string(arg2);
3708 if (!p || !p2)
3709 ret = -TARGET_EFAULT;
3710 else
3711 ret = get_errno(rename(p, p2));
3712 unlock_user(p2, arg2, 0);
3713 unlock_user(p, arg1, 0);
3715 break;
3716 #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
3717 case TARGET_NR_renameat:
3719 void *p2;
3720 p = lock_user_string(arg2);
3721 p2 = lock_user_string(arg4);
3722 if (!p || !p2)
3723 ret = -TARGET_EFAULT;
3724 else
3725 ret = get_errno(sys_renameat(arg1, p, arg3, p2));
3726 unlock_user(p2, arg4, 0);
3727 unlock_user(p, arg2, 0);
3729 break;
3730 #endif
3731 case TARGET_NR_mkdir:
3732 if (!(p = lock_user_string(arg1)))
3733 goto efault;
3734 ret = get_errno(mkdir(p, arg2));
3735 unlock_user(p, arg1, 0);
3736 break;
3737 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
3738 case TARGET_NR_mkdirat:
3739 if (!(p = lock_user_string(arg2)))
3740 goto efault;
3741 ret = get_errno(sys_mkdirat(arg1, p, arg3));
3742 unlock_user(p, arg2, 0);
3743 break;
3744 #endif
3745 case TARGET_NR_rmdir:
3746 if (!(p = lock_user_string(arg1)))
3747 goto efault;
3748 ret = get_errno(rmdir(p));
3749 unlock_user(p, arg1, 0);
3750 break;
3751 case TARGET_NR_dup:
3752 ret = get_errno(dup(arg1));
3753 break;
3754 case TARGET_NR_pipe:
3756 int host_pipe[2];
3757 ret = get_errno(pipe(host_pipe));
3758 if (!is_error(ret)) {
3759 #if defined(TARGET_MIPS)
3760 CPUMIPSState *env = (CPUMIPSState*)cpu_env;
3761 env->active_tc.gpr[3] = host_pipe[1];
3762 ret = host_pipe[0];
3763 #elif defined(TARGET_SH4)
3764 ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
3765 ret = host_pipe[0];
3766 #else
3767 if (put_user_s32(host_pipe[0], arg1)
3768 || put_user_s32(host_pipe[1], arg1 + sizeof(host_pipe[0])))
3769 goto efault;
3770 #endif
3773 break;
3774 case TARGET_NR_times:
3776 struct target_tms *tmsp;
3777 struct tms tms;
3778 ret = get_errno(times(&tms));
3779 if (arg1) {
3780 tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
3781 if (!tmsp)
3782 goto efault;
3783 tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
3784 tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
3785 tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
3786 tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime));
3788 if (!is_error(ret))
3789 ret = host_to_target_clock_t(ret);
3791 break;
3792 #ifdef TARGET_NR_prof
3793 case TARGET_NR_prof:
3794 goto unimplemented;
3795 #endif
3796 #ifdef TARGET_NR_signal
3797 case TARGET_NR_signal:
3798 goto unimplemented;
3799 #endif
3800 case TARGET_NR_acct:
3801 if (!(p = lock_user_string(arg1)))
3802 goto efault;
3803 ret = get_errno(acct(path(p)));
3804 unlock_user(p, arg1, 0);
3805 break;
3806 #ifdef TARGET_NR_umount2 /* not on alpha */
3807 case TARGET_NR_umount2:
3808 if (!(p = lock_user_string(arg1)))
3809 goto efault;
3810 ret = get_errno(umount2(p, arg2));
3811 unlock_user(p, arg1, 0);
3812 break;
3813 #endif
3814 #ifdef TARGET_NR_lock
3815 case TARGET_NR_lock:
3816 goto unimplemented;
3817 #endif
3818 case TARGET_NR_ioctl:
3819 ret = do_ioctl(arg1, arg2, arg3);
3820 break;
3821 case TARGET_NR_fcntl:
3822 ret = do_fcntl(arg1, arg2, arg3);
3823 break;
3824 #ifdef TARGET_NR_mpx
3825 case TARGET_NR_mpx:
3826 goto unimplemented;
3827 #endif
3828 case TARGET_NR_setpgid:
3829 ret = get_errno(setpgid(arg1, arg2));
3830 break;
3831 #ifdef TARGET_NR_ulimit
3832 case TARGET_NR_ulimit:
3833 goto unimplemented;
3834 #endif
3835 #ifdef TARGET_NR_oldolduname
3836 case TARGET_NR_oldolduname:
3837 goto unimplemented;
3838 #endif
3839 case TARGET_NR_umask:
3840 ret = get_errno(umask(arg1));
3841 break;
3842 case TARGET_NR_chroot:
3843 if (!(p = lock_user_string(arg1)))
3844 goto efault;
3845 ret = get_errno(chroot(p));
3846 unlock_user(p, arg1, 0);
3847 break;
3848 case TARGET_NR_ustat:
3849 goto unimplemented;
3850 case TARGET_NR_dup2:
3851 ret = get_errno(dup2(arg1, arg2));
3852 break;
3853 #ifdef TARGET_NR_getppid /* not on alpha */
3854 case TARGET_NR_getppid:
3855 ret = get_errno(getppid());
3856 break;
3857 #endif
3858 case TARGET_NR_getpgrp:
3859 ret = get_errno(getpgrp());
3860 break;
3861 case TARGET_NR_setsid:
3862 ret = get_errno(setsid());
3863 break;
3864 #ifdef TARGET_NR_sigaction
3865 case TARGET_NR_sigaction:
3867 #if !defined(TARGET_MIPS)
3868 struct target_old_sigaction *old_act;
3869 struct target_sigaction act, oact, *pact;
3870 if (arg2) {
3871 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
3872 goto efault;
3873 act._sa_handler = old_act->_sa_handler;
3874 target_siginitset(&act.sa_mask, old_act->sa_mask);
3875 act.sa_flags = old_act->sa_flags;
3876 act.sa_restorer = old_act->sa_restorer;
3877 unlock_user_struct(old_act, arg2, 0);
3878 pact = &act;
3879 } else {
3880 pact = NULL;
3882 ret = get_errno(do_sigaction(arg1, pact, &oact));
3883 if (!is_error(ret) && arg3) {
3884 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
3885 goto efault;
3886 old_act->_sa_handler = oact._sa_handler;
3887 old_act->sa_mask = oact.sa_mask.sig[0];
3888 old_act->sa_flags = oact.sa_flags;
3889 old_act->sa_restorer = oact.sa_restorer;
3890 unlock_user_struct(old_act, arg3, 1);
3892 #else
3893 struct target_sigaction act, oact, *pact, *old_act;
3895 if (arg2) {
3896 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
3897 goto efault;
3898 act._sa_handler = old_act->_sa_handler;
3899 target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
3900 act.sa_flags = old_act->sa_flags;
3901 unlock_user_struct(old_act, arg2, 0);
3902 pact = &act;
3903 } else {
3904 pact = NULL;
3907 ret = get_errno(do_sigaction(arg1, pact, &oact));
3909 if (!is_error(ret) && arg3) {
3910 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
3911 goto efault;
3912 old_act->_sa_handler = oact._sa_handler;
3913 old_act->sa_flags = oact.sa_flags;
3914 old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
3915 old_act->sa_mask.sig[1] = 0;
3916 old_act->sa_mask.sig[2] = 0;
3917 old_act->sa_mask.sig[3] = 0;
3918 unlock_user_struct(old_act, arg3, 1);
3920 #endif
3922 break;
3923 #endif
3924 case TARGET_NR_rt_sigaction:
3926 struct target_sigaction *act;
3927 struct target_sigaction *oact;
3929 if (arg2) {
3930 if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
3931 goto efault;
3932 } else
3933 act = NULL;
3934 if (arg3) {
3935 if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
3936 ret = -TARGET_EFAULT;
3937 goto rt_sigaction_fail;
3939 } else
3940 oact = NULL;
3941 ret = get_errno(do_sigaction(arg1, act, oact));
3942 rt_sigaction_fail:
3943 if (act)
3944 unlock_user_struct(act, arg2, 0);
3945 if (oact)
3946 unlock_user_struct(oact, arg3, 1);
3948 break;
3949 #ifdef TARGET_NR_sgetmask /* not on alpha */
3950 case TARGET_NR_sgetmask:
3952 sigset_t cur_set;
3953 abi_ulong target_set;
3954 sigprocmask(0, NULL, &cur_set);
3955 host_to_target_old_sigset(&target_set, &cur_set);
3956 ret = target_set;
3958 break;
3959 #endif
3960 #ifdef TARGET_NR_ssetmask /* not on alpha */
3961 case TARGET_NR_ssetmask:
3963 sigset_t set, oset, cur_set;
3964 abi_ulong target_set = arg1;
3965 sigprocmask(0, NULL, &cur_set);
3966 target_to_host_old_sigset(&set, &target_set);
3967 sigorset(&set, &set, &cur_set);
3968 sigprocmask(SIG_SETMASK, &set, &oset);
3969 host_to_target_old_sigset(&target_set, &oset);
3970 ret = target_set;
3972 break;
3973 #endif
3974 #ifdef TARGET_NR_sigprocmask
3975 case TARGET_NR_sigprocmask:
3977 int how = arg1;
3978 sigset_t set, oldset, *set_ptr;
3980 if (arg2) {
3981 switch(how) {
3982 case TARGET_SIG_BLOCK:
3983 how = SIG_BLOCK;
3984 break;
3985 case TARGET_SIG_UNBLOCK:
3986 how = SIG_UNBLOCK;
3987 break;
3988 case TARGET_SIG_SETMASK:
3989 how = SIG_SETMASK;
3990 break;
3991 default:
3992 ret = -TARGET_EINVAL;
3993 goto fail;
3995 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
3996 goto efault;
3997 target_to_host_old_sigset(&set, p);
3998 unlock_user(p, arg2, 0);
3999 set_ptr = &set;
4000 } else {
4001 how = 0;
4002 set_ptr = NULL;
4004 ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
4005 if (!is_error(ret) && arg3) {
4006 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4007 goto efault;
4008 host_to_target_old_sigset(p, &oldset);
4009 unlock_user(p, arg3, sizeof(target_sigset_t));
4012 break;
4013 #endif
4014 case TARGET_NR_rt_sigprocmask:
4016 int how = arg1;
4017 sigset_t set, oldset, *set_ptr;
4019 if (arg2) {
4020 switch(how) {
4021 case TARGET_SIG_BLOCK:
4022 how = SIG_BLOCK;
4023 break;
4024 case TARGET_SIG_UNBLOCK:
4025 how = SIG_UNBLOCK;
4026 break;
4027 case TARGET_SIG_SETMASK:
4028 how = SIG_SETMASK;
4029 break;
4030 default:
4031 ret = -TARGET_EINVAL;
4032 goto fail;
4034 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4035 goto efault;
4036 target_to_host_sigset(&set, p);
4037 unlock_user(p, arg2, 0);
4038 set_ptr = &set;
4039 } else {
4040 how = 0;
4041 set_ptr = NULL;
4043 ret = get_errno(sigprocmask(how, set_ptr, &oldset));
4044 if (!is_error(ret) && arg3) {
4045 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4046 goto efault;
4047 host_to_target_sigset(p, &oldset);
4048 unlock_user(p, arg3, sizeof(target_sigset_t));
4051 break;
4052 #ifdef TARGET_NR_sigpending
4053 case TARGET_NR_sigpending:
4055 sigset_t set;
4056 ret = get_errno(sigpending(&set));
4057 if (!is_error(ret)) {
4058 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4059 goto efault;
4060 host_to_target_old_sigset(p, &set);
4061 unlock_user(p, arg1, sizeof(target_sigset_t));
4064 break;
4065 #endif
4066 case TARGET_NR_rt_sigpending:
4068 sigset_t set;
4069 ret = get_errno(sigpending(&set));
4070 if (!is_error(ret)) {
4071 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4072 goto efault;
4073 host_to_target_sigset(p, &set);
4074 unlock_user(p, arg1, sizeof(target_sigset_t));
4077 break;
4078 #ifdef TARGET_NR_sigsuspend
4079 case TARGET_NR_sigsuspend:
4081 sigset_t set;
4082 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4083 goto efault;
4084 target_to_host_old_sigset(&set, p);
4085 unlock_user(p, arg1, 0);
4086 ret = get_errno(sigsuspend(&set));
4088 break;
4089 #endif
4090 case TARGET_NR_rt_sigsuspend:
4092 sigset_t set;
4093 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4094 goto efault;
4095 target_to_host_sigset(&set, p);
4096 unlock_user(p, arg1, 0);
4097 ret = get_errno(sigsuspend(&set));
4099 break;
4100 case TARGET_NR_rt_sigtimedwait:
4102 sigset_t set;
4103 struct timespec uts, *puts;
4104 siginfo_t uinfo;
4106 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4107 goto efault;
4108 target_to_host_sigset(&set, p);
4109 unlock_user(p, arg1, 0);
4110 if (arg3) {
4111 puts = &uts;
4112 target_to_host_timespec(puts, arg3);
4113 } else {
4114 puts = NULL;
4116 ret = get_errno(sigtimedwait(&set, &uinfo, puts));
4117 if (!is_error(ret) && arg2) {
4118 if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
4119 goto efault;
4120 host_to_target_siginfo(p, &uinfo);
4121 unlock_user(p, arg2, sizeof(target_siginfo_t));
4124 break;
4125 case TARGET_NR_rt_sigqueueinfo:
4127 siginfo_t uinfo;
4128 if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
4129 goto efault;
4130 target_to_host_siginfo(&uinfo, p);
4131 unlock_user(p, arg1, 0);
4132 ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
4134 break;
4135 #ifdef TARGET_NR_sigreturn
4136 case TARGET_NR_sigreturn:
4137 /* NOTE: ret is eax, so not transcoding must be done */
4138 ret = do_sigreturn(cpu_env);
4139 break;
4140 #endif
4141 case TARGET_NR_rt_sigreturn:
4142 /* NOTE: ret is eax, so not transcoding must be done */
4143 ret = do_rt_sigreturn(cpu_env);
4144 break;
4145 case TARGET_NR_sethostname:
4146 if (!(p = lock_user_string(arg1)))
4147 goto efault;
4148 ret = get_errno(sethostname(p, arg2));
4149 unlock_user(p, arg1, 0);
4150 break;
4151 case TARGET_NR_setrlimit:
4153 /* XXX: convert resource ? */
4154 int resource = arg1;
4155 struct target_rlimit *target_rlim;
4156 struct rlimit rlim;
4157 if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
4158 goto efault;
4159 rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4160 rlim.rlim_max = tswapl(target_rlim->rlim_max);
4161 unlock_user_struct(target_rlim, arg2, 0);
4162 ret = get_errno(setrlimit(resource, &rlim));
4164 break;
4165 case TARGET_NR_getrlimit:
4167 /* XXX: convert resource ? */
4168 int resource = arg1;
4169 struct target_rlimit *target_rlim;
4170 struct rlimit rlim;
4172 ret = get_errno(getrlimit(resource, &rlim));
4173 if (!is_error(ret)) {
4174 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
4175 goto efault;
4176 rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4177 rlim.rlim_max = tswapl(target_rlim->rlim_max);
4178 unlock_user_struct(target_rlim, arg2, 1);
4181 break;
4182 case TARGET_NR_getrusage:
4184 struct rusage rusage;
4185 ret = get_errno(getrusage(arg1, &rusage));
4186 if (!is_error(ret)) {
4187 host_to_target_rusage(arg2, &rusage);
4190 break;
4191 case TARGET_NR_gettimeofday:
4193 struct timeval tv;
4194 ret = get_errno(gettimeofday(&tv, NULL));
4195 if (!is_error(ret)) {
4196 if (copy_to_user_timeval(arg1, &tv))
4197 goto efault;
4200 break;
4201 case TARGET_NR_settimeofday:
4203 struct timeval tv;
4204 if (copy_from_user_timeval(&tv, arg1))
4205 goto efault;
4206 ret = get_errno(settimeofday(&tv, NULL));
4208 break;
4209 #ifdef TARGET_NR_select
4210 case TARGET_NR_select:
4212 struct target_sel_arg_struct *sel;
4213 abi_ulong inp, outp, exp, tvp;
4214 long nsel;
4216 if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
4217 goto efault;
4218 nsel = tswapl(sel->n);
4219 inp = tswapl(sel->inp);
4220 outp = tswapl(sel->outp);
4221 exp = tswapl(sel->exp);
4222 tvp = tswapl(sel->tvp);
4223 unlock_user_struct(sel, arg1, 0);
4224 ret = do_select(nsel, inp, outp, exp, tvp);
4226 break;
4227 #endif
4228 case TARGET_NR_symlink:
4230 void *p2;
4231 p = lock_user_string(arg1);
4232 p2 = lock_user_string(arg2);
4233 if (!p || !p2)
4234 ret = -TARGET_EFAULT;
4235 else
4236 ret = get_errno(symlink(p, p2));
4237 unlock_user(p2, arg2, 0);
4238 unlock_user(p, arg1, 0);
4240 break;
4241 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
4242 case TARGET_NR_symlinkat:
4244 void *p2;
4245 p = lock_user_string(arg1);
4246 p2 = lock_user_string(arg3);
4247 if (!p || !p2)
4248 ret = -TARGET_EFAULT;
4249 else
4250 ret = get_errno(sys_symlinkat(p, arg2, p2));
4251 unlock_user(p2, arg3, 0);
4252 unlock_user(p, arg1, 0);
4254 break;
4255 #endif
4256 #ifdef TARGET_NR_oldlstat
4257 case TARGET_NR_oldlstat:
4258 goto unimplemented;
4259 #endif
4260 case TARGET_NR_readlink:
4262 void *p2;
4263 p = lock_user_string(arg1);
4264 p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
4265 if (!p || !p2)
4266 ret = -TARGET_EFAULT;
4267 else
4268 ret = get_errno(readlink(path(p), p2, arg3));
4269 unlock_user(p2, arg2, ret);
4270 unlock_user(p, arg1, 0);
4272 break;
4273 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
4274 case TARGET_NR_readlinkat:
4276 void *p2;
4277 p = lock_user_string(arg2);
4278 p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
4279 if (!p || !p2)
4280 ret = -TARGET_EFAULT;
4281 else
4282 ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
4283 unlock_user(p2, arg3, ret);
4284 unlock_user(p, arg2, 0);
4286 break;
4287 #endif
4288 #ifdef TARGET_NR_uselib
4289 case TARGET_NR_uselib:
4290 goto unimplemented;
4291 #endif
4292 #ifdef TARGET_NR_swapon
4293 case TARGET_NR_swapon:
4294 if (!(p = lock_user_string(arg1)))
4295 goto efault;
4296 ret = get_errno(swapon(p, arg2));
4297 unlock_user(p, arg1, 0);
4298 break;
4299 #endif
4300 case TARGET_NR_reboot:
4301 goto unimplemented;
4302 #ifdef TARGET_NR_readdir
4303 case TARGET_NR_readdir:
4304 goto unimplemented;
4305 #endif
4306 #ifdef TARGET_NR_mmap
4307 case TARGET_NR_mmap:
4308 #if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS)
4310 abi_ulong *v;
4311 abi_ulong v1, v2, v3, v4, v5, v6;
4312 if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
4313 goto efault;
4314 v1 = tswapl(v[0]);
4315 v2 = tswapl(v[1]);
4316 v3 = tswapl(v[2]);
4317 v4 = tswapl(v[3]);
4318 v5 = tswapl(v[4]);
4319 v6 = tswapl(v[5]);
4320 unlock_user(v, arg1, 0);
4321 ret = get_errno(target_mmap(v1, v2, v3,
4322 target_to_host_bitmask(v4, mmap_flags_tbl),
4323 v5, v6));
4325 #else
4326 ret = get_errno(target_mmap(arg1, arg2, arg3,
4327 target_to_host_bitmask(arg4, mmap_flags_tbl),
4328 arg5,
4329 arg6));
4330 #endif
4331 break;
4332 #endif
4333 #ifdef TARGET_NR_mmap2
4334 case TARGET_NR_mmap2:
4335 #ifndef MMAP_SHIFT
4336 #define MMAP_SHIFT 12
4337 #endif
4338 ret = get_errno(target_mmap(arg1, arg2, arg3,
4339 target_to_host_bitmask(arg4, mmap_flags_tbl),
4340 arg5,
4341 arg6 << MMAP_SHIFT));
4342 break;
4343 #endif
4344 case TARGET_NR_munmap:
4345 ret = get_errno(target_munmap(arg1, arg2));
4346 break;
4347 case TARGET_NR_mprotect:
4348 ret = get_errno(target_mprotect(arg1, arg2, arg3));
4349 break;
4350 #ifdef TARGET_NR_mremap
4351 case TARGET_NR_mremap:
4352 ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
4353 break;
4354 #endif
4355 /* ??? msync/mlock/munlock are broken for softmmu. */
4356 #ifdef TARGET_NR_msync
4357 case TARGET_NR_msync:
4358 ret = get_errno(msync(g2h(arg1), arg2, arg3));
4359 break;
4360 #endif
4361 #ifdef TARGET_NR_mlock
4362 case TARGET_NR_mlock:
4363 ret = get_errno(mlock(g2h(arg1), arg2));
4364 break;
4365 #endif
4366 #ifdef TARGET_NR_munlock
4367 case TARGET_NR_munlock:
4368 ret = get_errno(munlock(g2h(arg1), arg2));
4369 break;
4370 #endif
4371 #ifdef TARGET_NR_mlockall
4372 case TARGET_NR_mlockall:
4373 ret = get_errno(mlockall(arg1));
4374 break;
4375 #endif
4376 #ifdef TARGET_NR_munlockall
4377 case TARGET_NR_munlockall:
4378 ret = get_errno(munlockall());
4379 break;
4380 #endif
4381 case TARGET_NR_truncate:
4382 if (!(p = lock_user_string(arg1)))
4383 goto efault;
4384 ret = get_errno(truncate(p, arg2));
4385 unlock_user(p, arg1, 0);
4386 break;
4387 case TARGET_NR_ftruncate:
4388 ret = get_errno(ftruncate(arg1, arg2));
4389 break;
4390 case TARGET_NR_fchmod:
4391 ret = get_errno(fchmod(arg1, arg2));
4392 break;
4393 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
4394 case TARGET_NR_fchmodat:
4395 if (!(p = lock_user_string(arg2)))
4396 goto efault;
4397 ret = get_errno(sys_fchmodat(arg1, p, arg3, arg4));
4398 unlock_user(p, arg2, 0);
4399 break;
4400 #endif
4401 case TARGET_NR_getpriority:
4402 /* libc does special remapping of the return value of
4403 * sys_getpriority() so it's just easiest to call
4404 * sys_getpriority() directly rather than through libc. */
4405 ret = sys_getpriority(arg1, arg2);
4406 break;
4407 case TARGET_NR_setpriority:
4408 ret = get_errno(setpriority(arg1, arg2, arg3));
4409 break;
4410 #ifdef TARGET_NR_profil
4411 case TARGET_NR_profil:
4412 goto unimplemented;
4413 #endif
4414 case TARGET_NR_statfs:
4415 if (!(p = lock_user_string(arg1)))
4416 goto efault;
4417 ret = get_errno(statfs(path(p), &stfs));
4418 unlock_user(p, arg1, 0);
4419 convert_statfs:
4420 if (!is_error(ret)) {
4421 struct target_statfs *target_stfs;
4423 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
4424 goto efault;
4425 __put_user(stfs.f_type, &target_stfs->f_type);
4426 __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4427 __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4428 __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4429 __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4430 __put_user(stfs.f_files, &target_stfs->f_files);
4431 __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4432 __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4433 __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4434 __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4435 unlock_user_struct(target_stfs, arg2, 1);
4437 break;
4438 case TARGET_NR_fstatfs:
4439 ret = get_errno(fstatfs(arg1, &stfs));
4440 goto convert_statfs;
4441 #ifdef TARGET_NR_statfs64
4442 case TARGET_NR_statfs64:
4443 if (!(p = lock_user_string(arg1)))
4444 goto efault;
4445 ret = get_errno(statfs(path(p), &stfs));
4446 unlock_user(p, arg1, 0);
4447 convert_statfs64:
4448 if (!is_error(ret)) {
4449 struct target_statfs64 *target_stfs;
4451 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
4452 goto efault;
4453 __put_user(stfs.f_type, &target_stfs->f_type);
4454 __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4455 __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4456 __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4457 __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4458 __put_user(stfs.f_files, &target_stfs->f_files);
4459 __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4460 __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4461 __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4462 __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4463 unlock_user_struct(target_stfs, arg3, 1);
4465 break;
4466 case TARGET_NR_fstatfs64:
4467 ret = get_errno(fstatfs(arg1, &stfs));
4468 goto convert_statfs64;
4469 #endif
4470 #ifdef TARGET_NR_ioperm
4471 case TARGET_NR_ioperm:
4472 goto unimplemented;
4473 #endif
4474 #ifdef TARGET_NR_socketcall
4475 case TARGET_NR_socketcall:
4476 ret = do_socketcall(arg1, arg2);
4477 break;
4478 #endif
4479 #ifdef TARGET_NR_accept
4480 case TARGET_NR_accept:
4481 ret = do_accept(arg1, arg2, arg3);
4482 break;
4483 #endif
4484 #ifdef TARGET_NR_bind
4485 case TARGET_NR_bind:
4486 ret = do_bind(arg1, arg2, arg3);
4487 break;
4488 #endif
4489 #ifdef TARGET_NR_connect
4490 case TARGET_NR_connect:
4491 ret = do_connect(arg1, arg2, arg3);
4492 break;
4493 #endif
4494 #ifdef TARGET_NR_getpeername
4495 case TARGET_NR_getpeername:
4496 ret = do_getpeername(arg1, arg2, arg3);
4497 break;
4498 #endif
4499 #ifdef TARGET_NR_getsockname
4500 case TARGET_NR_getsockname:
4501 ret = do_getsockname(arg1, arg2, arg3);
4502 break;
4503 #endif
4504 #ifdef TARGET_NR_getsockopt
4505 case TARGET_NR_getsockopt:
4506 ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
4507 break;
4508 #endif
4509 #ifdef TARGET_NR_listen
4510 case TARGET_NR_listen:
4511 ret = get_errno(listen(arg1, arg2));
4512 break;
4513 #endif
4514 #ifdef TARGET_NR_recv
4515 case TARGET_NR_recv:
4516 ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
4517 break;
4518 #endif
4519 #ifdef TARGET_NR_recvfrom
4520 case TARGET_NR_recvfrom:
4521 ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
4522 break;
4523 #endif
4524 #ifdef TARGET_NR_recvmsg
4525 case TARGET_NR_recvmsg:
4526 ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
4527 break;
4528 #endif
4529 #ifdef TARGET_NR_send
4530 case TARGET_NR_send:
4531 ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
4532 break;
4533 #endif
4534 #ifdef TARGET_NR_sendmsg
4535 case TARGET_NR_sendmsg:
4536 ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
4537 break;
4538 #endif
4539 #ifdef TARGET_NR_sendto
4540 case TARGET_NR_sendto:
4541 ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
4542 break;
4543 #endif
4544 #ifdef TARGET_NR_shutdown
4545 case TARGET_NR_shutdown:
4546 ret = get_errno(shutdown(arg1, arg2));
4547 break;
4548 #endif
4549 #ifdef TARGET_NR_socket
4550 case TARGET_NR_socket:
4551 ret = do_socket(arg1, arg2, arg3);
4552 break;
4553 #endif
4554 #ifdef TARGET_NR_socketpair
4555 case TARGET_NR_socketpair:
4556 ret = do_socketpair(arg1, arg2, arg3, arg4);
4557 break;
4558 #endif
4559 #ifdef TARGET_NR_setsockopt
4560 case TARGET_NR_setsockopt:
4561 ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
4562 break;
4563 #endif
4565 case TARGET_NR_syslog:
4566 if (!(p = lock_user_string(arg2)))
4567 goto efault;
4568 ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
4569 unlock_user(p, arg2, 0);
4570 break;
4572 case TARGET_NR_setitimer:
4574 struct itimerval value, ovalue, *pvalue;
4576 if (arg2) {
4577 pvalue = &value;
4578 if (copy_from_user_timeval(&pvalue->it_interval, arg2)
4579 || copy_from_user_timeval(&pvalue->it_value,
4580 arg2 + sizeof(struct target_timeval)))
4581 goto efault;
4582 } else {
4583 pvalue = NULL;
4585 ret = get_errno(setitimer(arg1, pvalue, &ovalue));
4586 if (!is_error(ret) && arg3) {
4587 if (copy_to_user_timeval(arg3,
4588 &ovalue.it_interval)
4589 || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
4590 &ovalue.it_value))
4591 goto efault;
4594 break;
4595 case TARGET_NR_getitimer:
4597 struct itimerval value;
4599 ret = get_errno(getitimer(arg1, &value));
4600 if (!is_error(ret) && arg2) {
4601 if (copy_to_user_timeval(arg2,
4602 &value.it_interval)
4603 || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
4604 &value.it_value))
4605 goto efault;
4608 break;
4609 case TARGET_NR_stat:
4610 if (!(p = lock_user_string(arg1)))
4611 goto efault;
4612 ret = get_errno(stat(path(p), &st));
4613 unlock_user(p, arg1, 0);
4614 goto do_stat;
4615 case TARGET_NR_lstat:
4616 if (!(p = lock_user_string(arg1)))
4617 goto efault;
4618 ret = get_errno(lstat(path(p), &st));
4619 unlock_user(p, arg1, 0);
4620 goto do_stat;
4621 case TARGET_NR_fstat:
4623 ret = get_errno(fstat(arg1, &st));
4624 do_stat:
4625 if (!is_error(ret)) {
4626 struct target_stat *target_st;
4628 if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
4629 goto efault;
4630 __put_user(st.st_dev, &target_st->st_dev);
4631 __put_user(st.st_ino, &target_st->st_ino);
4632 __put_user(st.st_mode, &target_st->st_mode);
4633 __put_user(st.st_uid, &target_st->st_uid);
4634 __put_user(st.st_gid, &target_st->st_gid);
4635 __put_user(st.st_nlink, &target_st->st_nlink);
4636 __put_user(st.st_rdev, &target_st->st_rdev);
4637 __put_user(st.st_size, &target_st->st_size);
4638 __put_user(st.st_blksize, &target_st->st_blksize);
4639 __put_user(st.st_blocks, &target_st->st_blocks);
4640 __put_user(st.st_atime, &target_st->target_st_atime);
4641 __put_user(st.st_mtime, &target_st->target_st_mtime);
4642 __put_user(st.st_ctime, &target_st->target_st_ctime);
4643 unlock_user_struct(target_st, arg2, 1);
4646 break;
4647 #ifdef TARGET_NR_olduname
4648 case TARGET_NR_olduname:
4649 goto unimplemented;
4650 #endif
4651 #ifdef TARGET_NR_iopl
4652 case TARGET_NR_iopl:
4653 goto unimplemented;
4654 #endif
4655 case TARGET_NR_vhangup:
4656 ret = get_errno(vhangup());
4657 break;
4658 #ifdef TARGET_NR_idle
4659 case TARGET_NR_idle:
4660 goto unimplemented;
4661 #endif
4662 #ifdef TARGET_NR_syscall
4663 case TARGET_NR_syscall:
4664 ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
4665 break;
4666 #endif
4667 case TARGET_NR_wait4:
4669 int status;
4670 abi_long status_ptr = arg2;
4671 struct rusage rusage, *rusage_ptr;
4672 abi_ulong target_rusage = arg4;
4673 if (target_rusage)
4674 rusage_ptr = &rusage;
4675 else
4676 rusage_ptr = NULL;
4677 ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
4678 if (!is_error(ret)) {
4679 if (status_ptr) {
4680 if (put_user_s32(status, status_ptr))
4681 goto efault;
4683 if (target_rusage)
4684 host_to_target_rusage(target_rusage, &rusage);
4687 break;
4688 #ifdef TARGET_NR_swapoff
4689 case TARGET_NR_swapoff:
4690 if (!(p = lock_user_string(arg1)))
4691 goto efault;
4692 ret = get_errno(swapoff(p));
4693 unlock_user(p, arg1, 0);
4694 break;
4695 #endif
4696 case TARGET_NR_sysinfo:
4698 struct target_sysinfo *target_value;
4699 struct sysinfo value;
4700 ret = get_errno(sysinfo(&value));
4701 if (!is_error(ret) && arg1)
4703 if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
4704 goto efault;
4705 __put_user(value.uptime, &target_value->uptime);
4706 __put_user(value.loads[0], &target_value->loads[0]);
4707 __put_user(value.loads[1], &target_value->loads[1]);
4708 __put_user(value.loads[2], &target_value->loads[2]);
4709 __put_user(value.totalram, &target_value->totalram);
4710 __put_user(value.freeram, &target_value->freeram);
4711 __put_user(value.sharedram, &target_value->sharedram);
4712 __put_user(value.bufferram, &target_value->bufferram);
4713 __put_user(value.totalswap, &target_value->totalswap);
4714 __put_user(value.freeswap, &target_value->freeswap);
4715 __put_user(value.procs, &target_value->procs);
4716 __put_user(value.totalhigh, &target_value->totalhigh);
4717 __put_user(value.freehigh, &target_value->freehigh);
4718 __put_user(value.mem_unit, &target_value->mem_unit);
4719 unlock_user_struct(target_value, arg1, 1);
4722 break;
4723 #ifdef TARGET_NR_ipc
4724 case TARGET_NR_ipc:
4725 ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
4726 break;
4727 #endif
4728 case TARGET_NR_fsync:
4729 ret = get_errno(fsync(arg1));
4730 break;
4731 case TARGET_NR_clone:
4732 #if defined(TARGET_SH4)
4733 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
4734 #else
4735 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
4736 #endif
4737 break;
4738 #ifdef __NR_exit_group
4739 /* new thread calls */
4740 case TARGET_NR_exit_group:
4741 gdb_exit(cpu_env, arg1);
4742 ret = get_errno(exit_group(arg1));
4743 break;
4744 #endif
4745 case TARGET_NR_setdomainname:
4746 if (!(p = lock_user_string(arg1)))
4747 goto efault;
4748 ret = get_errno(setdomainname(p, arg2));
4749 unlock_user(p, arg1, 0);
4750 break;
4751 case TARGET_NR_uname:
4752 /* no need to transcode because we use the linux syscall */
4754 struct new_utsname * buf;
4756 if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
4757 goto efault;
4758 ret = get_errno(sys_uname(buf));
4759 if (!is_error(ret)) {
4760 /* Overrite the native machine name with whatever is being
4761 emulated. */
4762 strcpy (buf->machine, UNAME_MACHINE);
4763 /* Allow the user to override the reported release. */
4764 if (qemu_uname_release && *qemu_uname_release)
4765 strcpy (buf->release, qemu_uname_release);
4767 unlock_user_struct(buf, arg1, 1);
4769 break;
4770 #ifdef TARGET_I386
4771 case TARGET_NR_modify_ldt:
4772 ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
4773 break;
4774 #if !defined(TARGET_X86_64)
4775 case TARGET_NR_vm86old:
4776 goto unimplemented;
4777 case TARGET_NR_vm86:
4778 ret = do_vm86(cpu_env, arg1, arg2);
4779 break;
4780 #endif
4781 #endif
4782 case TARGET_NR_adjtimex:
4783 goto unimplemented;
4784 #ifdef TARGET_NR_create_module
4785 case TARGET_NR_create_module:
4786 #endif
4787 case TARGET_NR_init_module:
4788 case TARGET_NR_delete_module:
4789 #ifdef TARGET_NR_get_kernel_syms
4790 case TARGET_NR_get_kernel_syms:
4791 #endif
4792 goto unimplemented;
4793 case TARGET_NR_quotactl:
4794 goto unimplemented;
4795 case TARGET_NR_getpgid:
4796 ret = get_errno(getpgid(arg1));
4797 break;
4798 case TARGET_NR_fchdir:
4799 ret = get_errno(fchdir(arg1));
4800 break;
4801 #ifdef TARGET_NR_bdflush /* not on x86_64 */
4802 case TARGET_NR_bdflush:
4803 goto unimplemented;
4804 #endif
4805 #ifdef TARGET_NR_sysfs
4806 case TARGET_NR_sysfs:
4807 goto unimplemented;
4808 #endif
4809 case TARGET_NR_personality:
4810 ret = get_errno(personality(arg1));
4811 break;
4812 #ifdef TARGET_NR_afs_syscall
4813 case TARGET_NR_afs_syscall:
4814 goto unimplemented;
4815 #endif
4816 #ifdef TARGET_NR__llseek /* Not on alpha */
4817 case TARGET_NR__llseek:
4819 #if defined (__x86_64__)
4820 ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
4821 if (put_user_s64(ret, arg4))
4822 goto efault;
4823 #else
4824 int64_t res;
4825 ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
4826 if (put_user_s64(res, arg4))
4827 goto efault;
4828 #endif
4830 break;
4831 #endif
4832 case TARGET_NR_getdents:
4833 #if TARGET_ABI_BITS != 32
4834 goto unimplemented;
4835 #elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
4837 struct target_dirent *target_dirp;
4838 struct dirent *dirp;
4839 abi_long count = arg3;
4841 dirp = malloc(count);
4842 if (!dirp) {
4843 ret = -TARGET_ENOMEM;
4844 goto fail;
4847 ret = get_errno(sys_getdents(arg1, dirp, count));
4848 if (!is_error(ret)) {
4849 struct dirent *de;
4850 struct target_dirent *tde;
4851 int len = ret;
4852 int reclen, treclen;
4853 int count1, tnamelen;
4855 count1 = 0;
4856 de = dirp;
4857 if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4858 goto efault;
4859 tde = target_dirp;
4860 while (len > 0) {
4861 reclen = de->d_reclen;
4862 treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
4863 tde->d_reclen = tswap16(treclen);
4864 tde->d_ino = tswapl(de->d_ino);
4865 tde->d_off = tswapl(de->d_off);
4866 tnamelen = treclen - (2 * sizeof(abi_long) + 2);
4867 if (tnamelen > 256)
4868 tnamelen = 256;
4869 /* XXX: may not be correct */
4870 strncpy(tde->d_name, de->d_name, tnamelen);
4871 de = (struct dirent *)((char *)de + reclen);
4872 len -= reclen;
4873 tde = (struct target_dirent *)((char *)tde + treclen);
4874 count1 += treclen;
4876 ret = count1;
4877 unlock_user(target_dirp, arg2, ret);
4879 free(dirp);
4881 #else
4883 struct dirent *dirp;
4884 abi_long count = arg3;
4886 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4887 goto efault;
4888 ret = get_errno(sys_getdents(arg1, dirp, count));
4889 if (!is_error(ret)) {
4890 struct dirent *de;
4891 int len = ret;
4892 int reclen;
4893 de = dirp;
4894 while (len > 0) {
4895 reclen = de->d_reclen;
4896 if (reclen > len)
4897 break;
4898 de->d_reclen = tswap16(reclen);
4899 tswapls(&de->d_ino);
4900 tswapls(&de->d_off);
4901 de = (struct dirent *)((char *)de + reclen);
4902 len -= reclen;
4905 unlock_user(dirp, arg2, ret);
4907 #endif
4908 break;
4909 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
4910 case TARGET_NR_getdents64:
4912 struct dirent64 *dirp;
4913 abi_long count = arg3;
4914 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4915 goto efault;
4916 ret = get_errno(sys_getdents64(arg1, dirp, count));
4917 if (!is_error(ret)) {
4918 struct dirent64 *de;
4919 int len = ret;
4920 int reclen;
4921 de = dirp;
4922 while (len > 0) {
4923 reclen = de->d_reclen;
4924 if (reclen > len)
4925 break;
4926 de->d_reclen = tswap16(reclen);
4927 tswap64s((uint64_t *)&de->d_ino);
4928 tswap64s((uint64_t *)&de->d_off);
4929 de = (struct dirent64 *)((char *)de + reclen);
4930 len -= reclen;
4933 unlock_user(dirp, arg2, ret);
4935 break;
4936 #endif /* TARGET_NR_getdents64 */
4937 #ifdef TARGET_NR__newselect
4938 case TARGET_NR__newselect:
4939 ret = do_select(arg1, arg2, arg3, arg4, arg5);
4940 break;
4941 #endif
4942 #ifdef TARGET_NR_poll
4943 case TARGET_NR_poll:
4945 struct target_pollfd *target_pfd;
4946 unsigned int nfds = arg2;
4947 int timeout = arg3;
4948 struct pollfd *pfd;
4949 unsigned int i;
4951 target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
4952 if (!target_pfd)
4953 goto efault;
4954 pfd = alloca(sizeof(struct pollfd) * nfds);
4955 for(i = 0; i < nfds; i++) {
4956 pfd[i].fd = tswap32(target_pfd[i].fd);
4957 pfd[i].events = tswap16(target_pfd[i].events);
4959 ret = get_errno(poll(pfd, nfds, timeout));
4960 if (!is_error(ret)) {
4961 for(i = 0; i < nfds; i++) {
4962 target_pfd[i].revents = tswap16(pfd[i].revents);
4964 ret += nfds * (sizeof(struct target_pollfd)
4965 - sizeof(struct pollfd));
4967 unlock_user(target_pfd, arg1, ret);
4969 break;
4970 #endif
4971 case TARGET_NR_flock:
4972 /* NOTE: the flock constant seems to be the same for every
4973 Linux platform */
4974 ret = get_errno(flock(arg1, arg2));
4975 break;
4976 case TARGET_NR_readv:
4978 int count = arg3;
4979 struct iovec *vec;
4981 vec = alloca(count * sizeof(struct iovec));
4982 if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
4983 goto efault;
4984 ret = get_errno(readv(arg1, vec, count));
4985 unlock_iovec(vec, arg2, count, 1);
4987 break;
4988 case TARGET_NR_writev:
4990 int count = arg3;
4991 struct iovec *vec;
4993 vec = alloca(count * sizeof(struct iovec));
4994 if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
4995 goto efault;
4996 ret = get_errno(writev(arg1, vec, count));
4997 unlock_iovec(vec, arg2, count, 0);
4999 break;
5000 case TARGET_NR_getsid:
5001 ret = get_errno(getsid(arg1));
5002 break;
5003 #if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
5004 case TARGET_NR_fdatasync:
5005 ret = get_errno(fdatasync(arg1));
5006 break;
5007 #endif
5008 case TARGET_NR__sysctl:
5009 /* We don't implement this, but ENOTDIR is always a safe
5010 return value. */
5011 ret = -TARGET_ENOTDIR;
5012 break;
5013 case TARGET_NR_sched_setparam:
5015 struct sched_param *target_schp;
5016 struct sched_param schp;
5018 if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
5019 goto efault;
5020 schp.sched_priority = tswap32(target_schp->sched_priority);
5021 unlock_user_struct(target_schp, arg2, 0);
5022 ret = get_errno(sched_setparam(arg1, &schp));
5024 break;
5025 case TARGET_NR_sched_getparam:
5027 struct sched_param *target_schp;
5028 struct sched_param schp;
5029 ret = get_errno(sched_getparam(arg1, &schp));
5030 if (!is_error(ret)) {
5031 if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
5032 goto efault;
5033 target_schp->sched_priority = tswap32(schp.sched_priority);
5034 unlock_user_struct(target_schp, arg2, 1);
5037 break;
5038 case TARGET_NR_sched_setscheduler:
5040 struct sched_param *target_schp;
5041 struct sched_param schp;
5042 if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
5043 goto efault;
5044 schp.sched_priority = tswap32(target_schp->sched_priority);
5045 unlock_user_struct(target_schp, arg3, 0);
5046 ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
5048 break;
5049 case TARGET_NR_sched_getscheduler:
5050 ret = get_errno(sched_getscheduler(arg1));
5051 break;
5052 case TARGET_NR_sched_yield:
5053 ret = get_errno(sched_yield());
5054 break;
5055 case TARGET_NR_sched_get_priority_max:
5056 ret = get_errno(sched_get_priority_max(arg1));
5057 break;
5058 case TARGET_NR_sched_get_priority_min:
5059 ret = get_errno(sched_get_priority_min(arg1));
5060 break;
5061 case TARGET_NR_sched_rr_get_interval:
5063 struct timespec ts;
5064 ret = get_errno(sched_rr_get_interval(arg1, &ts));
5065 if (!is_error(ret)) {
5066 host_to_target_timespec(arg2, &ts);
5069 break;
5070 case TARGET_NR_nanosleep:
5072 struct timespec req, rem;
5073 target_to_host_timespec(&req, arg1);
5074 ret = get_errno(nanosleep(&req, &rem));
5075 if (is_error(ret) && arg2) {
5076 host_to_target_timespec(arg2, &rem);
5079 break;
5080 #ifdef TARGET_NR_query_module
5081 case TARGET_NR_query_module:
5082 goto unimplemented;
5083 #endif
5084 #ifdef TARGET_NR_nfsservctl
5085 case TARGET_NR_nfsservctl:
5086 goto unimplemented;
5087 #endif
5088 case TARGET_NR_prctl:
5089 switch (arg1)
5091 case PR_GET_PDEATHSIG:
5093 int deathsig;
5094 ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
5095 if (!is_error(ret) && arg2
5096 && put_user_ual(deathsig, arg2))
5097 goto efault;
5099 break;
5100 default:
5101 ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
5102 break;
5104 break;
5105 #ifdef TARGET_NR_arch_prctl
5106 case TARGET_NR_arch_prctl:
5107 #if defined(TARGET_I386) && !defined(TARGET_ABI32)
5108 ret = do_arch_prctl(cpu_env, arg1, arg2);
5109 break;
5110 #else
5111 goto unimplemented;
5112 #endif
5113 #endif
5114 #ifdef TARGET_NR_pread
5115 case TARGET_NR_pread:
5116 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5117 goto efault;
5118 ret = get_errno(pread(arg1, p, arg3, arg4));
5119 unlock_user(p, arg2, ret);
5120 break;
5121 case TARGET_NR_pwrite:
5122 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5123 goto efault;
5124 ret = get_errno(pwrite(arg1, p, arg3, arg4));
5125 unlock_user(p, arg2, 0);
5126 break;
5127 #endif
5128 #ifdef TARGET_NR_pread64
5129 case TARGET_NR_pread64:
5130 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5131 goto efault;
5132 ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
5133 unlock_user(p, arg2, ret);
5134 break;
5135 case TARGET_NR_pwrite64:
5136 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5137 goto efault;
5138 ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
5139 unlock_user(p, arg2, 0);
5140 break;
5141 #endif
5142 case TARGET_NR_getcwd:
5143 if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
5144 goto efault;
5145 ret = get_errno(sys_getcwd1(p, arg2));
5146 unlock_user(p, arg1, ret);
5147 break;
5148 case TARGET_NR_capget:
5149 goto unimplemented;
5150 case TARGET_NR_capset:
5151 goto unimplemented;
5152 case TARGET_NR_sigaltstack:
5153 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
5154 defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA)
5155 ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env));
5156 break;
5157 #else
5158 goto unimplemented;
5159 #endif
5160 case TARGET_NR_sendfile:
5161 goto unimplemented;
5162 #ifdef TARGET_NR_getpmsg
5163 case TARGET_NR_getpmsg:
5164 goto unimplemented;
5165 #endif
5166 #ifdef TARGET_NR_putpmsg
5167 case TARGET_NR_putpmsg:
5168 goto unimplemented;
5169 #endif
5170 #ifdef TARGET_NR_vfork
5171 case TARGET_NR_vfork:
5172 ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
5173 0, 0, 0, 0));
5174 break;
5175 #endif
5176 #ifdef TARGET_NR_ugetrlimit
5177 case TARGET_NR_ugetrlimit:
5179 struct rlimit rlim;
5180 ret = get_errno(getrlimit(arg1, &rlim));
5181 if (!is_error(ret)) {
5182 struct target_rlimit *target_rlim;
5183 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
5184 goto efault;
5185 target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
5186 target_rlim->rlim_max = tswapl(rlim.rlim_max);
5187 unlock_user_struct(target_rlim, arg2, 1);
5189 break;
5191 #endif
5192 #ifdef TARGET_NR_truncate64
5193 case TARGET_NR_truncate64:
5194 if (!(p = lock_user_string(arg1)))
5195 goto efault;
5196 ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
5197 unlock_user(p, arg1, 0);
5198 break;
5199 #endif
5200 #ifdef TARGET_NR_ftruncate64
5201 case TARGET_NR_ftruncate64:
5202 ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
5203 break;
5204 #endif
5205 #ifdef TARGET_NR_stat64
5206 case TARGET_NR_stat64:
5207 if (!(p = lock_user_string(arg1)))
5208 goto efault;
5209 ret = get_errno(stat(path(p), &st));
5210 unlock_user(p, arg1, 0);
5211 if (!is_error(ret))
5212 ret = host_to_target_stat64(cpu_env, arg2, &st);
5213 break;
5214 #endif
5215 #ifdef TARGET_NR_lstat64
5216 case TARGET_NR_lstat64:
5217 if (!(p = lock_user_string(arg1)))
5218 goto efault;
5219 ret = get_errno(lstat(path(p), &st));
5220 unlock_user(p, arg1, 0);
5221 if (!is_error(ret))
5222 ret = host_to_target_stat64(cpu_env, arg2, &st);
5223 break;
5224 #endif
5225 #ifdef TARGET_NR_fstat64
5226 case TARGET_NR_fstat64:
5227 ret = get_errno(fstat(arg1, &st));
5228 if (!is_error(ret))
5229 ret = host_to_target_stat64(cpu_env, arg2, &st);
5230 break;
5231 #endif
5232 #if defined(TARGET_NR_fstatat64) && defined(__NR_fstatat64)
5233 case TARGET_NR_fstatat64:
5234 if (!(p = lock_user_string(arg2)))
5235 goto efault;
5236 ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
5237 if (!is_error(ret))
5238 ret = host_to_target_stat64(cpu_env, arg3, &st);
5239 break;
5240 #endif
5241 #ifdef USE_UID16
5242 case TARGET_NR_lchown:
5243 if (!(p = lock_user_string(arg1)))
5244 goto efault;
5245 ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
5246 unlock_user(p, arg1, 0);
5247 break;
5248 case TARGET_NR_getuid:
5249 ret = get_errno(high2lowuid(getuid()));
5250 break;
5251 case TARGET_NR_getgid:
5252 ret = get_errno(high2lowgid(getgid()));
5253 break;
5254 case TARGET_NR_geteuid:
5255 ret = get_errno(high2lowuid(geteuid()));
5256 break;
5257 case TARGET_NR_getegid:
5258 ret = get_errno(high2lowgid(getegid()));
5259 break;
5260 case TARGET_NR_setreuid:
5261 ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
5262 break;
5263 case TARGET_NR_setregid:
5264 ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
5265 break;
5266 case TARGET_NR_getgroups:
5268 int gidsetsize = arg1;
5269 uint16_t *target_grouplist;
5270 gid_t *grouplist;
5271 int i;
5273 grouplist = alloca(gidsetsize * sizeof(gid_t));
5274 ret = get_errno(getgroups(gidsetsize, grouplist));
5275 if (gidsetsize == 0)
5276 break;
5277 if (!is_error(ret)) {
5278 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
5279 if (!target_grouplist)
5280 goto efault;
5281 for(i = 0;i < ret; i++)
5282 target_grouplist[i] = tswap16(grouplist[i]);
5283 unlock_user(target_grouplist, arg2, gidsetsize * 2);
5286 break;
5287 case TARGET_NR_setgroups:
5289 int gidsetsize = arg1;
5290 uint16_t *target_grouplist;
5291 gid_t *grouplist;
5292 int i;
5294 grouplist = alloca(gidsetsize * sizeof(gid_t));
5295 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
5296 if (!target_grouplist) {
5297 ret = -TARGET_EFAULT;
5298 goto fail;
5300 for(i = 0;i < gidsetsize; i++)
5301 grouplist[i] = tswap16(target_grouplist[i]);
5302 unlock_user(target_grouplist, arg2, 0);
5303 ret = get_errno(setgroups(gidsetsize, grouplist));
5305 break;
5306 case TARGET_NR_fchown:
5307 ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
5308 break;
5309 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
5310 case TARGET_NR_fchownat:
5311 if (!(p = lock_user_string(arg2)))
5312 goto efault;
5313 ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
5314 unlock_user(p, arg2, 0);
5315 break;
5316 #endif
5317 #ifdef TARGET_NR_setresuid
5318 case TARGET_NR_setresuid:
5319 ret = get_errno(setresuid(low2highuid(arg1),
5320 low2highuid(arg2),
5321 low2highuid(arg3)));
5322 break;
5323 #endif
5324 #ifdef TARGET_NR_getresuid
5325 case TARGET_NR_getresuid:
5327 uid_t ruid, euid, suid;
5328 ret = get_errno(getresuid(&ruid, &euid, &suid));
5329 if (!is_error(ret)) {
5330 if (put_user_u16(high2lowuid(ruid), arg1)
5331 || put_user_u16(high2lowuid(euid), arg2)
5332 || put_user_u16(high2lowuid(suid), arg3))
5333 goto efault;
5336 break;
5337 #endif
5338 #ifdef TARGET_NR_getresgid
5339 case TARGET_NR_setresgid:
5340 ret = get_errno(setresgid(low2highgid(arg1),
5341 low2highgid(arg2),
5342 low2highgid(arg3)));
5343 break;
5344 #endif
5345 #ifdef TARGET_NR_getresgid
5346 case TARGET_NR_getresgid:
5348 gid_t rgid, egid, sgid;
5349 ret = get_errno(getresgid(&rgid, &egid, &sgid));
5350 if (!is_error(ret)) {
5351 if (put_user_u16(high2lowgid(rgid), arg1)
5352 || put_user_u16(high2lowgid(egid), arg2)
5353 || put_user_u16(high2lowgid(sgid), arg3))
5354 goto efault;
5357 break;
5358 #endif
5359 case TARGET_NR_chown:
5360 if (!(p = lock_user_string(arg1)))
5361 goto efault;
5362 ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
5363 unlock_user(p, arg1, 0);
5364 break;
5365 case TARGET_NR_setuid:
5366 ret = get_errno(setuid(low2highuid(arg1)));
5367 break;
5368 case TARGET_NR_setgid:
5369 ret = get_errno(setgid(low2highgid(arg1)));
5370 break;
5371 case TARGET_NR_setfsuid:
5372 ret = get_errno(setfsuid(arg1));
5373 break;
5374 case TARGET_NR_setfsgid:
5375 ret = get_errno(setfsgid(arg1));
5376 break;
5377 #endif /* USE_UID16 */
5379 #ifdef TARGET_NR_lchown32
5380 case TARGET_NR_lchown32:
5381 if (!(p = lock_user_string(arg1)))
5382 goto efault;
5383 ret = get_errno(lchown(p, arg2, arg3));
5384 unlock_user(p, arg1, 0);
5385 break;
5386 #endif
5387 #ifdef TARGET_NR_getuid32
5388 case TARGET_NR_getuid32:
5389 ret = get_errno(getuid());
5390 break;
5391 #endif
5392 #ifdef TARGET_NR_getgid32
5393 case TARGET_NR_getgid32:
5394 ret = get_errno(getgid());
5395 break;
5396 #endif
5397 #ifdef TARGET_NR_geteuid32
5398 case TARGET_NR_geteuid32:
5399 ret = get_errno(geteuid());
5400 break;
5401 #endif
5402 #ifdef TARGET_NR_getegid32
5403 case TARGET_NR_getegid32:
5404 ret = get_errno(getegid());
5405 break;
5406 #endif
5407 #ifdef TARGET_NR_setreuid32
5408 case TARGET_NR_setreuid32:
5409 ret = get_errno(setreuid(arg1, arg2));
5410 break;
5411 #endif
5412 #ifdef TARGET_NR_setregid32
5413 case TARGET_NR_setregid32:
5414 ret = get_errno(setregid(arg1, arg2));
5415 break;
5416 #endif
5417 #ifdef TARGET_NR_getgroups32
5418 case TARGET_NR_getgroups32:
5420 int gidsetsize = arg1;
5421 uint32_t *target_grouplist;
5422 gid_t *grouplist;
5423 int i;
5425 grouplist = alloca(gidsetsize * sizeof(gid_t));
5426 ret = get_errno(getgroups(gidsetsize, grouplist));
5427 if (gidsetsize == 0)
5428 break;
5429 if (!is_error(ret)) {
5430 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
5431 if (!target_grouplist) {
5432 ret = -TARGET_EFAULT;
5433 goto fail;
5435 for(i = 0;i < ret; i++)
5436 target_grouplist[i] = tswap32(grouplist[i]);
5437 unlock_user(target_grouplist, arg2, gidsetsize * 4);
5440 break;
5441 #endif
5442 #ifdef TARGET_NR_setgroups32
5443 case TARGET_NR_setgroups32:
5445 int gidsetsize = arg1;
5446 uint32_t *target_grouplist;
5447 gid_t *grouplist;
5448 int i;
5450 grouplist = alloca(gidsetsize * sizeof(gid_t));
5451 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
5452 if (!target_grouplist) {
5453 ret = -TARGET_EFAULT;
5454 goto fail;
5456 for(i = 0;i < gidsetsize; i++)
5457 grouplist[i] = tswap32(target_grouplist[i]);
5458 unlock_user(target_grouplist, arg2, 0);
5459 ret = get_errno(setgroups(gidsetsize, grouplist));
5461 break;
5462 #endif
5463 #ifdef TARGET_NR_fchown32
5464 case TARGET_NR_fchown32:
5465 ret = get_errno(fchown(arg1, arg2, arg3));
5466 break;
5467 #endif
5468 #ifdef TARGET_NR_setresuid32
5469 case TARGET_NR_setresuid32:
5470 ret = get_errno(setresuid(arg1, arg2, arg3));
5471 break;
5472 #endif
5473 #ifdef TARGET_NR_getresuid32
5474 case TARGET_NR_getresuid32:
5476 uid_t ruid, euid, suid;
5477 ret = get_errno(getresuid(&ruid, &euid, &suid));
5478 if (!is_error(ret)) {
5479 if (put_user_u32(ruid, arg1)
5480 || put_user_u32(euid, arg2)
5481 || put_user_u32(suid, arg3))
5482 goto efault;
5485 break;
5486 #endif
5487 #ifdef TARGET_NR_setresgid32
5488 case TARGET_NR_setresgid32:
5489 ret = get_errno(setresgid(arg1, arg2, arg3));
5490 break;
5491 #endif
5492 #ifdef TARGET_NR_getresgid32
5493 case TARGET_NR_getresgid32:
5495 gid_t rgid, egid, sgid;
5496 ret = get_errno(getresgid(&rgid, &egid, &sgid));
5497 if (!is_error(ret)) {
5498 if (put_user_u32(rgid, arg1)
5499 || put_user_u32(egid, arg2)
5500 || put_user_u32(sgid, arg3))
5501 goto efault;
5504 break;
5505 #endif
5506 #ifdef TARGET_NR_chown32
5507 case TARGET_NR_chown32:
5508 if (!(p = lock_user_string(arg1)))
5509 goto efault;
5510 ret = get_errno(chown(p, arg2, arg3));
5511 unlock_user(p, arg1, 0);
5512 break;
5513 #endif
5514 #ifdef TARGET_NR_setuid32
5515 case TARGET_NR_setuid32:
5516 ret = get_errno(setuid(arg1));
5517 break;
5518 #endif
5519 #ifdef TARGET_NR_setgid32
5520 case TARGET_NR_setgid32:
5521 ret = get_errno(setgid(arg1));
5522 break;
5523 #endif
5524 #ifdef TARGET_NR_setfsuid32
5525 case TARGET_NR_setfsuid32:
5526 ret = get_errno(setfsuid(arg1));
5527 break;
5528 #endif
5529 #ifdef TARGET_NR_setfsgid32
5530 case TARGET_NR_setfsgid32:
5531 ret = get_errno(setfsgid(arg1));
5532 break;
5533 #endif
5535 case TARGET_NR_pivot_root:
5536 goto unimplemented;
5537 #ifdef TARGET_NR_mincore
5538 case TARGET_NR_mincore:
5539 goto unimplemented;
5540 #endif
5541 #ifdef TARGET_NR_madvise
5542 case TARGET_NR_madvise:
5543 /* A straight passthrough may not be safe because qemu sometimes
5544 turns private flie-backed mappings into anonymous mappings.
5545 This will break MADV_DONTNEED.
5546 This is a hint, so ignoring and returning success is ok. */
5547 ret = get_errno(0);
5548 break;
5549 #endif
5550 #if TARGET_ABI_BITS == 32
5551 case TARGET_NR_fcntl64:
5553 int cmd;
5554 struct flock64 fl;
5555 struct target_flock64 *target_fl;
5556 #ifdef TARGET_ARM
5557 struct target_eabi_flock64 *target_efl;
5558 #endif
5560 switch(arg2){
5561 case TARGET_F_GETLK64:
5562 cmd = F_GETLK64;
5563 break;
5564 case TARGET_F_SETLK64:
5565 cmd = F_SETLK64;
5566 break;
5567 case TARGET_F_SETLKW64:
5568 cmd = F_SETLK64;
5569 break;
5570 default:
5571 cmd = arg2;
5572 break;
5575 switch(arg2) {
5576 case TARGET_F_GETLK64:
5577 #ifdef TARGET_ARM
5578 if (((CPUARMState *)cpu_env)->eabi) {
5579 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1))
5580 goto efault;
5581 fl.l_type = tswap16(target_efl->l_type);
5582 fl.l_whence = tswap16(target_efl->l_whence);
5583 fl.l_start = tswap64(target_efl->l_start);
5584 fl.l_len = tswap64(target_efl->l_len);
5585 fl.l_pid = tswapl(target_efl->l_pid);
5586 unlock_user_struct(target_efl, arg3, 0);
5587 } else
5588 #endif
5590 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1))
5591 goto efault;
5592 fl.l_type = tswap16(target_fl->l_type);
5593 fl.l_whence = tswap16(target_fl->l_whence);
5594 fl.l_start = tswap64(target_fl->l_start);
5595 fl.l_len = tswap64(target_fl->l_len);
5596 fl.l_pid = tswapl(target_fl->l_pid);
5597 unlock_user_struct(target_fl, arg3, 0);
5599 ret = get_errno(fcntl(arg1, cmd, &fl));
5600 if (ret == 0) {
5601 #ifdef TARGET_ARM
5602 if (((CPUARMState *)cpu_env)->eabi) {
5603 if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0))
5604 goto efault;
5605 target_efl->l_type = tswap16(fl.l_type);
5606 target_efl->l_whence = tswap16(fl.l_whence);
5607 target_efl->l_start = tswap64(fl.l_start);
5608 target_efl->l_len = tswap64(fl.l_len);
5609 target_efl->l_pid = tswapl(fl.l_pid);
5610 unlock_user_struct(target_efl, arg3, 1);
5611 } else
5612 #endif
5614 if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0))
5615 goto efault;
5616 target_fl->l_type = tswap16(fl.l_type);
5617 target_fl->l_whence = tswap16(fl.l_whence);
5618 target_fl->l_start = tswap64(fl.l_start);
5619 target_fl->l_len = tswap64(fl.l_len);
5620 target_fl->l_pid = tswapl(fl.l_pid);
5621 unlock_user_struct(target_fl, arg3, 1);
5624 break;
5626 case TARGET_F_SETLK64:
5627 case TARGET_F_SETLKW64:
5628 #ifdef TARGET_ARM
5629 if (((CPUARMState *)cpu_env)->eabi) {
5630 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1))
5631 goto efault;
5632 fl.l_type = tswap16(target_efl->l_type);
5633 fl.l_whence = tswap16(target_efl->l_whence);
5634 fl.l_start = tswap64(target_efl->l_start);
5635 fl.l_len = tswap64(target_efl->l_len);
5636 fl.l_pid = tswapl(target_efl->l_pid);
5637 unlock_user_struct(target_efl, arg3, 0);
5638 } else
5639 #endif
5641 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1))
5642 goto efault;
5643 fl.l_type = tswap16(target_fl->l_type);
5644 fl.l_whence = tswap16(target_fl->l_whence);
5645 fl.l_start = tswap64(target_fl->l_start);
5646 fl.l_len = tswap64(target_fl->l_len);
5647 fl.l_pid = tswapl(target_fl->l_pid);
5648 unlock_user_struct(target_fl, arg3, 0);
5650 ret = get_errno(fcntl(arg1, cmd, &fl));
5651 break;
5652 default:
5653 ret = do_fcntl(arg1, cmd, arg3);
5654 break;
5656 break;
5658 #endif
5659 #ifdef TARGET_NR_cacheflush
5660 case TARGET_NR_cacheflush:
5661 /* self-modifying code is handled automatically, so nothing needed */
5662 ret = 0;
5663 break;
5664 #endif
5665 #ifdef TARGET_NR_security
5666 case TARGET_NR_security:
5667 goto unimplemented;
5668 #endif
5669 #ifdef TARGET_NR_getpagesize
5670 case TARGET_NR_getpagesize:
5671 ret = TARGET_PAGE_SIZE;
5672 break;
5673 #endif
5674 case TARGET_NR_gettid:
5675 ret = get_errno(gettid());
5676 break;
5677 #ifdef TARGET_NR_readahead
5678 case TARGET_NR_readahead:
5679 goto unimplemented;
5680 #endif
5681 #ifdef TARGET_NR_setxattr
5682 case TARGET_NR_setxattr:
5683 case TARGET_NR_lsetxattr:
5684 case TARGET_NR_fsetxattr:
5685 case TARGET_NR_getxattr:
5686 case TARGET_NR_lgetxattr:
5687 case TARGET_NR_fgetxattr:
5688 case TARGET_NR_listxattr:
5689 case TARGET_NR_llistxattr:
5690 case TARGET_NR_flistxattr:
5691 case TARGET_NR_removexattr:
5692 case TARGET_NR_lremovexattr:
5693 case TARGET_NR_fremovexattr:
5694 goto unimplemented_nowarn;
5695 #endif
5696 #ifdef TARGET_NR_set_thread_area
5697 case TARGET_NR_set_thread_area:
5698 #if defined(TARGET_MIPS)
5699 ((CPUMIPSState *) cpu_env)->tls_value = arg1;
5700 ret = 0;
5701 break;
5702 #elif defined(TARGET_I386) && defined(TARGET_ABI32)
5703 ret = do_set_thread_area(cpu_env, arg1);
5704 break;
5705 #else
5706 goto unimplemented_nowarn;
5707 #endif
5708 #endif
5709 #ifdef TARGET_NR_get_thread_area
5710 case TARGET_NR_get_thread_area:
5711 #if defined(TARGET_I386) && defined(TARGET_ABI32)
5712 ret = do_get_thread_area(cpu_env, arg1);
5713 #else
5714 goto unimplemented_nowarn;
5715 #endif
5716 #endif
5717 #ifdef TARGET_NR_getdomainname
5718 case TARGET_NR_getdomainname:
5719 goto unimplemented_nowarn;
5720 #endif
5722 #ifdef TARGET_NR_clock_gettime
5723 case TARGET_NR_clock_gettime:
5725 struct timespec ts;
5726 ret = get_errno(clock_gettime(arg1, &ts));
5727 if (!is_error(ret)) {
5728 host_to_target_timespec(arg2, &ts);
5730 break;
5732 #endif
5733 #ifdef TARGET_NR_clock_getres
5734 case TARGET_NR_clock_getres:
5736 struct timespec ts;
5737 ret = get_errno(clock_getres(arg1, &ts));
5738 if (!is_error(ret)) {
5739 host_to_target_timespec(arg2, &ts);
5741 break;
5743 #endif
5744 #ifdef TARGET_NR_clock_nanosleep
5745 case TARGET_NR_clock_nanosleep:
5747 struct timespec ts;
5748 target_to_host_timespec(&ts, arg3);
5749 ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
5750 if (arg4)
5751 host_to_target_timespec(arg4, &ts);
5752 break;
5754 #endif
5756 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
5757 case TARGET_NR_set_tid_address:
5758 ret = get_errno(set_tid_address((int *)g2h(arg1)));
5759 break;
5760 #endif
5762 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
5763 case TARGET_NR_tkill:
5764 ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
5765 break;
5766 #endif
5768 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
5769 case TARGET_NR_tgkill:
5770 ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
5771 target_to_host_signal(arg3)));
5772 break;
5773 #endif
5775 #ifdef TARGET_NR_set_robust_list
5776 case TARGET_NR_set_robust_list:
5777 goto unimplemented_nowarn;
5778 #endif
5780 #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
5781 case TARGET_NR_utimensat:
5783 struct timespec ts[2];
5784 target_to_host_timespec(ts, arg3);
5785 target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
5786 if (!arg2)
5787 ret = get_errno(sys_utimensat(arg1, NULL, ts, arg4));
5788 else {
5789 if (!(p = lock_user_string(arg2))) {
5790 ret = -TARGET_EFAULT;
5791 goto fail;
5793 ret = get_errno(sys_utimensat(arg1, path(p), ts, arg4));
5794 unlock_user(p, arg2, 0);
5797 break;
5798 #endif
5799 #if defined(USE_NPTL)
5800 case TARGET_NR_futex:
5801 ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
5802 break;
5803 #endif
5805 default:
5806 unimplemented:
5807 gemu_log("qemu: Unsupported syscall: %d\n", num);
5808 #if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
5809 unimplemented_nowarn:
5810 #endif
5811 ret = -TARGET_ENOSYS;
5812 break;
5814 fail:
5815 #ifdef DEBUG
5816 gemu_log(" = %ld\n", ret);
5817 #endif
5818 if(do_strace)
5819 print_syscall_ret(num, ret);
5820 return ret;
5821 efault:
5822 ret = -TARGET_EFAULT;
5823 goto fail;