rtoss - Blame information for rev 79

Subversion Repositories:
Rev:
Rev Author Line No. Line
76 roytam 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 <sys/types.h>
32 #include <sys/ipc.h>
33 #include <sys/msg.h>
34 #include <sys/wait.h>
35 #include <sys/time.h>
36 #include <sys/stat.h>
37 #include <sys/mount.h>
38 #include <sys/prctl.h>
39 #include <sys/resource.h>
40 #include <sys/mman.h>
41 #include <sys/swap.h>
42 #include <signal.h>
43 #include <sched.h>
44 #include <sys/socket.h>
45 #include <sys/un.h>
46 #include <sys/uio.h>
47 #include <sys/poll.h>
48 #include <sys/times.h>
49 #include <sys/shm.h>
50 #include <sys/sem.h>
51 #include <sys/statfs.h>
52 #include <utime.h>
53 #include <sys/sysinfo.h>
54 #include <sys/utsname.h>
55 //#include <sys/user.h>
56 #include <netinet/ip.h>
57 #include <netinet/tcp.h>
58 #include <qemu-common.h>
59 #ifdef TARGET_GPROF
60 #include <sys/gmon.h>
61 #endif
62 #ifdef CONFIG_EVENTFD
63 #include <sys/eventfd.h>
64 #endif
65  
66 #define termios host_termios
67 #define winsize host_winsize
68 #define termio host_termio
69 #define sgttyb host_sgttyb /* same as target */
70 #define tchars host_tchars /* same as target */
71 #define ltchars host_ltchars /* same as target */
72  
73 #include <linux/termios.h>
74 #include <linux/unistd.h>
75 #include <linux/utsname.h>
76 #include <linux/cdrom.h>
77 #include <linux/hdreg.h>
78 #include <linux/soundcard.h>
79 #include <linux/kd.h>
80 #include <linux/mtio.h>
81 #include <linux/fs.h>
79 roytam 82 #include <linux/fb.h>
83 #include <linux/vt.h>
76 roytam 84 #include "linux_loop.h"
85  
86 #include "qemu.h"
87 #include "qemu-common.h"
88  
89 #if defined(CONFIG_USE_NPTL)
90 #define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
91     CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
92 #else
93 /* XXX: Hardcode the above values.  */
94 #define CLONE_NPTL_FLAGS2 0
95 #endif
96  
97 //#define DEBUG
98  
99 //#include <linux/msdos_fs.h>
100 #define VFAT_IOCTL_READDIR_BOTH         _IOR('r', 1, struct linux_dirent [2])
101 #define VFAT_IOCTL_READDIR_SHORT        _IOR('r', 2, struct linux_dirent [2])
102  
103  
104 #undef _syscall0
105 #undef _syscall1
106 #undef _syscall2
107 #undef _syscall3
108 #undef _syscall4
109 #undef _syscall5
110 #undef _syscall6
111  
112 #define _syscall0(type,name)            \
113 static type name (void)                 \
114 {                                       \
115         return syscall(__NR_##name);    \
116 }
117  
118 #define _syscall1(type,name,type1,arg1)         \
119 static type name (type1 arg1)                   \
120 {                                               \
121         return syscall(__NR_##name, arg1);      \
122 }
123  
124 #define _syscall2(type,name,type1,arg1,type2,arg2)      \
125 static type name (type1 arg1,type2 arg2)                \
126 {                                                       \
127         return syscall(__NR_##name, arg1, arg2);        \
128 }
129  
130 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)   \
131 static type name (type1 arg1,type2 arg2,type3 arg3)             \
132 {                                                               \
133         return syscall(__NR_##name, arg1, arg2, arg3);          \
134 }
135  
136 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)        \
137 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4)                  \
138 {                                                                               \
139         return syscall(__NR_##name, arg1, arg2, arg3, arg4);                    \
140 }
141  
142 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,        \
143                   type5,arg5)                                                   \
144 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5)       \
145 {                                                                               \
146         return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5);              \
147 }
148  
149  
150 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,        \
151                   type5,arg5,type6,arg6)                                        \
152 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,       \
153                   type6 arg6)                                                   \
154 {                                                                               \
155         return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6);        \
156 }
157  
158  
159 #define __NR_sys_uname __NR_uname
160 #define __NR_sys_faccessat __NR_faccessat
161 #define __NR_sys_fchmodat __NR_fchmodat
162 #define __NR_sys_fchownat __NR_fchownat
163 #define __NR_sys_fstatat64 __NR_fstatat64
164 #define __NR_sys_futimesat __NR_futimesat
165 #define __NR_sys_getcwd1 __NR_getcwd
166 #define __NR_sys_getdents __NR_getdents
167 #define __NR_sys_getdents64 __NR_getdents64
168 #define __NR_sys_getpriority __NR_getpriority
169 #define __NR_sys_linkat __NR_linkat
170 #define __NR_sys_mkdirat __NR_mkdirat
171 #define __NR_sys_mknodat __NR_mknodat
172 #define __NR_sys_newfstatat __NR_newfstatat
173 #define __NR_sys_openat __NR_openat
174 #define __NR_sys_readlinkat __NR_readlinkat
175 #define __NR_sys_renameat __NR_renameat
176 #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
177 #define __NR_sys_symlinkat __NR_symlinkat
178 #define __NR_sys_syslog __NR_syslog
179 #define __NR_sys_tgkill __NR_tgkill
180 #define __NR_sys_tkill __NR_tkill
181 #define __NR_sys_unlinkat __NR_unlinkat
182 #define __NR_sys_utimensat __NR_utimensat
183 #define __NR_sys_futex __NR_futex
184 #define __NR_sys_inotify_init __NR_inotify_init
185 #define __NR_sys_inotify_add_watch __NR_inotify_add_watch
186 #define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
187  
188 #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
189 #define __NR__llseek __NR_lseek
190 #endif
191  
192 #ifdef __NR_gettid
193 _syscall0(int, gettid)
194 #else
195 /* This is a replacement for the host gettid() and must return a host
196    errno. */
197 static int gettid(void) {
198     return -ENOSYS;
199 }
200 #endif
201 _syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
202 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
203 _syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
204 #endif
205 _syscall2(int, sys_getpriority, int, which, int, who);
206 #if defined(TARGET_NR__llseek) && !defined (__x86_64__)
207 _syscall5(int, _llseek,  uint,  fd, ulong, hi, ulong, lo,
208           loff_t *, res, uint, wh);
209 #endif
210 _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
211 _syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
212 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
213 _syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
214 #endif
215 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
216 _syscall2(int,sys_tkill,int,tid,int,sig)
217 #endif
218 #ifdef __NR_exit_group
219 _syscall1(int,exit_group,int,error_code)
220 #endif
221 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
222 _syscall1(int,set_tid_address,int *,tidptr)
223 #endif
224 #if defined(CONFIG_USE_NPTL)
225 #if defined(TARGET_NR_futex) && defined(__NR_futex)
226 _syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
227           const struct timespec *,timeout,int *,uaddr2,int,val3)
228 #endif
229 #endif
230  
231 static bitmask_transtbl fcntl_flags_tbl[] = {
232   { TARGET_O_ACCMODE,   TARGET_O_WRONLY,    O_ACCMODE,   O_WRONLY,    },
233   { TARGET_O_ACCMODE,   TARGET_O_RDWR,      O_ACCMODE,   O_RDWR,      },
234   { TARGET_O_CREAT,     TARGET_O_CREAT,     O_CREAT,     O_CREAT,     },
235   { TARGET_O_EXCL,      TARGET_O_EXCL,      O_EXCL,      O_EXCL,      },
236   { TARGET_O_NOCTTY,    TARGET_O_NOCTTY,    O_NOCTTY,    O_NOCTTY,    },
237   { TARGET_O_TRUNC,     TARGET_O_TRUNC,     O_TRUNC,     O_TRUNC,     },
238   { TARGET_O_APPEND,    TARGET_O_APPEND,    O_APPEND,    O_APPEND,    },
239   { TARGET_O_NONBLOCK,  TARGET_O_NONBLOCK,  O_NONBLOCK,  O_NONBLOCK,  },
240   { TARGET_O_SYNC,      TARGET_O_SYNC,      O_SYNC,      O_SYNC,      },
241   { TARGET_FASYNC,      TARGET_FASYNC,      FASYNC,      FASYNC,      },
242   { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
243   { TARGET_O_NOFOLLOW,  TARGET_O_NOFOLLOW,  O_NOFOLLOW,  O_NOFOLLOW,  },
244   { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
245 #if defined(O_DIRECT)
246   { TARGET_O_DIRECT,    TARGET_O_DIRECT,    O_DIRECT,    O_DIRECT,    },
247 #endif
248   { 0, 0, 0, 0 }
249 };
250  
251 #define COPY_UTSNAME_FIELD(dest, src) \
252   do { \
253       /* __NEW_UTS_LEN doesn't include terminating null */ \
254       (void) strncpy((dest), (src), __NEW_UTS_LEN); \
255       (dest)[__NEW_UTS_LEN] = '\0'; \
256   } while (0)
257  
258 static int sys_uname(struct new_utsname *buf)
259 {
260   struct utsname uts_buf;
261  
262   if (uname(&uts_buf) < 0)
263       return (-1);
264  
265   /*
266    * Just in case these have some differences, we
267    * translate utsname to new_utsname (which is the
268    * struct linux kernel uses).
269    */
270  
271   bzero(buf, sizeof (*buf));
272   COPY_UTSNAME_FIELD(buf->sysname, uts_buf.sysname);
273   COPY_UTSNAME_FIELD(buf->nodename, uts_buf.nodename);
274   COPY_UTSNAME_FIELD(buf->release, uts_buf.release);
275   COPY_UTSNAME_FIELD(buf->version, uts_buf.version);
276   COPY_UTSNAME_FIELD(buf->machine, uts_buf.machine);
277 #ifdef _GNU_SOURCE
278   COPY_UTSNAME_FIELD(buf->domainname, uts_buf.domainname);
279 #endif
280   return (0);
281  
282 #undef COPY_UTSNAME_FIELD
283 }
284  
285 static int sys_getcwd1(char *buf, size_t size)
286 {
287   if (getcwd(buf, size) == NULL) {
288       /* getcwd() sets errno */
289       return (-1);
290   }
291   return strlen(buf)+1;
292 }
293  
294 #ifdef CONFIG_ATFILE
295 /*
296  * Host system seems to have atfile syscall stubs available.  We
297  * now enable them one by one as specified by target syscall_nr.h.
298  */
299  
300 #ifdef TARGET_NR_faccessat
301 static int sys_faccessat(int dirfd, const char *pathname, int mode)
302 {
303   return (faccessat(dirfd, pathname, mode, 0));
304 }
305 #endif
306 #ifdef TARGET_NR_fchmodat
307 static int sys_fchmodat(int dirfd, const char *pathname, mode_t mode)
308 {
309   return (fchmodat(dirfd, pathname, mode, 0));
310 }
311 #endif
312 #if defined(TARGET_NR_fchownat) && defined(USE_UID16)
313 static int sys_fchownat(int dirfd, const char *pathname, uid_t owner,
314     gid_t group, int flags)
315 {
316   return (fchownat(dirfd, pathname, owner, group, flags));
317 }
318 #endif
319 #ifdef __NR_fstatat64
320 static int sys_fstatat64(int dirfd, const char *pathname, struct stat *buf,
321     int flags)
322 {
323   return (fstatat(dirfd, pathname, buf, flags));
324 }
325 #endif
326 #ifdef __NR_newfstatat
327 static int sys_newfstatat(int dirfd, const char *pathname, struct stat *buf,
328     int flags)
329 {
330   return (fstatat(dirfd, pathname, buf, flags));
331 }
332 #endif
333 #ifdef TARGET_NR_futimesat
334 static int sys_futimesat(int dirfd, const char *pathname,
335     const struct timeval times[2])
336 {
337   return (futimesat(dirfd, pathname, times));
338 }
339 #endif
340 #ifdef TARGET_NR_linkat
341 static int sys_linkat(int olddirfd, const char *oldpath,
342     int newdirfd, const char *newpath, int flags)
343 {
344   return (linkat(olddirfd, oldpath, newdirfd, newpath, flags));
345 }
346 #endif
347 #ifdef TARGET_NR_mkdirat
348 static int sys_mkdirat(int dirfd, const char *pathname, mode_t mode)
349 {
350   return (mkdirat(dirfd, pathname, mode));
351 }
352 #endif
353 #ifdef TARGET_NR_mknodat
354 static int sys_mknodat(int dirfd, const char *pathname, mode_t mode,
355     dev_t dev)
356 {
357   return (mknodat(dirfd, pathname, mode, dev));
358 }
359 #endif
360 #ifdef TARGET_NR_openat
361 static int sys_openat(int dirfd, const char *pathname, int flags, ...)
362 {
363   /*
364    * open(2) has extra parameter 'mode' when called with
365    * flag O_CREAT.
366    */
367   if ((flags & O_CREAT) != 0) {
368       va_list ap;
369       mode_t mode;
370  
371       /*
372        * Get the 'mode' parameter and translate it to
373        * host bits.
374        */
375       va_start(ap, flags);
376       mode = va_arg(ap, mode_t);
377       mode = target_to_host_bitmask(mode, fcntl_flags_tbl);
378       va_end(ap);
379  
380       return (openat(dirfd, pathname, flags, mode));
381   }
382   return (openat(dirfd, pathname, flags));
383 }
384 #endif
385 #ifdef TARGET_NR_readlinkat
386 static int sys_readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz)
387 {
388   return (readlinkat(dirfd, pathname, buf, bufsiz));
389 }
390 #endif
391 #ifdef TARGET_NR_renameat
392 static int sys_renameat(int olddirfd, const char *oldpath,
393     int newdirfd, const char *newpath)
394 {
395   return (renameat(olddirfd, oldpath, newdirfd, newpath));
396 }
397 #endif
398 #ifdef TARGET_NR_symlinkat
399 static int sys_symlinkat(const char *oldpath, int newdirfd, const char *newpath)
400 {
401   return (symlinkat(oldpath, newdirfd, newpath));
402 }
403 #endif
404 #ifdef TARGET_NR_unlinkat
405 static int sys_unlinkat(int dirfd, const char *pathname, int flags)
406 {
407   return (unlinkat(dirfd, pathname, flags));
408 }
409 #endif
410 #else /* !CONFIG_ATFILE */
411  
412 /*
413  * Try direct syscalls instead
414  */
415 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
416 _syscall3(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode)
417 #endif
418 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
419 _syscall3(int,sys_fchmodat,int,dirfd,const char *,pathname, mode_t,mode)
420 #endif
421 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) && defined(USE_UID16)
422 _syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
423           uid_t,owner,gid_t,group,int,flags)
424 #endif
425 #if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
426         defined(__NR_fstatat64)
427 _syscall4(int,sys_fstatat64,int,dirfd,const char *,pathname,
428           struct stat *,buf,int,flags)
429 #endif
430 #if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
431 _syscall3(int,sys_futimesat,int,dirfd,const char *,pathname,
432          const struct timeval *,times)
433 #endif
434 #if (defined(TARGET_NR_newfstatat) || defined(TARGET_NR_fstatat64) ) && \
435         defined(__NR_newfstatat)
436 _syscall4(int,sys_newfstatat,int,dirfd,const char *,pathname,
437           struct stat *,buf,int,flags)
438 #endif
439 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
440 _syscall5(int,sys_linkat,int,olddirfd,const char *,oldpath,
441       int,newdirfd,const char *,newpath,int,flags)
442 #endif
443 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
444 _syscall3(int,sys_mkdirat,int,dirfd,const char *,pathname,mode_t,mode)
445 #endif
446 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
447 _syscall4(int,sys_mknodat,int,dirfd,const char *,pathname,
448           mode_t,mode,dev_t,dev)
449 #endif
450 #if defined(TARGET_NR_openat) && defined(__NR_openat)
451 _syscall4(int,sys_openat,int,dirfd,const char *,pathname,int,flags,mode_t,mode)
452 #endif
453 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
454 _syscall4(int,sys_readlinkat,int,dirfd,const char *,pathname,
455           char *,buf,size_t,bufsize)
456 #endif
457 #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
458 _syscall4(int,sys_renameat,int,olddirfd,const char *,oldpath,
459           int,newdirfd,const char *,newpath)
460 #endif
461 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
462 _syscall3(int,sys_symlinkat,const char *,oldpath,
463           int,newdirfd,const char *,newpath)
464 #endif
465 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
466 _syscall3(int,sys_unlinkat,int,dirfd,const char *,pathname,int,flags)
467 #endif
468  
469 #endif /* CONFIG_ATFILE */
470  
471 #ifdef CONFIG_UTIMENSAT
472 static int sys_utimensat(int dirfd, const char *pathname,
473     const struct timespec times[2], int flags)
474 {
475     if (pathname == NULL)
476         return futimens(dirfd, times);
477     else
478         return utimensat(dirfd, pathname, times, flags);
479 }
480 #else
481 #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
482 _syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
483           const struct timespec *,tsp,int,flags)
484 #endif
485 #endif /* CONFIG_UTIMENSAT  */
486  
487 #ifdef CONFIG_INOTIFY
488 #include <sys/inotify.h>
489  
490 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
491 static int sys_inotify_init(void)
492 {
493   return (inotify_init());
494 }
495 #endif
496 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
497 static int sys_inotify_add_watch(int fd,const char *pathname, int32_t mask)
498 {
499   return (inotify_add_watch(fd, pathname, mask));
500 }
501 #endif
502 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
503 static int sys_inotify_rm_watch(int fd, int32_t wd)
504 {
505   return (inotify_rm_watch(fd, wd));
506 }
507 #endif
508 #else
509 /* Userspace can usually survive runtime without inotify */
510 #undef TARGET_NR_inotify_init
511 #undef TARGET_NR_inotify_add_watch
512 #undef TARGET_NR_inotify_rm_watch
513 #endif /* CONFIG_INOTIFY  */
514  
515  
516 extern int personality(int);
517 extern int flock(int, int);
518 extern int setfsuid(int);
519 extern int setfsgid(int);
520 extern int setgroups(int, gid_t *);
521  
522 #define ERRNO_TABLE_SIZE 1200
523  
524 /* target_to_host_errno_table[] is initialized from
525  * host_to_target_errno_table[] in syscall_init(). */
526 static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
527 };
528  
529 /*
530  * This list is the union of errno values overridden in asm-<arch>/errno.h
531  * minus the errnos that are not actually generic to all archs.
532  */
533 static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
534     [EIDRM]             = TARGET_EIDRM,
535     [ECHRNG]            = TARGET_ECHRNG,
536     [EL2NSYNC]          = TARGET_EL2NSYNC,
537     [EL3HLT]            = TARGET_EL3HLT,
538     [EL3RST]            = TARGET_EL3RST,
539     [ELNRNG]            = TARGET_ELNRNG,
540     [EUNATCH]           = TARGET_EUNATCH,
541     [ENOCSI]            = TARGET_ENOCSI,
542     [EL2HLT]            = TARGET_EL2HLT,
543     [EDEADLK]           = TARGET_EDEADLK,
544     [ENOLCK]            = TARGET_ENOLCK,
545     [EBADE]             = TARGET_EBADE,
546     [EBADR]             = TARGET_EBADR,
547     [EXFULL]            = TARGET_EXFULL,
548     [ENOANO]            = TARGET_ENOANO,
549     [EBADRQC]           = TARGET_EBADRQC,
550     [EBADSLT]           = TARGET_EBADSLT,
551     [EBFONT]            = TARGET_EBFONT,
552     [ENOSTR]            = TARGET_ENOSTR,
553     [ENODATA]           = TARGET_ENODATA,
554     [ETIME]             = TARGET_ETIME,
555     [ENOSR]             = TARGET_ENOSR,
556     [ENONET]            = TARGET_ENONET,
557     [ENOPKG]            = TARGET_ENOPKG,
558     [EREMOTE]           = TARGET_EREMOTE,
559     [ENOLINK]           = TARGET_ENOLINK,
560     [EADV]              = TARGET_EADV,
561     [ESRMNT]            = TARGET_ESRMNT,
562     [ECOMM]             = TARGET_ECOMM,
563     [EPROTO]            = TARGET_EPROTO,
564     [EDOTDOT]           = TARGET_EDOTDOT,
565     [EMULTIHOP]         = TARGET_EMULTIHOP,
566     [EBADMSG]           = TARGET_EBADMSG,
567     [ENAMETOOLONG]      = TARGET_ENAMETOOLONG,
568     [EOVERFLOW]         = TARGET_EOVERFLOW,
569     [ENOTUNIQ]          = TARGET_ENOTUNIQ,
570     [EBADFD]            = TARGET_EBADFD,
571     [EREMCHG]           = TARGET_EREMCHG,
572     [ELIBACC]           = TARGET_ELIBACC,
573     [ELIBBAD]           = TARGET_ELIBBAD,
574     [ELIBSCN]           = TARGET_ELIBSCN,
575     [ELIBMAX]           = TARGET_ELIBMAX,
576     [ELIBEXEC]          = TARGET_ELIBEXEC,
577     [EILSEQ]            = TARGET_EILSEQ,
578     [ENOSYS]            = TARGET_ENOSYS,
579     [ELOOP]             = TARGET_ELOOP,
580     [ERESTART]          = TARGET_ERESTART,
581     [ESTRPIPE]          = TARGET_ESTRPIPE,
582     [ENOTEMPTY]         = TARGET_ENOTEMPTY,
583     [EUSERS]            = TARGET_EUSERS,
584     [ENOTSOCK]          = TARGET_ENOTSOCK,
585     [EDESTADDRREQ]      = TARGET_EDESTADDRREQ,
586     [EMSGSIZE]          = TARGET_EMSGSIZE,
587     [EPROTOTYPE]        = TARGET_EPROTOTYPE,
588     [ENOPROTOOPT]       = TARGET_ENOPROTOOPT,
589     [EPROTONOSUPPORT]   = TARGET_EPROTONOSUPPORT,
590     [ESOCKTNOSUPPORT]   = TARGET_ESOCKTNOSUPPORT,
591     [EOPNOTSUPP]        = TARGET_EOPNOTSUPP,
592     [EPFNOSUPPORT]      = TARGET_EPFNOSUPPORT,
593     [EAFNOSUPPORT]      = TARGET_EAFNOSUPPORT,
594     [EADDRINUSE]        = TARGET_EADDRINUSE,
595     [EADDRNOTAVAIL]     = TARGET_EADDRNOTAVAIL,
596     [ENETDOWN]          = TARGET_ENETDOWN,
597     [ENETUNREACH]       = TARGET_ENETUNREACH,
598     [ENETRESET]         = TARGET_ENETRESET,
599     [ECONNABORTED]      = TARGET_ECONNABORTED,
600     [ECONNRESET]        = TARGET_ECONNRESET,
601     [ENOBUFS]           = TARGET_ENOBUFS,
602     [EISCONN]           = TARGET_EISCONN,
603     [ENOTCONN]          = TARGET_ENOTCONN,
604     [EUCLEAN]           = TARGET_EUCLEAN,
605     [ENOTNAM]           = TARGET_ENOTNAM,
606     [ENAVAIL]           = TARGET_ENAVAIL,
607     [EISNAM]            = TARGET_EISNAM,
608     [EREMOTEIO]         = TARGET_EREMOTEIO,
609     [ESHUTDOWN]         = TARGET_ESHUTDOWN,
610     [ETOOMANYREFS]      = TARGET_ETOOMANYREFS,
611     [ETIMEDOUT]         = TARGET_ETIMEDOUT,
612     [ECONNREFUSED]      = TARGET_ECONNREFUSED,
613     [EHOSTDOWN]         = TARGET_EHOSTDOWN,
614     [EHOSTUNREACH]      = TARGET_EHOSTUNREACH,
615     [EALREADY]          = TARGET_EALREADY,
616     [EINPROGRESS]       = TARGET_EINPROGRESS,
617     [ESTALE]            = TARGET_ESTALE,
618     [ECANCELED]         = TARGET_ECANCELED,
619     [ENOMEDIUM]         = TARGET_ENOMEDIUM,
620     [EMEDIUMTYPE]       = TARGET_EMEDIUMTYPE,
621 #ifdef ENOKEY
622     [ENOKEY]            = TARGET_ENOKEY,
623 #endif
624 #ifdef EKEYEXPIRED
625     [EKEYEXPIRED]       = TARGET_EKEYEXPIRED,
626 #endif
627 #ifdef EKEYREVOKED
628     [EKEYREVOKED]       = TARGET_EKEYREVOKED,
629 #endif
630 #ifdef EKEYREJECTED
631     [EKEYREJECTED]      = TARGET_EKEYREJECTED,
632 #endif
633 #ifdef EOWNERDEAD
634     [EOWNERDEAD]        = TARGET_EOWNERDEAD,
635 #endif
636 #ifdef ENOTRECOVERABLE
637     [ENOTRECOVERABLE]   = TARGET_ENOTRECOVERABLE,
638 #endif
639 };
640  
641 static inline int host_to_target_errno(int err)
642 {
643     if(host_to_target_errno_table[err])
644         return host_to_target_errno_table[err];
645     return err;
646 }
647  
648 static inline int target_to_host_errno(int err)
649 {
650     if (target_to_host_errno_table[err])
651         return target_to_host_errno_table[err];
652     return err;
653 }
654  
655 static inline abi_long get_errno(abi_long ret)
656 {
657     if (ret == -1)
658         return -host_to_target_errno(errno);
659     else
660         return ret;
661 }
662  
663 static inline int is_error(abi_long ret)
664 {
665     return (abi_ulong)ret >= (abi_ulong)(-4096);
666 }
667  
668 char *target_strerror(int err)
669 {
670     return strerror(target_to_host_errno(err));
671 }
672  
673 static abi_ulong target_brk;
674 static abi_ulong target_original_brk;
675  
676 void target_set_brk(abi_ulong new_brk)
677 {
678     target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
679 }
680  
681 /* do_brk() must return target values and target errnos. */
682 abi_long do_brk(abi_ulong new_brk)
683 {
684     abi_ulong brk_page;
685     abi_long mapped_addr;
686     int new_alloc_size;
687  
688     if (!new_brk)
689         return target_brk;
690     if (new_brk < target_original_brk)
691         return target_brk;
692  
693     brk_page = HOST_PAGE_ALIGN(target_brk);
694  
695     /* If the new brk is less than this, set it and we're done... */
696     if (new_brk < brk_page) {
697         target_brk = new_brk;
698         return target_brk;
699     }
700  
701     /* We need to allocate more memory after the brk... */
702     new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
703     mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
704                                         PROT_READ|PROT_WRITE,
705                                         MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
706  
707     if (!is_error(mapped_addr))
708         target_brk = new_brk;
709  
710     return target_brk;
711 }
712  
713 static inline abi_long copy_from_user_fdset(fd_set *fds,
714                                             abi_ulong target_fds_addr,
715                                             int n)
716 {
717     int i, nw, j, k;
718     abi_ulong b, *target_fds;
719  
720     nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
721     if (!(target_fds = lock_user(VERIFY_READ,
722                                  target_fds_addr,
723                                  sizeof(abi_ulong) * nw,
724                                  1)))
725         return -TARGET_EFAULT;
726  
727     FD_ZERO(fds);
728     k = 0;
729     for (i = 0; i < nw; i++) {
730         /* grab the abi_ulong */
731         __get_user(b, &target_fds[i]);
732         for (j = 0; j < TARGET_ABI_BITS; j++) {
733             /* check the bit inside the abi_ulong */
734             if ((b >> j) & 1)
735                 FD_SET(k, fds);
736             k++;
737         }
738     }
739  
740     unlock_user(target_fds, target_fds_addr, 0);
741  
742     return 0;
743 }
744  
745 static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
746                                           const fd_set *fds,
747                                           int n)
748 {
749     int i, nw, j, k;
750     abi_long v;
751     abi_ulong *target_fds;
752  
753     nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
754     if (!(target_fds = lock_user(VERIFY_WRITE,
755                                  target_fds_addr,
756                                  sizeof(abi_ulong) * nw,
757                                  0)))
758         return -TARGET_EFAULT;
759  
760     k = 0;
761     for (i = 0; i < nw; i++) {
762         v = 0;
763         for (j = 0; j < TARGET_ABI_BITS; j++) {
764             v |= ((FD_ISSET(k, fds) != 0) << j);
765             k++;
766         }
767         __put_user(v, &target_fds[i]);
768     }
769  
770     unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
771  
772     return 0;
773 }
774  
775 #if defined(__alpha__)
776 #define HOST_HZ 1024
777 #else
778 #define HOST_HZ 100
779 #endif
780  
781 static inline abi_long host_to_target_clock_t(long ticks)
782 {
783 #if HOST_HZ == TARGET_HZ
784     return ticks;
785 #else
786     return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
787 #endif
788 }
789  
790 static inline abi_long host_to_target_rusage(abi_ulong target_addr,
791                                              const struct rusage *rusage)
792 {
793     struct target_rusage *target_rusage;
794  
795     if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
796         return -TARGET_EFAULT;
797     target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
798     target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
799     target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
800     target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec);
801     target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss);
802     target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss);
803     target_rusage->ru_idrss = tswapl(rusage->ru_idrss);
804     target_rusage->ru_isrss = tswapl(rusage->ru_isrss);
805     target_rusage->ru_minflt = tswapl(rusage->ru_minflt);
806     target_rusage->ru_majflt = tswapl(rusage->ru_majflt);
807     target_rusage->ru_nswap = tswapl(rusage->ru_nswap);
808     target_rusage->ru_inblock = tswapl(rusage->ru_inblock);
809     target_rusage->ru_oublock = tswapl(rusage->ru_oublock);
810     target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd);
811     target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv);
812     target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);
813     target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
814     target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
815     unlock_user_struct(target_rusage, target_addr, 1);
816  
817     return 0;
818 }
819  
820 static inline abi_long copy_from_user_timeval(struct timeval *tv,
821                                               abi_ulong target_tv_addr)
822 {
823     struct target_timeval *target_tv;
824  
825     if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
826         return -TARGET_EFAULT;
827  
828     __get_user(tv->tv_sec, &target_tv->tv_sec);
829     __get_user(tv->tv_usec, &target_tv->tv_usec);
830  
831     unlock_user_struct(target_tv, target_tv_addr, 0);
832  
833     return 0;
834 }
835  
836 static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
837                                             const struct timeval *tv)
838 {
839     struct target_timeval *target_tv;
840  
841     if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
842         return -TARGET_EFAULT;
843  
844     __put_user(tv->tv_sec, &target_tv->tv_sec);
845     __put_user(tv->tv_usec, &target_tv->tv_usec);
846  
847     unlock_user_struct(target_tv, target_tv_addr, 1);
848  
849     return 0;
850 }
851  
852 #if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
853 #include <mqueue.h>
854  
855 static inline abi_long copy_from_user_mq_attr(struct mq_attr *attr,
856                                               abi_ulong target_mq_attr_addr)
857 {
858     struct target_mq_attr *target_mq_attr;
859  
860     if (!lock_user_struct(VERIFY_READ, target_mq_attr,
861                           target_mq_attr_addr, 1))
862         return -TARGET_EFAULT;
863  
864     __get_user(attr->mq_flags, &target_mq_attr->mq_flags);
865     __get_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
866     __get_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
867     __get_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
868  
869     unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0);
870  
871     return 0;
872 }
873  
874 static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr,
875                                             const struct mq_attr *attr)
876 {
877     struct target_mq_attr *target_mq_attr;
878  
879     if (!lock_user_struct(VERIFY_WRITE, target_mq_attr,
880                           target_mq_attr_addr, 0))
881         return -TARGET_EFAULT;
882  
883     __put_user(attr->mq_flags, &target_mq_attr->mq_flags);
884     __put_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
885     __put_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
886     __put_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
887  
888     unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1);
889  
890     return 0;
891 }
892 #endif
893  
894 /* do_select() must return target values and target errnos. */
895 static abi_long do_select(int n,
896                           abi_ulong rfd_addr, abi_ulong wfd_addr,
897                           abi_ulong efd_addr, abi_ulong target_tv_addr)
898 {
899     fd_set rfds, wfds, efds;
900     fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
901     struct timeval tv, *tv_ptr;
902     abi_long ret;
903  
904     if (rfd_addr) {
905         if (copy_from_user_fdset(&rfds, rfd_addr, n))
906             return -TARGET_EFAULT;
907         rfds_ptr = &rfds;
908     } else {
909         rfds_ptr = NULL;
910     }
911     if (wfd_addr) {
912         if (copy_from_user_fdset(&wfds, wfd_addr, n))
913             return -TARGET_EFAULT;
914         wfds_ptr = &wfds;
915     } else {
916         wfds_ptr = NULL;
917     }
918     if (efd_addr) {
919         if (copy_from_user_fdset(&efds, efd_addr, n))
920             return -TARGET_EFAULT;
921         efds_ptr = &efds;
922     } else {
923         efds_ptr = NULL;
924     }
925  
926     if (target_tv_addr) {
927         if (copy_from_user_timeval(&tv, target_tv_addr))
928             return -TARGET_EFAULT;
929         tv_ptr = &tv;
930     } else {
931         tv_ptr = NULL;
932     }
933  
934     ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
935  
936     if (!is_error(ret)) {
937         if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
938             return -TARGET_EFAULT;
939         if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
940             return -TARGET_EFAULT;
941         if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
942             return -TARGET_EFAULT;
943  
944         if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
945             return -TARGET_EFAULT;
946     }
947  
948     return ret;
949 }
950  
951 static abi_long do_pipe2(int host_pipe[], int flags)
952 {
953 #ifdef CONFIG_PIPE2
954     return pipe2(host_pipe, flags);
955 #else
956     return -ENOSYS;
957 #endif
958 }
959  
960 static abi_long do_pipe(void *cpu_env, abi_ulong pipedes, int flags)
961 {
962     int host_pipe[2];
963     abi_long ret;
964     ret = flags ? do_pipe2(host_pipe, flags) : pipe(host_pipe);
965  
966     if (is_error(ret))
967         return get_errno(ret);
968 #if defined(TARGET_MIPS)
969     ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1];
970     ret = host_pipe[0];
971 #elif defined(TARGET_SH4)
972     ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
973     ret = host_pipe[0];
974 #else
975     if (put_user_s32(host_pipe[0], pipedes)
976         || put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0])))
977         return -TARGET_EFAULT;
978 #endif
979     return get_errno(ret);
980 }
981  
982 static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn,
983                                               abi_ulong target_addr,
984                                               socklen_t len)
985 {
986     struct target_ip_mreqn *target_smreqn;
987  
988     target_smreqn = lock_user(VERIFY_READ, target_addr, len, 1);
989     if (!target_smreqn)
990         return -TARGET_EFAULT;
991     mreqn->imr_multiaddr.s_addr = target_smreqn->imr_multiaddr.s_addr;
992     mreqn->imr_address.s_addr = target_smreqn->imr_address.s_addr;
993     if (len == sizeof(struct target_ip_mreqn))
994         mreqn->imr_ifindex = tswapl(target_smreqn->imr_ifindex);
995     unlock_user(target_smreqn, target_addr, 0);
996  
997     return 0;
998 }
999  
1000 static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
1001                                                abi_ulong target_addr,
1002                                                socklen_t len)
1003 {
1004     const socklen_t unix_maxlen = sizeof (struct sockaddr_un);
1005     sa_family_t sa_family;
1006     struct target_sockaddr *target_saddr;
1007  
1008     target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
1009     if (!target_saddr)
1010         return -TARGET_EFAULT;
1011  
1012     sa_family = tswap16(target_saddr->sa_family);
1013  
1014     /* Oops. The caller might send a incomplete sun_path; sun_path
1015      * must be terminated by \0 (see the manual page), but
1016      * unfortunately it is quite common to specify sockaddr_un
1017      * length as "strlen(x->sun_path)" while it should be
1018      * "strlen(...) + 1". We'll fix that here if needed.
1019      * Linux kernel has a similar feature.
1020      */
1021  
1022     if (sa_family == AF_UNIX) {
1023         if (len < unix_maxlen && len > 0) {
1024             char *cp = (char*)target_saddr;
1025  
1026             if ( cp[len-1] && !cp[len] )
1027                 len++;
1028         }
1029         if (len > unix_maxlen)
1030             len = unix_maxlen;
1031     }
1032  
1033     memcpy(addr, target_saddr, len);
1034     addr->sa_family = sa_family;
1035     unlock_user(target_saddr, target_addr, 0);
1036  
1037     return 0;
1038 }
1039  
1040 static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
1041                                                struct sockaddr *addr,
1042                                                socklen_t len)
1043 {
1044     struct target_sockaddr *target_saddr;
1045  
1046     target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
1047     if (!target_saddr)
1048         return -TARGET_EFAULT;
1049     memcpy(target_saddr, addr, len);
1050     target_saddr->sa_family = tswap16(addr->sa_family);
1051     unlock_user(target_saddr, target_addr, len);
1052  
1053     return 0;
1054 }
1055  
1056 /* ??? Should this also swap msgh->name?  */
1057 static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
1058                                            struct target_msghdr *target_msgh)
1059 {
1060     struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1061     abi_long msg_controllen;
1062     abi_ulong target_cmsg_addr;
1063     struct target_cmsghdr *target_cmsg;
1064     socklen_t space = 0;
1065  
1066     msg_controllen = tswapl(target_msgh->msg_controllen);
1067     if (msg_controllen < sizeof (struct target_cmsghdr))
1068         goto the_end;
1069     target_cmsg_addr = tswapl(target_msgh->msg_control);
1070     target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
1071     if (!target_cmsg)
1072         return -TARGET_EFAULT;
1073  
1074     while (cmsg && target_cmsg) {
1075         void *data = CMSG_DATA(cmsg);
1076         void *target_data = TARGET_CMSG_DATA(target_cmsg);
1077  
1078         int len = tswapl(target_cmsg->cmsg_len)
1079                   - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
1080  
1081         space += CMSG_SPACE(len);
1082         if (space > msgh->msg_controllen) {
1083             space -= CMSG_SPACE(len);
1084             gemu_log("Host cmsg overflow\n");
1085             break;
1086         }
1087  
1088         cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
1089         cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
1090         cmsg->cmsg_len = CMSG_LEN(len);
1091  
1092         if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1093             gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1094             memcpy(data, target_data, len);
1095         } else {
1096             int *fd = (int *)data;
1097             int *target_fd = (int *)target_data;
1098             int i, numfds = len / sizeof(int);
1099  
1100             for (i = 0; i < numfds; i++)
1101                 fd[i] = tswap32(target_fd[i]);
1102         }
1103  
1104         cmsg = CMSG_NXTHDR(msgh, cmsg);
1105         target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1106     }
1107     unlock_user(target_cmsg, target_cmsg_addr, 0);
1108  the_end:
1109     msgh->msg_controllen = space;
1110     return 0;
1111 }
1112  
1113 /* ??? Should this also swap msgh->name?  */
1114 static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
1115                                            struct msghdr *msgh)
1116 {
1117     struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1118     abi_long msg_controllen;
1119     abi_ulong target_cmsg_addr;
1120     struct target_cmsghdr *target_cmsg;
1121     socklen_t space = 0;
1122  
1123     msg_controllen = tswapl(target_msgh->msg_controllen);
1124     if (msg_controllen < sizeof (struct target_cmsghdr))
1125         goto the_end;
1126     target_cmsg_addr = tswapl(target_msgh->msg_control);
1127     target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
1128     if (!target_cmsg)
1129         return -TARGET_EFAULT;
1130  
1131     while (cmsg && target_cmsg) {
1132         void *data = CMSG_DATA(cmsg);
1133         void *target_data = TARGET_CMSG_DATA(target_cmsg);
1134  
1135         int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
1136  
1137         space += TARGET_CMSG_SPACE(len);
1138         if (space > msg_controllen) {
1139             space -= TARGET_CMSG_SPACE(len);
1140             gemu_log("Target cmsg overflow\n");
1141             break;
1142         }
1143  
1144         target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
1145         target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
1146         target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
1147  
1148         if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1149             gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1150             memcpy(target_data, data, len);
1151         } else {
1152             int *fd = (int *)data;
1153             int *target_fd = (int *)target_data;
1154             int i, numfds = len / sizeof(int);
1155  
1156             for (i = 0; i < numfds; i++)
1157                 target_fd[i] = tswap32(fd[i]);
1158         }
1159  
1160         cmsg = CMSG_NXTHDR(msgh, cmsg);
1161         target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1162     }
1163     unlock_user(target_cmsg, target_cmsg_addr, space);
1164  the_end:
1165     target_msgh->msg_controllen = tswapl(space);
1166     return 0;
1167 }
1168  
1169 /* do_setsockopt() Must return target values and target errnos. */
1170 static abi_long do_setsockopt(int sockfd, int level, int optname,
1171                               abi_ulong optval_addr, socklen_t optlen)
1172 {
1173     abi_long ret;
1174     int val;
1175     struct ip_mreqn *ip_mreq;
1176     struct ip_mreq_source *ip_mreq_source;
1177  
1178     switch(level) {
1179     case SOL_TCP:
1180         /* TCP options all take an 'int' value.  */
1181         if (optlen < sizeof(uint32_t))
1182             return -TARGET_EINVAL;
1183  
1184         if (get_user_u32(val, optval_addr))
1185             return -TARGET_EFAULT;
1186         ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1187         break;
1188     case SOL_IP:
1189         switch(optname) {
1190         case IP_TOS:
1191         case IP_TTL:
1192         case IP_HDRINCL:
1193         case IP_ROUTER_ALERT:
1194         case IP_RECVOPTS:
1195         case IP_RETOPTS:
1196         case IP_PKTINFO:
1197         case IP_MTU_DISCOVER:
1198         case IP_RECVERR:
1199         case IP_RECVTOS:
1200 #ifdef IP_FREEBIND
1201         case IP_FREEBIND:
1202 #endif
1203         case IP_MULTICAST_TTL:
1204         case IP_MULTICAST_LOOP:
1205             val = 0;
1206             if (optlen >= sizeof(uint32_t)) {
1207                 if (get_user_u32(val, optval_addr))
1208                     return -TARGET_EFAULT;
1209             } else if (optlen >= 1) {
1210                 if (get_user_u8(val, optval_addr))
1211                     return -TARGET_EFAULT;
1212             }
1213             ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1214             break;
1215         case IP_ADD_MEMBERSHIP:
1216         case IP_DROP_MEMBERSHIP:
1217             if (optlen < sizeof (struct target_ip_mreq) ||
1218                 optlen > sizeof (struct target_ip_mreqn))
1219                 return -TARGET_EINVAL;
1220  
1221             ip_mreq = (struct ip_mreqn *) alloca(optlen);
1222             target_to_host_ip_mreq(ip_mreq, optval_addr, optlen);
1223             ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq, optlen));
1224             break;
1225  
1226         case IP_BLOCK_SOURCE:
1227         case IP_UNBLOCK_SOURCE:
1228         case IP_ADD_SOURCE_MEMBERSHIP:
1229         case IP_DROP_SOURCE_MEMBERSHIP:
1230             if (optlen != sizeof (struct target_ip_mreq_source))
1231                 return -TARGET_EINVAL;
1232  
1233             ip_mreq_source = lock_user(VERIFY_READ, optval_addr, optlen, 1);
1234             ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq_source, optlen));
1235             unlock_user (ip_mreq_source, optval_addr, 0);
1236             break;
1237  
1238         default:
1239             goto unimplemented;
1240         }
1241         break;
1242     case TARGET_SOL_SOCKET:
1243         switch (optname) {
1244             /* Options with 'int' argument.  */
1245         case TARGET_SO_DEBUG:
1246                 optname = SO_DEBUG;
1247                 break;
1248         case TARGET_SO_REUSEADDR:
1249                 optname = SO_REUSEADDR;
1250                 break;
1251         case TARGET_SO_TYPE:
1252                 optname = SO_TYPE;
1253                 break;
1254         case TARGET_SO_ERROR:
1255                 optname = SO_ERROR;
1256                 break;
1257         case TARGET_SO_DONTROUTE:
1258                 optname = SO_DONTROUTE;
1259                 break;
1260         case TARGET_SO_BROADCAST:
1261                 optname = SO_BROADCAST;
1262                 break;
1263         case TARGET_SO_SNDBUF:
1264                 optname = SO_SNDBUF;
1265                 break;
1266         case TARGET_SO_RCVBUF:
1267                 optname = SO_RCVBUF;
1268                 break;
1269         case TARGET_SO_KEEPALIVE:
1270                 optname = SO_KEEPALIVE;
1271                 break;
1272         case TARGET_SO_OOBINLINE:
1273                 optname = SO_OOBINLINE;
1274                 break;
1275         case TARGET_SO_NO_CHECK:
1276                 optname = SO_NO_CHECK;
1277                 break;
1278         case TARGET_SO_PRIORITY:
1279                 optname = SO_PRIORITY;
1280                 break;
1281 #ifdef SO_BSDCOMPAT
1282         case TARGET_SO_BSDCOMPAT:
1283                 optname = SO_BSDCOMPAT;
1284                 break;
1285 #endif
1286         case TARGET_SO_PASSCRED:
1287                 optname = SO_PASSCRED;
1288                 break;
1289         case TARGET_SO_TIMESTAMP:
1290                 optname = SO_TIMESTAMP;
1291                 break;
1292         case TARGET_SO_RCVLOWAT:
1293                 optname = SO_RCVLOWAT;
1294                 break;
1295         case TARGET_SO_RCVTIMEO:
1296                 optname = SO_RCVTIMEO;
1297                 break;
1298         case TARGET_SO_SNDTIMEO:
1299                 optname = SO_SNDTIMEO;
1300                 break;
1301             break;
1302         default:
1303             goto unimplemented;
1304         }
1305         if (optlen < sizeof(uint32_t))
1306             return -TARGET_EINVAL;
1307  
1308         if (get_user_u32(val, optval_addr))
1309             return -TARGET_EFAULT;
1310         ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
1311         break;
1312     default:
1313     unimplemented:
1314         gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
1315         ret = -TARGET_ENOPROTOOPT;
1316     }
1317     return ret;
1318 }
1319  
1320 /* do_getsockopt() Must return target values and target errnos. */
1321 static abi_long do_getsockopt(int sockfd, int level, int optname,
1322                               abi_ulong optval_addr, abi_ulong optlen)
1323 {
1324     abi_long ret;
1325     int len, val;
1326     socklen_t lv;
1327  
1328     switch(level) {
1329     case TARGET_SOL_SOCKET:
1330         level = SOL_SOCKET;
1331         switch (optname) {
1332         case TARGET_SO_LINGER:
1333         case TARGET_SO_RCVTIMEO:
1334         case TARGET_SO_SNDTIMEO:
1335         case TARGET_SO_PEERCRED:
1336         case TARGET_SO_PEERNAME:
1337             /* These don't just return a single integer */
1338             goto unimplemented;
1339         default:
1340             goto int_case;
1341         }
1342         break;
1343     case SOL_TCP:
1344         /* TCP options all take an 'int' value.  */
1345     int_case:
1346         if (get_user_u32(len, optlen))
1347             return -TARGET_EFAULT;
1348         if (len < 0)
1349             return -TARGET_EINVAL;
1350         lv = sizeof(int);
1351         ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1352         if (ret < 0)
1353             return ret;
1354         if (len > lv)
1355             len = lv;
1356         if (len == 4) {
1357             if (put_user_u32(val, optval_addr))
1358                 return -TARGET_EFAULT;
1359         } else {
1360             if (put_user_u8(val, optval_addr))
1361                 return -TARGET_EFAULT;
1362         }
1363         if (put_user_u32(len, optlen))
1364             return -TARGET_EFAULT;
1365         break;
1366     case SOL_IP:
1367         switch(optname) {
1368         case IP_TOS:
1369         case IP_TTL:
1370         case IP_HDRINCL:
1371         case IP_ROUTER_ALERT:
1372         case IP_RECVOPTS:
1373         case IP_RETOPTS:
1374         case IP_PKTINFO:
1375         case IP_MTU_DISCOVER:
1376         case IP_RECVERR:
1377         case IP_RECVTOS:
1378 #ifdef IP_FREEBIND
1379         case IP_FREEBIND:
1380 #endif
1381         case IP_MULTICAST_TTL:
1382         case IP_MULTICAST_LOOP:
1383             if (get_user_u32(len, optlen))
1384                 return -TARGET_EFAULT;
1385             if (len < 0)
1386                 return -TARGET_EINVAL;
1387             lv = sizeof(int);
1388             ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1389             if (ret < 0)
1390                 return ret;
1391             if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
1392                 len = 1;
1393                 if (put_user_u32(len, optlen)
1394                     || put_user_u8(val, optval_addr))
1395                     return -TARGET_EFAULT;
1396             } else {
1397                 if (len > sizeof(int))
1398                     len = sizeof(int);
1399                 if (put_user_u32(len, optlen)
1400                     || put_user_u32(val, optval_addr))
1401                     return -TARGET_EFAULT;
1402             }
1403             break;
1404         default:
1405             ret = -TARGET_ENOPROTOOPT;
1406             break;
1407         }
1408         break;
1409     default:
1410     unimplemented:
1411         gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1412                  level, optname);
1413         ret = -TARGET_EOPNOTSUPP;
1414         break;
1415     }
1416     return ret;
1417 }
1418  
1419 /* FIXME
1420  * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1421  * other lock functions have a return code of 0 for failure.
1422  */
1423 static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1424                            int count, int copy)
1425 {
1426     struct target_iovec *target_vec;
1427     abi_ulong base;
1428     int i;
1429  
1430     target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1431     if (!target_vec)
1432         return -TARGET_EFAULT;
1433     for(i = 0;i < count; i++) {
1434         base = tswapl(target_vec[i].iov_base);
1435         vec[i].iov_len = tswapl(target_vec[i].iov_len);
1436         if (vec[i].iov_len != 0) {
1437             vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
1438             /* Don't check lock_user return value. We must call writev even
1439                if a element has invalid base address. */
1440         } else {
1441             /* zero length pointer is ignored */
1442             vec[i].iov_base = NULL;
1443         }
1444     }
1445     unlock_user (target_vec, target_addr, 0);
1446     return 0;
1447 }
1448  
1449 static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1450                              int count, int copy)
1451 {
1452     struct target_iovec *target_vec;
1453     abi_ulong base;
1454     int i;
1455  
1456     target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1457     if (!target_vec)
1458         return -TARGET_EFAULT;
1459     for(i = 0;i < count; i++) {
1460         if (target_vec[i].iov_base) {
1461             base = tswapl(target_vec[i].iov_base);
1462             unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1463         }
1464     }
1465     unlock_user (target_vec, target_addr, 0);
1466  
1467     return 0;
1468 }
1469  
1470 /* do_socket() Must return target values and target errnos. */
1471 static abi_long do_socket(int domain, int type, int protocol)
1472 {
1473 #if defined(TARGET_MIPS)
1474     switch(type) {
1475     case TARGET_SOCK_DGRAM:
1476         type = SOCK_DGRAM;
1477         break;
1478     case TARGET_SOCK_STREAM:
1479         type = SOCK_STREAM;
1480         break;
1481     case TARGET_SOCK_RAW:
1482         type = SOCK_RAW;
1483         break;
1484     case TARGET_SOCK_RDM:
1485         type = SOCK_RDM;
1486         break;
1487     case TARGET_SOCK_SEQPACKET:
1488         type = SOCK_SEQPACKET;
1489         break;
1490     case TARGET_SOCK_PACKET:
1491         type = SOCK_PACKET;
1492         break;
1493     }
1494 #endif
1495     if (domain == PF_NETLINK)
1496         return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1497     return get_errno(socket(domain, type, protocol));
1498 }
1499  
1500 /* do_bind() Must return target values and target errnos. */
1501 static abi_long do_bind(int sockfd, abi_ulong target_addr,
1502                         socklen_t addrlen)
1503 {
1504     void *addr;
1505     abi_long ret;
1506  
1507     if (addrlen < 0)
1508         return -TARGET_EINVAL;
1509  
1510     addr = alloca(addrlen+1);
1511  
1512     ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1513     if (ret)
1514         return ret;
1515  
1516     return get_errno(bind(sockfd, addr, addrlen));
1517 }
1518  
1519 /* do_connect() Must return target values and target errnos. */
1520 static abi_long do_connect(int sockfd, abi_ulong target_addr,
1521                            socklen_t addrlen)
1522 {
1523     void *addr;
1524     abi_long ret;
1525  
1526     if (addrlen < 0)
1527         return -TARGET_EINVAL;
1528  
1529     addr = alloca(addrlen);
1530  
1531     ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1532     if (ret)
1533         return ret;
1534  
1535     return get_errno(connect(sockfd, addr, addrlen));
1536 }
1537  
1538 /* do_sendrecvmsg() Must return target values and target errnos. */
1539 static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1540                                int flags, int send)
1541 {
1542     abi_long ret, len;
1543     struct target_msghdr *msgp;
1544     struct msghdr msg;
1545     int count;
1546     struct iovec *vec;
1547     abi_ulong target_vec;
1548  
1549     /* FIXME */
1550     if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1551                           msgp,
1552                           target_msg,
1553                           send ? 1 : 0))
1554         return -TARGET_EFAULT;
1555     if (msgp->msg_name) {
1556         msg.msg_namelen = tswap32(msgp->msg_namelen);
1557         msg.msg_name = alloca(msg.msg_namelen);
1558         ret = target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
1559                                 msg.msg_namelen);
1560         if (ret) {
1561             unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1562             return ret;
1563         }
1564     } else {
1565         msg.msg_name = NULL;
1566         msg.msg_namelen = 0;
1567     }
1568     msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
1569     msg.msg_control = alloca(msg.msg_controllen);
1570     msg.msg_flags = tswap32(msgp->msg_flags);
1571  
1572     count = tswapl(msgp->msg_iovlen);
1573     vec = alloca(count * sizeof(struct iovec));
1574     target_vec = tswapl(msgp->msg_iov);
1575     lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1576     msg.msg_iovlen = count;
1577     msg.msg_iov = vec;
1578  
1579     if (send) {
1580         ret = target_to_host_cmsg(&msg, msgp);
1581         if (ret == 0)
1582             ret = get_errno(sendmsg(fd, &msg, flags));
1583     } else {
1584         ret = get_errno(recvmsg(fd, &msg, flags));
1585         if (!is_error(ret)) {
1586             len = ret;
1587             ret = host_to_target_cmsg(msgp, &msg);
1588             if (!is_error(ret))
1589                 ret = len;
1590         }
1591     }
1592     unlock_iovec(vec, target_vec, count, !send);
1593     unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1594     return ret;
1595 }
1596  
1597 /* do_accept() Must return target values and target errnos. */
1598 static abi_long do_accept(int fd, abi_ulong target_addr,
1599                           abi_ulong target_addrlen_addr)
1600 {
1601     socklen_t addrlen;
1602     void *addr;
1603     abi_long ret;
1604  
1605     if (target_addr == 0)
1606        return get_errno(accept(fd, NULL, NULL));
1607  
1608     /* linux returns EINVAL if addrlen pointer is invalid */
1609     if (get_user_u32(addrlen, target_addrlen_addr))
1610         return -TARGET_EINVAL;
1611  
1612     if (addrlen < 0)
1613         return -TARGET_EINVAL;
1614  
1615     if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1616         return -TARGET_EINVAL;
1617  
1618     addr = alloca(addrlen);
1619  
1620     ret = get_errno(accept(fd, addr, &addrlen));
1621     if (!is_error(ret)) {
1622         host_to_target_sockaddr(target_addr, addr, addrlen);
1623         if (put_user_u32(addrlen, target_addrlen_addr))
1624             ret = -TARGET_EFAULT;
1625     }
1626     return ret;
1627 }
1628  
1629 /* do_getpeername() Must return target values and target errnos. */
1630 static abi_long do_getpeername(int fd, abi_ulong target_addr,
1631                                abi_ulong target_addrlen_addr)
1632 {
1633     socklen_t addrlen;
1634     void *addr;
1635     abi_long ret;
1636  
1637     if (get_user_u32(addrlen, target_addrlen_addr))
1638         return -TARGET_EFAULT;
1639  
1640     if (addrlen < 0)
1641         return -TARGET_EINVAL;
1642  
1643     if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1644         return -TARGET_EFAULT;
1645  
1646     addr = alloca(addrlen);
1647  
1648     ret = get_errno(getpeername(fd, addr, &addrlen));
1649     if (!is_error(ret)) {
1650         host_to_target_sockaddr(target_addr, addr, addrlen);
1651         if (put_user_u32(addrlen, target_addrlen_addr))
1652             ret = -TARGET_EFAULT;
1653     }
1654     return ret;
1655 }
1656  
1657 /* do_getsockname() Must return target values and target errnos. */
1658 static abi_long do_getsockname(int fd, abi_ulong target_addr,
1659                                abi_ulong target_addrlen_addr)
1660 {
1661     socklen_t addrlen;
1662     void *addr;
1663     abi_long ret;
1664  
1665     if (get_user_u32(addrlen, target_addrlen_addr))
1666         return -TARGET_EFAULT;
1667  
1668     if (addrlen < 0)
1669         return -TARGET_EINVAL;
1670  
1671     if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1672         return -TARGET_EFAULT;
1673  
1674     addr = alloca(addrlen);
1675  
1676     ret = get_errno(getsockname(fd, addr, &addrlen));
1677     if (!is_error(ret)) {
1678         host_to_target_sockaddr(target_addr, addr, addrlen);
1679         if (put_user_u32(addrlen, target_addrlen_addr))
1680             ret = -TARGET_EFAULT;
1681     }
1682     return ret;
1683 }
1684  
1685 /* do_socketpair() Must return target values and target errnos. */
1686 static abi_long do_socketpair(int domain, int type, int protocol,
1687                               abi_ulong target_tab_addr)
1688 {
1689     int tab[2];
1690     abi_long ret;
1691  
1692     ret = get_errno(socketpair(domain, type, protocol, tab));
1693     if (!is_error(ret)) {
1694         if (put_user_s32(tab[0], target_tab_addr)
1695             || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1696             ret = -TARGET_EFAULT;
1697     }
1698     return ret;
1699 }
1700  
1701 /* do_sendto() Must return target values and target errnos. */
1702 static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
1703                           abi_ulong target_addr, socklen_t addrlen)
1704 {
1705     void *addr;
1706     void *host_msg;
1707     abi_long ret;
1708  
1709     if (addrlen < 0)
1710         return -TARGET_EINVAL;
1711  
1712     host_msg = lock_user(VERIFY_READ, msg, len, 1);
1713     if (!host_msg)
1714         return -TARGET_EFAULT;
1715     if (target_addr) {
1716         addr = alloca(addrlen);
1717         ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1718         if (ret) {
1719             unlock_user(host_msg, msg, 0);
1720             return ret;
1721         }
1722         ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
1723     } else {
1724         ret = get_errno(send(fd, host_msg, len, flags));
1725     }
1726     unlock_user(host_msg, msg, 0);
1727     return ret;
1728 }
1729  
1730 /* do_recvfrom() Must return target values and target errnos. */
1731 static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
1732                             abi_ulong target_addr,
1733                             abi_ulong target_addrlen)
1734 {
1735     socklen_t addrlen;
1736     void *addr;
1737     void *host_msg;
1738     abi_long ret;
1739  
1740     host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
1741     if (!host_msg)
1742         return -TARGET_EFAULT;
1743     if (target_addr) {
1744         if (get_user_u32(addrlen, target_addrlen)) {
1745             ret = -TARGET_EFAULT;
1746             goto fail;
1747         }
1748         if (addrlen < 0) {
1749             ret = -TARGET_EINVAL;
1750             goto fail;
1751         }
1752         addr = alloca(addrlen);
1753         ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
1754     } else {
1755         addr = NULL; /* To keep compiler quiet.  */
1756         ret = get_errno(recv(fd, host_msg, len, flags));
1757     }
1758     if (!is_error(ret)) {
1759         if (target_addr) {
1760             host_to_target_sockaddr(target_addr, addr, addrlen);
1761             if (put_user_u32(addrlen, target_addrlen)) {
1762                 ret = -TARGET_EFAULT;
1763                 goto fail;
1764             }
1765         }
1766         unlock_user(host_msg, msg, len);
1767     } else {
1768 fail:
1769         unlock_user(host_msg, msg, 0);
1770     }
1771     return ret;
1772 }
1773  
1774 #ifdef TARGET_NR_socketcall
1775 /* do_socketcall() Must return target values and target errnos. */
1776 static abi_long do_socketcall(int num, abi_ulong vptr)
1777 {
1778     abi_long ret;
1779     const int n = sizeof(abi_ulong);
1780  
1781     switch(num) {
1782     case SOCKOP_socket:
1783         {
1784             abi_ulong domain, type, protocol;
1785  
1786             if (get_user_ual(domain, vptr)
1787                 || get_user_ual(type, vptr + n)
1788                 || get_user_ual(protocol, vptr + 2 * n))
1789                 return -TARGET_EFAULT;
1790  
1791             ret = do_socket(domain, type, protocol);
1792         }
1793         break;
1794     case SOCKOP_bind:
1795         {
1796             abi_ulong sockfd;
1797             abi_ulong target_addr;
1798             socklen_t addrlen;
1799  
1800             if (get_user_ual(sockfd, vptr)
1801                 || get_user_ual(target_addr, vptr + n)
1802                 || get_user_ual(addrlen, vptr + 2 * n))
1803                 return -TARGET_EFAULT;
1804  
1805             ret = do_bind(sockfd, target_addr, addrlen);
1806         }
1807         break;
1808     case SOCKOP_connect:
1809         {
1810             abi_ulong sockfd;
1811             abi_ulong target_addr;
1812             socklen_t addrlen;
1813  
1814             if (get_user_ual(sockfd, vptr)
1815                 || get_user_ual(target_addr, vptr + n)
1816                 || get_user_ual(addrlen, vptr + 2 * n))
1817                 return -TARGET_EFAULT;
1818  
1819             ret = do_connect(sockfd, target_addr, addrlen);
1820         }
1821         break;
1822     case SOCKOP_listen:
1823         {
1824             abi_ulong sockfd, backlog;
1825  
1826             if (get_user_ual(sockfd, vptr)
1827                 || get_user_ual(backlog, vptr + n))
1828                 return -TARGET_EFAULT;
1829  
1830             ret = get_errno(listen(sockfd, backlog));
1831         }
1832         break;
1833     case SOCKOP_accept:
1834         {
1835             abi_ulong sockfd;
1836             abi_ulong target_addr, target_addrlen;
1837  
1838             if (get_user_ual(sockfd, vptr)
1839                 || get_user_ual(target_addr, vptr + n)
1840                 || get_user_ual(target_addrlen, vptr + 2 * n))
1841                 return -TARGET_EFAULT;
1842  
1843             ret = do_accept(sockfd, target_addr, target_addrlen);
1844         }
1845         break;
1846     case SOCKOP_getsockname:
1847         {
1848             abi_ulong sockfd;
1849             abi_ulong target_addr, target_addrlen;
1850  
1851             if (get_user_ual(sockfd, vptr)
1852                 || get_user_ual(target_addr, vptr + n)
1853                 || get_user_ual(target_addrlen, vptr + 2 * n))
1854                 return -TARGET_EFAULT;
1855  
1856             ret = do_getsockname(sockfd, target_addr, target_addrlen);
1857         }
1858         break;
1859     case SOCKOP_getpeername:
1860         {
1861             abi_ulong sockfd;
1862             abi_ulong target_addr, target_addrlen;
1863  
1864             if (get_user_ual(sockfd, vptr)
1865                 || get_user_ual(target_addr, vptr + n)
1866                 || get_user_ual(target_addrlen, vptr + 2 * n))
1867                 return -TARGET_EFAULT;
1868  
1869             ret = do_getpeername(sockfd, target_addr, target_addrlen);
1870         }
1871         break;
1872     case SOCKOP_socketpair:
1873         {
1874             abi_ulong domain, type, protocol;
1875             abi_ulong tab;
1876  
1877             if (get_user_ual(domain, vptr)
1878                 || get_user_ual(type, vptr + n)
1879                 || get_user_ual(protocol, vptr + 2 * n)
1880                 || get_user_ual(tab, vptr + 3 * n))
1881                 return -TARGET_EFAULT;
1882  
1883             ret = do_socketpair(domain, type, protocol, tab);
1884         }
1885         break;
1886     case SOCKOP_send:
1887         {
1888             abi_ulong sockfd;
1889             abi_ulong msg;
1890             size_t len;
1891             abi_ulong flags;
1892  
1893             if (get_user_ual(sockfd, vptr)
1894                 || get_user_ual(msg, vptr + n)
1895                 || get_user_ual(len, vptr + 2 * n)
1896                 || get_user_ual(flags, vptr + 3 * n))
1897                 return -TARGET_EFAULT;
1898  
1899             ret = do_sendto(sockfd, msg, len, flags, 0, 0);
1900         }
1901         break;
1902     case SOCKOP_recv:
1903         {
1904             abi_ulong sockfd;
1905             abi_ulong msg;
1906             size_t len;
1907             abi_ulong flags;
1908  
1909             if (get_user_ual(sockfd, vptr)
1910                 || get_user_ual(msg, vptr + n)
1911                 || get_user_ual(len, vptr + 2 * n)
1912                 || get_user_ual(flags, vptr + 3 * n))
1913                 return -TARGET_EFAULT;
1914  
1915             ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
1916         }
1917         break;
1918     case SOCKOP_sendto:
1919         {
1920             abi_ulong sockfd;
1921             abi_ulong msg;
1922             size_t len;
1923             abi_ulong flags;
1924             abi_ulong addr;
1925             socklen_t addrlen;
1926  
1927             if (get_user_ual(sockfd, vptr)
1928                 || get_user_ual(msg, vptr + n)
1929                 || get_user_ual(len, vptr + 2 * n)
1930                 || get_user_ual(flags, vptr + 3 * n)
1931                 || get_user_ual(addr, vptr + 4 * n)
1932                 || get_user_ual(addrlen, vptr + 5 * n))
1933                 return -TARGET_EFAULT;
1934  
1935             ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
1936         }
1937         break;
1938     case SOCKOP_recvfrom:
1939         {
1940             abi_ulong sockfd;
1941             abi_ulong msg;
1942             size_t len;
1943             abi_ulong flags;
1944             abi_ulong addr;
1945             socklen_t addrlen;
1946  
1947             if (get_user_ual(sockfd, vptr)
1948                 || get_user_ual(msg, vptr + n)
1949                 || get_user_ual(len, vptr + 2 * n)
1950                 || get_user_ual(flags, vptr + 3 * n)
1951                 || get_user_ual(addr, vptr + 4 * n)
1952                 || get_user_ual(addrlen, vptr + 5 * n))
1953                 return -TARGET_EFAULT;
1954  
1955             ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
1956         }
1957         break;
1958     case SOCKOP_shutdown:
1959         {
1960             abi_ulong sockfd, how;
1961  
1962             if (get_user_ual(sockfd, vptr)
1963                 || get_user_ual(how, vptr + n))
1964                 return -TARGET_EFAULT;
1965  
1966             ret = get_errno(shutdown(sockfd, how));
1967         }
1968         break;
1969     case SOCKOP_sendmsg:
1970     case SOCKOP_recvmsg:
1971         {
1972             abi_ulong fd;
1973             abi_ulong target_msg;
1974             abi_ulong flags;
1975  
1976             if (get_user_ual(fd, vptr)
1977                 || get_user_ual(target_msg, vptr + n)
1978                 || get_user_ual(flags, vptr + 2 * n))
1979                 return -TARGET_EFAULT;
1980  
1981             ret = do_sendrecvmsg(fd, target_msg, flags,
1982                                  (num == SOCKOP_sendmsg));
1983         }
1984         break;
1985     case SOCKOP_setsockopt:
1986         {
1987             abi_ulong sockfd;
1988             abi_ulong level;
1989             abi_ulong optname;
1990             abi_ulong optval;
1991             socklen_t optlen;
1992  
1993             if (get_user_ual(sockfd, vptr)
1994                 || get_user_ual(level, vptr + n)
1995                 || get_user_ual(optname, vptr + 2 * n)
1996                 || get_user_ual(optval, vptr + 3 * n)
1997                 || get_user_ual(optlen, vptr + 4 * n))
1998                 return -TARGET_EFAULT;
1999  
2000             ret = do_setsockopt(sockfd, level, optname, optval, optlen);
2001         }
2002         break;
2003     case SOCKOP_getsockopt:
2004         {
2005             abi_ulong sockfd;
2006             abi_ulong level;
2007             abi_ulong optname;
2008             abi_ulong optval;
2009             socklen_t optlen;
2010  
2011             if (get_user_ual(sockfd, vptr)
2012                 || get_user_ual(level, vptr + n)
2013                 || get_user_ual(optname, vptr + 2 * n)
2014                 || get_user_ual(optval, vptr + 3 * n)
2015                 || get_user_ual(optlen, vptr + 4 * n))
2016                 return -TARGET_EFAULT;
2017  
2018             ret = do_getsockopt(sockfd, level, optname, optval, optlen);
2019         }
2020         break;
2021     default:
2022         gemu_log("Unsupported socketcall: %d\n", num);
2023         ret = -TARGET_ENOSYS;
2024         break;
2025     }
2026     return ret;
2027 }
2028 #endif
2029  
2030 #define N_SHM_REGIONS   32
2031  
2032 static struct shm_region {
2033     abi_ulong   start;
2034     abi_ulong   size;
2035 } shm_regions[N_SHM_REGIONS];
2036  
2037 struct target_ipc_perm
2038 {
2039     abi_long __key;
2040     abi_ulong uid;
2041     abi_ulong gid;
2042     abi_ulong cuid;
2043     abi_ulong cgid;
2044     unsigned short int mode;
2045     unsigned short int __pad1;
2046     unsigned short int __seq;
2047     unsigned short int __pad2;
2048     abi_ulong __unused1;
2049     abi_ulong __unused2;
2050 };
2051  
2052 struct target_semid_ds
2053 {
2054   struct target_ipc_perm sem_perm;
2055   abi_ulong sem_otime;
2056   abi_ulong __unused1;
2057   abi_ulong sem_ctime;
2058   abi_ulong __unused2;
2059   abi_ulong sem_nsems;
2060   abi_ulong __unused3;
2061   abi_ulong __unused4;
2062 };
2063  
2064 static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
2065                                                abi_ulong target_addr)
2066 {
2067     struct target_ipc_perm *target_ip;
2068     struct target_semid_ds *target_sd;
2069  
2070     if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2071         return -TARGET_EFAULT;
2072     target_ip = &(target_sd->sem_perm);
2073     host_ip->__key = tswapl(target_ip->__key);
2074     host_ip->uid = tswapl(target_ip->uid);
2075     host_ip->gid = tswapl(target_ip->gid);
2076     host_ip->cuid = tswapl(target_ip->cuid);
2077     host_ip->cgid = tswapl(target_ip->cgid);
2078     host_ip->mode = tswapl(target_ip->mode);
2079     unlock_user_struct(target_sd, target_addr, 0);
2080     return 0;
2081 }
2082  
2083 static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
2084                                                struct ipc_perm *host_ip)
2085 {
2086     struct target_ipc_perm *target_ip;
2087     struct target_semid_ds *target_sd;
2088  
2089     if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2090         return -TARGET_EFAULT;
2091     target_ip = &(target_sd->sem_perm);
2092     target_ip->__key = tswapl(host_ip->__key);
2093     target_ip->uid = tswapl(host_ip->uid);
2094     target_ip->gid = tswapl(host_ip->gid);
2095     target_ip->cuid = tswapl(host_ip->cuid);
2096     target_ip->cgid = tswapl(host_ip->cgid);
2097     target_ip->mode = tswapl(host_ip->mode);
2098     unlock_user_struct(target_sd, target_addr, 1);
2099     return 0;
2100 }
2101  
2102 static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
2103                                                abi_ulong target_addr)
2104 {
2105     struct target_semid_ds *target_sd;
2106  
2107     if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2108         return -TARGET_EFAULT;
2109     if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr))
2110         return -TARGET_EFAULT;
2111     host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
2112     host_sd->sem_otime = tswapl(target_sd->sem_otime);
2113     host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
2114     unlock_user_struct(target_sd, target_addr, 0);
2115     return 0;
2116 }
2117  
2118 static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
2119                                                struct semid_ds *host_sd)
2120 {
2121     struct target_semid_ds *target_sd;
2122  
2123     if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2124         return -TARGET_EFAULT;
2125     if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
2126         return -TARGET_EFAULT;;
2127     target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
2128     target_sd->sem_otime = tswapl(host_sd->sem_otime);
2129     target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
2130     unlock_user_struct(target_sd, target_addr, 1);
2131     return 0;
2132 }
2133  
2134 struct target_seminfo {
2135     int semmap;
2136     int semmni;
2137     int semmns;
2138     int semmnu;
2139     int semmsl;
2140     int semopm;
2141     int semume;
2142     int semusz;
2143     int semvmx;
2144     int semaem;
2145 };
2146  
2147 static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
2148                                               struct seminfo *host_seminfo)
2149 {
2150     struct target_seminfo *target_seminfo;
2151     if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
2152         return -TARGET_EFAULT;
2153     __put_user(host_seminfo->semmap, &target_seminfo->semmap);
2154     __put_user(host_seminfo->semmni, &target_seminfo->semmni);
2155     __put_user(host_seminfo->semmns, &target_seminfo->semmns);
2156     __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
2157     __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
2158     __put_user(host_seminfo->semopm, &target_seminfo->semopm);
2159     __put_user(host_seminfo->semume, &target_seminfo->semume);
2160     __put_user(host_seminfo->semusz, &target_seminfo->semusz);
2161     __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
2162     __put_user(host_seminfo->semaem, &target_seminfo->semaem);
2163     unlock_user_struct(target_seminfo, target_addr, 1);
2164     return 0;
2165 }
2166  
2167 union semun {
2168         int val;
2169         struct semid_ds *buf;
2170         unsigned short *array;
2171         struct seminfo *__buf;
2172 };
2173  
2174 union target_semun {
2175         int val;
2176         abi_ulong buf;
2177         abi_ulong array;
2178         abi_ulong __buf;
2179 };
2180  
2181 static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
2182                                                abi_ulong target_addr)
2183 {
2184     int nsems;
2185     unsigned short *array;
2186     union semun semun;
2187     struct semid_ds semid_ds;
2188     int i, ret;
2189  
2190     semun.buf = &semid_ds;
2191  
2192     ret = semctl(semid, 0, IPC_STAT, semun);
2193     if (ret == -1)
2194         return get_errno(ret);
2195  
2196     nsems = semid_ds.sem_nsems;
2197  
2198     *host_array = malloc(nsems*sizeof(unsigned short));
2199     array = lock_user(VERIFY_READ, target_addr,
2200                       nsems*sizeof(unsigned short), 1);
2201     if (!array)
2202         return -TARGET_EFAULT;
2203  
2204     for(i=0; i<nsems; i++) {
2205         __get_user((*host_array)[i], &array[i]);
2206     }
2207     unlock_user(array, target_addr, 0);
2208  
2209     return 0;
2210 }
2211  
2212 static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
2213                                                unsigned short **host_array)
2214 {
2215     int nsems;
2216     unsigned short *array;
2217     union semun semun;
2218     struct semid_ds semid_ds;
2219     int i, ret;
2220  
2221     semun.buf = &semid_ds;
2222  
2223     ret = semctl(semid, 0, IPC_STAT, semun);
2224     if (ret == -1)
2225         return get_errno(ret);
2226  
2227     nsems = semid_ds.sem_nsems;
2228  
2229     array = lock_user(VERIFY_WRITE, target_addr,
2230                       nsems*sizeof(unsigned short), 0);
2231     if (!array)
2232         return -TARGET_EFAULT;
2233  
2234     for(i=0; i<nsems; i++) {
2235         __put_user((*host_array)[i], &array[i]);
2236     }
2237     free(*host_array);
2238     unlock_user(array, target_addr, 1);
2239  
2240     return 0;
2241 }
2242  
2243 static inline abi_long do_semctl(int semid, int semnum, int cmd,
2244                                  union target_semun target_su)
2245 {
2246     union semun arg;
2247     struct semid_ds dsarg;
2248     unsigned short *array = NULL;
2249     struct seminfo seminfo;
2250     abi_long ret = -TARGET_EINVAL;
2251     abi_long err;
2252     cmd &= 0xff;
2253  
2254     switch( cmd ) {
2255         case GETVAL:
2256         case SETVAL:
2257             arg.val = tswapl(target_su.val);
2258             ret = get_errno(semctl(semid, semnum, cmd, arg));
2259             target_su.val = tswapl(arg.val);
2260             break;
2261         case GETALL:
2262         case SETALL:
2263             err = target_to_host_semarray(semid, &array, target_su.array);
2264             if (err)
2265                 return err;
2266             arg.array = array;
2267             ret = get_errno(semctl(semid, semnum, cmd, arg));
2268             err = host_to_target_semarray(semid, target_su.array, &array);
2269             if (err)
2270                 return err;
2271             break;
2272         case IPC_STAT:
2273         case IPC_SET:
2274         case SEM_STAT:
2275             err = target_to_host_semid_ds(&dsarg, target_su.buf);
2276             if (err)
2277                 return err;
2278             arg.buf = &dsarg;
2279             ret = get_errno(semctl(semid, semnum, cmd, arg));
2280             err = host_to_target_semid_ds(target_su.buf, &dsarg);
2281             if (err)
2282                 return err;
2283             break;
2284         case IPC_INFO:
2285         case SEM_INFO:
2286             arg.__buf = &seminfo;
2287             ret = get_errno(semctl(semid, semnum, cmd, arg));
2288             err = host_to_target_seminfo(target_su.__buf, &seminfo);
2289             if (err)
2290                 return err;
2291             break;
2292         case IPC_RMID:
2293         case GETPID:
2294         case GETNCNT:
2295         case GETZCNT:
2296             ret = get_errno(semctl(semid, semnum, cmd, NULL));
2297             break;
2298     }
2299  
2300     return ret;
2301 }
2302  
2303 struct target_sembuf {
2304     unsigned short sem_num;
2305     short sem_op;
2306     short sem_flg;
2307 };
2308  
2309 static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
2310                                              abi_ulong target_addr,
2311                                              unsigned nsops)
2312 {
2313     struct target_sembuf *target_sembuf;
2314     int i;
2315  
2316     target_sembuf = lock_user(VERIFY_READ, target_addr,
2317                               nsops*sizeof(struct target_sembuf), 1);
2318     if (!target_sembuf)
2319         return -TARGET_EFAULT;
2320  
2321     for(i=0; i<nsops; i++) {
2322         __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
2323         __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
2324         __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
2325     }
2326  
2327     unlock_user(target_sembuf, target_addr, 0);
2328  
2329     return 0;
2330 }
2331  
2332 static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
2333 {
2334     struct sembuf sops[nsops];
2335  
2336     if (target_to_host_sembuf(sops, ptr, nsops))
2337         return -TARGET_EFAULT;
2338  
2339     return semop(semid, sops, nsops);
2340 }
2341  
2342 struct target_msqid_ds
2343 {
2344     struct target_ipc_perm msg_perm;
2345     abi_ulong msg_stime;
2346 #if TARGET_ABI_BITS == 32
2347     abi_ulong __unused1;
2348 #endif
2349     abi_ulong msg_rtime;
2350 #if TARGET_ABI_BITS == 32
2351     abi_ulong __unused2;
2352 #endif
2353     abi_ulong msg_ctime;
2354 #if TARGET_ABI_BITS == 32
2355     abi_ulong __unused3;
2356 #endif
2357     abi_ulong __msg_cbytes;
2358     abi_ulong msg_qnum;
2359     abi_ulong msg_qbytes;
2360     abi_ulong msg_lspid;
2361     abi_ulong msg_lrpid;
2362     abi_ulong __unused4;
2363     abi_ulong __unused5;
2364 };
2365  
2366 static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
2367                                                abi_ulong target_addr)
2368 {
2369     struct target_msqid_ds *target_md;
2370  
2371     if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
2372         return -TARGET_EFAULT;
2373     if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
2374         return -TARGET_EFAULT;
2375     host_md->msg_stime = tswapl(target_md->msg_stime);
2376     host_md->msg_rtime = tswapl(target_md->msg_rtime);
2377     host_md->msg_ctime = tswapl(target_md->msg_ctime);
2378     host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
2379     host_md->msg_qnum = tswapl(target_md->msg_qnum);
2380     host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
2381     host_md->msg_lspid = tswapl(target_md->msg_lspid);
2382     host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
2383     unlock_user_struct(target_md, target_addr, 0);
2384     return 0;
2385 }
2386  
2387 static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
2388                                                struct msqid_ds *host_md)
2389 {
2390     struct target_msqid_ds *target_md;
2391  
2392     if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
2393         return -TARGET_EFAULT;
2394     if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
2395         return -TARGET_EFAULT;
2396     target_md->msg_stime = tswapl(host_md->msg_stime);
2397     target_md->msg_rtime = tswapl(host_md->msg_rtime);
2398     target_md->msg_ctime = tswapl(host_md->msg_ctime);
2399     target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
2400     target_md->msg_qnum = tswapl(host_md->msg_qnum);
2401     target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
2402     target_md->msg_lspid = tswapl(host_md->msg_lspid);
2403     target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
2404     unlock_user_struct(target_md, target_addr, 1);
2405     return 0;
2406 }
2407  
2408 struct target_msginfo {
2409     int msgpool;
2410     int msgmap;
2411     int msgmax;
2412     int msgmnb;
2413     int msgmni;
2414     int msgssz;
2415     int msgtql;
2416     unsigned short int msgseg;
2417 };
2418  
2419 static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
2420                                               struct msginfo *host_msginfo)
2421 {
2422     struct target_msginfo *target_msginfo;
2423     if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
2424         return -TARGET_EFAULT;
2425     __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
2426     __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
2427     __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
2428     __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
2429     __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
2430     __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
2431     __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
2432     __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
2433     unlock_user_struct(target_msginfo, target_addr, 1);
2434     return 0;
2435 }
2436  
2437 static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
2438 {
2439     struct msqid_ds dsarg;
2440     struct msginfo msginfo;
2441     abi_long ret = -TARGET_EINVAL;
2442  
2443     cmd &= 0xff;
2444  
2445     switch (cmd) {
2446     case IPC_STAT:
2447     case IPC_SET:
2448     case MSG_STAT:
2449         if (target_to_host_msqid_ds(&dsarg,ptr))
2450             return -TARGET_EFAULT;
2451         ret = get_errno(msgctl(msgid, cmd, &dsarg));
2452         if (host_to_target_msqid_ds(ptr,&dsarg))
2453             return -TARGET_EFAULT;
2454         break;
2455     case IPC_RMID:
2456         ret = get_errno(msgctl(msgid, cmd, NULL));
2457         break;
2458     case IPC_INFO:
2459     case MSG_INFO:
2460         ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
2461         if (host_to_target_msginfo(ptr, &msginfo))
2462             return -TARGET_EFAULT;
2463         break;
2464     }
2465  
2466     return ret;
2467 }
2468  
2469 struct target_msgbuf {
2470     abi_long mtype;
2471     char        mtext[1];
2472 };
2473  
2474 static inline abi_long do_msgsnd(int msqid, abi_long msgp,
2475                                  unsigned int msgsz, int msgflg)
2476 {
2477     struct target_msgbuf *target_mb;
2478     struct msgbuf *host_mb;
2479     abi_long ret = 0;
2480  
2481     if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
2482         return -TARGET_EFAULT;
2483     host_mb = malloc(msgsz+sizeof(long));
2484     host_mb->mtype = (abi_long) tswapl(target_mb->mtype);
2485     memcpy(host_mb->mtext, target_mb->mtext, msgsz);
2486     ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
2487     free(host_mb);
2488     unlock_user_struct(target_mb, msgp, 0);
2489  
2490     return ret;
2491 }
2492  
2493 static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2494                                  unsigned int msgsz, abi_long msgtyp,
2495                                  int msgflg)
2496 {
2497     struct target_msgbuf *target_mb;
2498     char *target_mtext;
2499     struct msgbuf *host_mb;
2500     abi_long ret = 0;
2501  
2502     if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2503         return -TARGET_EFAULT;
2504  
2505     host_mb = malloc(msgsz+sizeof(long));
2506     ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapl(msgtyp), msgflg));
2507  
2508     if (ret > 0) {
2509         abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2510         target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2511         if (!target_mtext) {
2512             ret = -TARGET_EFAULT;
2513             goto end;
2514         }
2515         memcpy(target_mb->mtext, host_mb->mtext, ret);
2516         unlock_user(target_mtext, target_mtext_addr, ret);
2517     }
2518  
2519     target_mb->mtype = tswapl(host_mb->mtype);
2520     free(host_mb);
2521  
2522 end:
2523     if (target_mb)
2524         unlock_user_struct(target_mb, msgp, 1);
2525     return ret;
2526 }
2527  
2528 struct target_shmid_ds
2529 {
2530     struct target_ipc_perm shm_perm;
2531     abi_ulong shm_segsz;
2532     abi_ulong shm_atime;
2533 #if TARGET_ABI_BITS == 32
2534     abi_ulong __unused1;
2535 #endif
2536     abi_ulong shm_dtime;
2537 #if TARGET_ABI_BITS == 32
2538     abi_ulong __unused2;
2539 #endif
2540     abi_ulong shm_ctime;
2541 #if TARGET_ABI_BITS == 32
2542     abi_ulong __unused3;
2543 #endif
2544     int shm_cpid;
2545     int shm_lpid;
2546     abi_ulong shm_nattch;
2547     unsigned long int __unused4;
2548     unsigned long int __unused5;
2549 };
2550  
2551 static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
2552                                                abi_ulong target_addr)
2553 {
2554     struct target_shmid_ds *target_sd;
2555  
2556     if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2557         return -TARGET_EFAULT;
2558     if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr))
2559         return -TARGET_EFAULT;
2560     __get_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2561     __get_user(host_sd->shm_atime, &target_sd->shm_atime);
2562     __get_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2563     __get_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2564     __get_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2565     __get_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2566     __get_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2567     unlock_user_struct(target_sd, target_addr, 0);
2568     return 0;
2569 }
2570  
2571 static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
2572                                                struct shmid_ds *host_sd)
2573 {
2574     struct target_shmid_ds *target_sd;
2575  
2576     if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2577         return -TARGET_EFAULT;
2578     if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm)))
2579         return -TARGET_EFAULT;
2580     __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2581     __put_user(host_sd->shm_atime, &target_sd->shm_atime);
2582     __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2583     __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2584     __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2585     __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2586     __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2587     unlock_user_struct(target_sd, target_addr, 1);
2588     return 0;
2589 }
2590  
2591 struct  target_shminfo {
2592     abi_ulong shmmax;
2593     abi_ulong shmmin;
2594     abi_ulong shmmni;
2595     abi_ulong shmseg;
2596     abi_ulong shmall;
2597 };
2598  
2599 static inline abi_long host_to_target_shminfo(abi_ulong target_addr,
2600                                               struct shminfo *host_shminfo)
2601 {
2602     struct target_shminfo *target_shminfo;
2603     if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0))
2604         return -TARGET_EFAULT;
2605     __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
2606     __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
2607     __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
2608     __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
2609     __put_user(host_shminfo->shmall, &target_shminfo->shmall);
2610     unlock_user_struct(target_shminfo, target_addr, 1);
2611     return 0;
2612 }
2613  
2614 struct target_shm_info {
2615     int used_ids;
2616     abi_ulong shm_tot;
2617     abi_ulong shm_rss;
2618     abi_ulong shm_swp;
2619     abi_ulong swap_attempts;
2620     abi_ulong swap_successes;
2621 };
2622  
2623 static inline abi_long host_to_target_shm_info(abi_ulong target_addr,
2624                                                struct shm_info *host_shm_info)
2625 {
2626     struct target_shm_info *target_shm_info;
2627     if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0))
2628         return -TARGET_EFAULT;
2629     __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
2630     __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
2631     __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
2632     __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
2633     __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts);
2634     __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes);
2635     unlock_user_struct(target_shm_info, target_addr, 1);
2636     return 0;
2637 }
2638  
2639 static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
2640 {
2641     struct shmid_ds dsarg;
2642     struct shminfo shminfo;
2643     struct shm_info shm_info;
2644     abi_long ret = -TARGET_EINVAL;
2645  
2646     cmd &= 0xff;
2647  
2648     switch(cmd) {
2649     case IPC_STAT:
2650     case IPC_SET:
2651     case SHM_STAT:
2652         if (target_to_host_shmid_ds(&dsarg, buf))
2653             return -TARGET_EFAULT;
2654         ret = get_errno(shmctl(shmid, cmd, &dsarg));
2655         if (host_to_target_shmid_ds(buf, &dsarg))
2656             return -TARGET_EFAULT;
2657         break;
2658     case IPC_INFO:
2659         ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
2660         if (host_to_target_shminfo(buf, &shminfo))
2661             return -TARGET_EFAULT;
2662         break;
2663     case SHM_INFO:
2664         ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
2665         if (host_to_target_shm_info(buf, &shm_info))
2666             return -TARGET_EFAULT;
2667         break;
2668     case IPC_RMID:
2669     case SHM_LOCK:
2670     case SHM_UNLOCK:
2671         ret = get_errno(shmctl(shmid, cmd, NULL));
2672         break;
2673     }
2674  
2675     return ret;
2676 }
2677  
2678 static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
2679 {
2680     abi_long raddr;
2681     void *host_raddr;
2682     struct shmid_ds shm_info;
2683     int i,ret;
2684  
2685     /* find out the length of the shared memory segment */
2686     ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
2687     if (is_error(ret)) {
2688         /* can't get length, bail out */
2689         return ret;
2690     }
2691  
2692     mmap_lock();
2693  
2694     if (shmaddr)
2695         host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
2696     else {
2697         abi_ulong mmap_start;
2698  
2699         mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
2700  
2701         if (mmap_start == -1) {
2702             errno = ENOMEM;
2703             host_raddr = (void *)-1;
2704         } else
2705             host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);
2706     }
2707  
2708     if (host_raddr == (void *)-1) {
2709         mmap_unlock();
2710         return get_errno((long)host_raddr);
2711     }
2712     raddr=h2g((unsigned long)host_raddr);
2713  
2714     page_set_flags(raddr, raddr + shm_info.shm_segsz,
2715                    PAGE_VALID | PAGE_READ |
2716                    ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
2717  
2718     for (i = 0; i < N_SHM_REGIONS; i++) {
2719         if (shm_regions[i].start == 0) {
2720             shm_regions[i].start = raddr;
2721             shm_regions[i].size = shm_info.shm_segsz;
2722             break;
2723         }
2724     }
2725  
2726     mmap_unlock();
2727     return raddr;
2728  
2729 }
2730  
2731 static inline abi_long do_shmdt(abi_ulong shmaddr)
2732 {
2733     int i;
2734  
2735     for (i = 0; i < N_SHM_REGIONS; ++i) {
2736         if (shm_regions[i].start == shmaddr) {
2737             shm_regions[i].start = 0;
2738             page_set_flags(shmaddr, shm_regions[i].size, 0);
2739             break;
2740         }
2741     }
2742  
2743     return get_errno(shmdt(g2h(shmaddr)));
2744 }
2745  
2746 #ifdef TARGET_NR_ipc
2747 /* ??? This only works with linear mappings.  */
2748 /* do_ipc() must return target values and target errnos. */
2749 static abi_long do_ipc(unsigned int call, int first,
2750                        int second, int third,
2751                        abi_long ptr, abi_long fifth)
2752 {
2753     int version;
2754     abi_long ret = 0;
2755  
2756     version = call >> 16;
2757     call &= 0xffff;
2758  
2759     switch (call) {
2760     case IPCOP_semop:
2761         ret = do_semop(first, ptr, second);
2762         break;
2763  
2764     case IPCOP_semget:
2765         ret = get_errno(semget(first, second, third));
2766         break;
2767  
2768     case IPCOP_semctl:
2769         ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr);
2770         break;
2771  
2772     case IPCOP_msgget:
2773         ret = get_errno(msgget(first, second));
2774         break;
2775  
2776     case IPCOP_msgsnd:
2777         ret = do_msgsnd(first, ptr, second, third);
2778         break;
2779  
2780     case IPCOP_msgctl:
2781         ret = do_msgctl(first, second, ptr);
2782         break;
2783  
2784     case IPCOP_msgrcv:
2785         switch (version) {
2786         case 0:
2787             {
2788                 struct target_ipc_kludge {
2789                     abi_long msgp;
2790                     abi_long msgtyp;
2791                 } *tmp;
2792  
2793                 if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
2794                     ret = -TARGET_EFAULT;
2795                     break;
2796                 }
2797  
2798                 ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
2799  
2800                 unlock_user_struct(tmp, ptr, 0);
2801                 break;
2802             }
2803         default:
2804             ret = do_msgrcv(first, ptr, second, fifth, third);
2805         }
2806         break;
2807  
2808     case IPCOP_shmat:
2809         switch (version) {
2810         default:
2811         {
2812             abi_ulong raddr;
2813             raddr = do_shmat(first, ptr, second);
2814             if (is_error(raddr))
2815                 return get_errno(raddr);
2816             if (put_user_ual(raddr, third))
2817                 return -TARGET_EFAULT;
2818             break;
2819         }
2820         case 1:
2821             ret = -TARGET_EINVAL;
2822             break;
2823         }
2824         break;
2825     case IPCOP_shmdt:
2826         ret = do_shmdt(ptr);
2827         break;
2828  
2829     case IPCOP_shmget:
2830         /* IPC_* flag values are the same on all linux platforms */
2831         ret = get_errno(shmget(first, second, third));
2832         break;
2833  
2834         /* IPC_* and SHM_* command values are the same on all linux platforms */
2835     case IPCOP_shmctl:
2836         ret = do_shmctl(first, second, third);
2837         break;
2838     default:
2839         gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2840         ret = -TARGET_ENOSYS;
2841         break;
2842     }
2843     return ret;
2844 }
2845 #endif
2846  
2847 /* kernel structure types definitions */
2848 #define IFNAMSIZ        16
2849  
2850 #define STRUCT(name, ...) STRUCT_ ## name,
2851 #define STRUCT_SPECIAL(name) STRUCT_ ## name,
2852 enum {
2853 #include "syscall_types.h"
2854 };
2855 #undef STRUCT
2856 #undef STRUCT_SPECIAL
2857  
2858 #define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = {  __VA_ARGS__, TYPE_NULL };
2859 #define STRUCT_SPECIAL(name)
2860 #include "syscall_types.h"
2861 #undef STRUCT
2862 #undef STRUCT_SPECIAL
2863  
2864 typedef struct IOCTLEntry {
2865     unsigned int target_cmd;
2866     unsigned int host_cmd;
2867     const char *name;
2868     int access;
2869     const argtype arg_type[5];
2870 } IOCTLEntry;
2871  
2872 #define IOC_R 0x0001
2873 #define IOC_W 0x0002
2874 #define IOC_RW (IOC_R | IOC_W)
2875  
2876 #define MAX_STRUCT_SIZE 4096
2877  
2878 static IOCTLEntry ioctl_entries[] = {
2879 #define IOCTL(cmd, access, ...) \
2880     { TARGET_ ## cmd, cmd, #cmd, access, {  __VA_ARGS__ } },
2881 #include "ioctls.h"
2882     { 0, 0, },
2883 };
2884  
2885 /* ??? Implement proper locking for ioctls.  */
2886 /* do_ioctl() Must return target values and target errnos. */
2887 static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
2888 {
2889     const IOCTLEntry *ie;
2890     const argtype *arg_type;
2891     abi_long ret;
2892     uint8_t buf_temp[MAX_STRUCT_SIZE];
2893     int target_size;
2894     void *argptr;
2895  
2896     ie = ioctl_entries;
2897     for(;;) {
2898         if (ie->target_cmd == 0) {
2899             gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
2900             return -TARGET_ENOSYS;
2901         }
2902         if (ie->target_cmd == cmd)
2903             break;
2904         ie++;
2905     }
2906     arg_type = ie->arg_type;
2907 #if defined(DEBUG)
2908     gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
2909 #endif
2910     switch(arg_type[0]) {
2911     case TYPE_NULL:
2912         /* no argument */
2913         ret = get_errno(ioctl(fd, ie->host_cmd));
2914         break;
2915     case TYPE_PTRVOID:
2916     case TYPE_INT:
2917         /* int argment */
2918         ret = get_errno(ioctl(fd, ie->host_cmd, arg));
2919         break;
2920     case TYPE_PTR:
2921         arg_type++;
2922         target_size = thunk_type_size(arg_type, 0);
2923         switch(ie->access) {
2924         case IOC_R:
2925             ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2926             if (!is_error(ret)) {
2927                 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2928                 if (!argptr)
2929                     return -TARGET_EFAULT;
2930                 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2931                 unlock_user(argptr, arg, target_size);
2932             }
2933             break;
2934         case IOC_W:
2935             argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2936             if (!argptr)
2937                 return -TARGET_EFAULT;
2938             thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2939             unlock_user(argptr, arg, 0);
2940             ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2941             break;
2942         default:
2943         case IOC_RW:
2944             argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2945             if (!argptr)
2946                 return -TARGET_EFAULT;
2947             thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2948             unlock_user(argptr, arg, 0);
2949             ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2950             if (!is_error(ret)) {
2951                 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2952                 if (!argptr)
2953                     return -TARGET_EFAULT;
2954                 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2955                 unlock_user(argptr, arg, target_size);
2956             }
2957             break;
2958         }
2959         break;
2960     default:
2961         gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
2962                  (long)cmd, arg_type[0]);
2963         ret = -TARGET_ENOSYS;
2964         break;
2965     }
2966     return ret;
2967 }
2968  
2969 static const bitmask_transtbl iflag_tbl[] = {
2970         { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
2971         { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
2972         { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
2973         { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
2974         { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
2975         { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
2976         { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
2977         { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
2978         { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
2979         { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
2980         { TARGET_IXON, TARGET_IXON, IXON, IXON },
2981         { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
2982         { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
2983         { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
2984         { 0, 0, 0, 0 }
2985 };
2986  
2987 static const bitmask_transtbl oflag_tbl[] = {
2988         { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
2989         { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
2990         { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
2991         { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
2992         { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
2993         { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
2994         { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
2995         { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
2996         { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
2997         { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
2998         { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
2999         { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
3000         { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
3001         { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
3002         { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
3003         { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
3004         { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
3005         { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
3006         { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
3007         { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
3008         { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
3009         { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
3010         { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
3011         { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
3012         { 0, 0, 0, 0 }
3013 };
3014  
3015 static const bitmask_transtbl cflag_tbl[] = {
3016         { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
3017         { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
3018         { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
3019         { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
3020         { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
3021         { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
3022         { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
3023         { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
3024         { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
3025         { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
3026         { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
3027         { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
3028         { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
3029         { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
3030         { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
3031         { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
3032         { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
3033         { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
3034         { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
3035         { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
3036         { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
3037         { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
3038         { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
3039         { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
3040         { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
3041         { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
3042         { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
3043         { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
3044         { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
3045         { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
3046         { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
3047         { 0, 0, 0, 0 }
3048 };
3049  
3050 static const bitmask_transtbl lflag_tbl[] = {
3051         { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
3052         { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
3053         { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
3054         { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
3055         { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
3056         { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
3057         { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
3058         { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
3059         { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
3060         { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
3061         { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
3062         { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
3063         { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
3064         { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
3065         { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
3066         { 0, 0, 0, 0 }
3067 };
3068  
3069 static void target_to_host_termios (void *dst, const void *src)
3070 {
3071     struct host_termios *host = dst;
3072     const struct target_termios *target = src;
3073  
3074     host->c_iflag =
3075         target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
3076     host->c_oflag =
3077         target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
3078     host->c_cflag =
3079         target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
3080     host->c_lflag =
3081         target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
3082     host->c_line = target->c_line;
3083  
3084     memset(host->c_cc, 0, sizeof(host->c_cc));
3085     host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
3086     host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
3087     host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
3088     host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
3089     host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
3090     host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
3091     host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
3092     host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
3093     host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
3094     host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
3095     host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
3096     host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
3097     host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
3098     host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
3099     host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
3100     host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
3101     host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
3102 }
3103  
3104 static void host_to_target_termios (void *dst, const void *src)
3105 {
3106     struct target_termios *target = dst;
3107     const struct host_termios *host = src;
3108  
3109     target->c_iflag =
3110         tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
3111     target->c_oflag =
3112         tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
3113     target->c_cflag =
3114         tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
3115     target->c_lflag =
3116         tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
3117     target->c_line = host->c_line;
3118  
3119     memset(target->c_cc, 0, sizeof(target->c_cc));
3120     target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
3121     target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
3122     target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
3123     target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
3124     target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
3125     target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
3126     target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
3127     target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
3128     target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
3129     target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
3130     target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
3131     target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
3132     target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
3133     target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
3134     target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
3135     target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
3136     target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
3137 }
3138  
3139 static const StructEntry struct_termios_def = {
3140     .convert = { host_to_target_termios, target_to_host_termios },
3141     .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
3142     .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
3143 };
3144  
3145 static bitmask_transtbl mmap_flags_tbl[] = {
3146         { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
3147         { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
3148         { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
3149         { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
3150         { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
3151         { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
3152         { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
3153         { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
3154         { 0, 0, 0, 0 }
3155 };
3156  
3157 #if defined(TARGET_I386)
3158  
3159 /* NOTE: there is really one LDT for all the threads */
3160 static uint8_t *ldt_table;
3161  
3162 static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
3163 {
3164     int size;
3165     void *p;
3166  
3167     if (!ldt_table)
3168         return 0;
3169     size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
3170     if (size > bytecount)
3171         size = bytecount;
3172     p = lock_user(VERIFY_WRITE, ptr, size, 0);
3173     if (!p)
3174         return -TARGET_EFAULT;
3175     /* ??? Should this by byteswapped?  */
3176     memcpy(p, ldt_table, size);
3177     unlock_user(p, ptr, size);
3178     return size;
3179 }
3180  
3181 /* XXX: add locking support */
3182 static abi_long write_ldt(CPUX86State *env,
3183                           abi_ulong ptr, unsigned long bytecount, int oldmode)
3184 {
3185     struct target_modify_ldt_ldt_s ldt_info;
3186     struct target_modify_ldt_ldt_s *target_ldt_info;
3187     int seg_32bit, contents, read_exec_only, limit_in_pages;
3188     int seg_not_present, useable, lm;
3189     uint32_t *lp, entry_1, entry_2;
3190  
3191     if (bytecount != sizeof(ldt_info))
3192         return -TARGET_EINVAL;
3193     if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
3194         return -TARGET_EFAULT;
3195     ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3196     ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
3197     ldt_info.limit = tswap32(target_ldt_info->limit);
3198     ldt_info.flags = tswap32(target_ldt_info->flags);
3199     unlock_user_struct(target_ldt_info, ptr, 0);
3200  
3201     if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
3202         return -TARGET_EINVAL;
3203     seg_32bit = ldt_info.flags & 1;
3204     contents = (ldt_info.flags >> 1) & 3;
3205     read_exec_only = (ldt_info.flags >> 3) & 1;
3206     limit_in_pages = (ldt_info.flags >> 4) & 1;
3207     seg_not_present = (ldt_info.flags >> 5) & 1;
3208     useable = (ldt_info.flags >> 6) & 1;
3209 #ifdef TARGET_ABI32
3210     lm = 0;
3211 #else
3212     lm = (ldt_info.flags >> 7) & 1;
3213 #endif
3214     if (contents == 3) {
3215         if (oldmode)
3216             return -TARGET_EINVAL;
3217         if (seg_not_present == 0)
3218             return -TARGET_EINVAL;
3219     }
3220     /* allocate the LDT */
3221     if (!ldt_table) {
3222         env->ldt.base = target_mmap(0,
3223                                     TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
3224                                     PROT_READ|PROT_WRITE,
3225                                     MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
3226         if (env->ldt.base == -1)
3227             return -TARGET_ENOMEM;
3228         memset(g2h(env->ldt.base), 0,
3229                TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
3230         env->ldt.limit = 0xffff;
3231         ldt_table = g2h(env->ldt.base);
3232     }
3233  
3234     /* NOTE: same code as Linux kernel */
3235     /* Allow LDTs to be cleared by the user. */
3236     if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3237         if (oldmode ||
3238             (contents == 0              &&
3239              read_exec_only == 1        &&
3240              seg_32bit == 0             &&
3241              limit_in_pages == 0        &&
3242              seg_not_present == 1       &&
3243              useable == 0 )) {
3244             entry_1 = 0;
3245             entry_2 = 0;
3246             goto install;
3247         }
3248     }
3249  
3250     entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
3251         (ldt_info.limit & 0x0ffff);
3252     entry_2 = (ldt_info.base_addr & 0xff000000) |
3253         ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3254         (ldt_info.limit & 0xf0000) |
3255         ((read_exec_only ^ 1) << 9) |
3256         (contents << 10) |
3257         ((seg_not_present ^ 1) << 15) |
3258         (seg_32bit << 22) |
3259         (limit_in_pages << 23) |
3260         (lm << 21) |
3261         0x7000;
3262     if (!oldmode)
3263         entry_2 |= (useable << 20);
3264  
3265     /* Install the new entry ...  */
3266 install:
3267     lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
3268     lp[0] = tswap32(entry_1);
3269     lp[1] = tswap32(entry_2);
3270     return 0;
3271 }
3272  
3273 /* specific and weird i386 syscalls */
3274 static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
3275                               unsigned long bytecount)
3276 {
3277     abi_long ret;
3278  
3279     switch (func) {
3280     case 0:
3281         ret = read_ldt(ptr, bytecount);
3282         break;
3283     case 1:
3284         ret = write_ldt(env, ptr, bytecount, 1);
3285         break;
3286     case 0x11:
3287         ret = write_ldt(env, ptr, bytecount, 0);
3288         break;
3289     default:
3290         ret = -TARGET_ENOSYS;
3291         break;
3292     }
3293     return ret;
3294 }
3295  
3296 #if defined(TARGET_I386) && defined(TARGET_ABI32)
3297 static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
3298 {
3299     uint64_t *gdt_table = g2h(env->gdt.base);
3300     struct target_modify_ldt_ldt_s ldt_info;
3301     struct target_modify_ldt_ldt_s *target_ldt_info;
3302     int seg_32bit, contents, read_exec_only, limit_in_pages;
3303     int seg_not_present, useable, lm;
3304     uint32_t