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