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