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