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