Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ a6f79cc9

History | View | Annotate | Download (259.3 kB)

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
#ifdef __ia64__
45
int __clone2(int (*fn)(void *), void *child_stack_base,
46
             size_t stack_size, int flags, void *arg, ...);
47
#endif
48
#include <sys/socket.h>
49
#include <sys/un.h>
50
#include <sys/uio.h>
51
#include <sys/poll.h>
52
#include <sys/times.h>
53
#include <sys/shm.h>
54
#include <sys/sem.h>
55
#include <sys/statfs.h>
56
#include <utime.h>
57
#include <sys/sysinfo.h>
58
#include <sys/utsname.h>
59
//#include <sys/user.h>
60
#include <netinet/ip.h>
61
#include <netinet/tcp.h>
62
#include <linux/wireless.h>
63
#include "qemu-common.h"
64
#ifdef TARGET_GPROF
65
#include <sys/gmon.h>
66
#endif
67
#ifdef CONFIG_EVENTFD
68
#include <sys/eventfd.h>
69
#endif
70
#ifdef CONFIG_EPOLL
71
#include <sys/epoll.h>
72
#endif
73
#ifdef CONFIG_ATTR
74
#include "qemu-xattr.h"
75
#endif
76

    
77
#define termios host_termios
78
#define winsize host_winsize
79
#define termio host_termio
80
#define sgttyb host_sgttyb /* same as target */
81
#define tchars host_tchars /* same as target */
82
#define ltchars host_ltchars /* same as target */
83

    
84
#include <linux/termios.h>
85
#include <linux/unistd.h>
86
#include <linux/utsname.h>
87
#include <linux/cdrom.h>
88
#include <linux/hdreg.h>
89
#include <linux/soundcard.h>
90
#include <linux/kd.h>
91
#include <linux/mtio.h>
92
#include <linux/fs.h>
93
#if defined(CONFIG_FIEMAP)
94
#include <linux/fiemap.h>
95
#endif
96
#include <linux/fb.h>
97
#include <linux/vt.h>
98
#include "linux_loop.h"
99
#include "cpu-uname.h"
100

    
101
#include "qemu.h"
102

    
103
#if defined(CONFIG_USE_NPTL)
104
#define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
105
    CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
106
#else
107
/* XXX: Hardcode the above values.  */
108
#define CLONE_NPTL_FLAGS2 0
109
#endif
110

    
111
//#define DEBUG
112

    
113
//#include <linux/msdos_fs.h>
114
#define        VFAT_IOCTL_READDIR_BOTH                _IOR('r', 1, struct linux_dirent [2])
115
#define        VFAT_IOCTL_READDIR_SHORT        _IOR('r', 2, struct linux_dirent [2])
116

    
117

    
118
#undef _syscall0
119
#undef _syscall1
120
#undef _syscall2
121
#undef _syscall3
122
#undef _syscall4
123
#undef _syscall5
124
#undef _syscall6
125

    
126
#define _syscall0(type,name)                \
127
static type name (void)                        \
128
{                                        \
129
        return syscall(__NR_##name);        \
130
}
131

    
132
#define _syscall1(type,name,type1,arg1)                \
133
static type name (type1 arg1)                        \
134
{                                                \
135
        return syscall(__NR_##name, arg1);        \
136
}
137

    
138
#define _syscall2(type,name,type1,arg1,type2,arg2)        \
139
static type name (type1 arg1,type2 arg2)                \
140
{                                                        \
141
        return syscall(__NR_##name, arg1, arg2);        \
142
}
143

    
144
#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)        \
145
static type name (type1 arg1,type2 arg2,type3 arg3)                \
146
{                                                                \
147
        return syscall(__NR_##name, arg1, arg2, arg3);                \
148
}
149

    
150
#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)        \
151
static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4)                        \
152
{                                                                                \
153
        return syscall(__NR_##name, arg1, arg2, arg3, arg4);                        \
154
}
155

    
156
#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,        \
157
                  type5,arg5)                                                        \
158
static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5)        \
159
{                                                                                \
160
        return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5);                \
161
}
162

    
163

    
164
#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,        \
165
                  type5,arg5,type6,arg6)                                        \
166
static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,        \
167
                  type6 arg6)                                                        \
168
{                                                                                \
169
        return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6);        \
170
}
171

    
172

    
173
#define __NR_sys_uname __NR_uname
174
#define __NR_sys_faccessat __NR_faccessat
175
#define __NR_sys_fchmodat __NR_fchmodat
176
#define __NR_sys_fchownat __NR_fchownat
177
#define __NR_sys_fstatat64 __NR_fstatat64
178
#define __NR_sys_futimesat __NR_futimesat
179
#define __NR_sys_getcwd1 __NR_getcwd
180
#define __NR_sys_getdents __NR_getdents
181
#define __NR_sys_getdents64 __NR_getdents64
182
#define __NR_sys_getpriority __NR_getpriority
183
#define __NR_sys_linkat __NR_linkat
184
#define __NR_sys_mkdirat __NR_mkdirat
185
#define __NR_sys_mknodat __NR_mknodat
186
#define __NR_sys_newfstatat __NR_newfstatat
187
#define __NR_sys_openat __NR_openat
188
#define __NR_sys_readlinkat __NR_readlinkat
189
#define __NR_sys_renameat __NR_renameat
190
#define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
191
#define __NR_sys_symlinkat __NR_symlinkat
192
#define __NR_sys_syslog __NR_syslog
193
#define __NR_sys_tgkill __NR_tgkill
194
#define __NR_sys_tkill __NR_tkill
195
#define __NR_sys_unlinkat __NR_unlinkat
196
#define __NR_sys_utimensat __NR_utimensat
197
#define __NR_sys_futex __NR_futex
198
#define __NR_sys_inotify_init __NR_inotify_init
199
#define __NR_sys_inotify_add_watch __NR_inotify_add_watch
200
#define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
201

    
202
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) || \
203
    defined(__s390x__)
204
#define __NR__llseek __NR_lseek
205
#endif
206

    
207
#ifdef __NR_gettid
208
_syscall0(int, gettid)
209
#else
210
/* This is a replacement for the host gettid() and must return a host
211
   errno. */
212
static int gettid(void) {
213
    return -ENOSYS;
214
}
215
#endif
216
_syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
217
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
218
_syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
219
#endif
220
_syscall2(int, sys_getpriority, int, which, int, who);
221
#if defined(TARGET_NR__llseek) && defined(__NR_llseek)
222
_syscall5(int, _llseek,  uint,  fd, ulong, hi, ulong, lo,
223
          loff_t *, res, uint, wh);
224
#endif
225
_syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
226
_syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
227
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
228
_syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
229
#endif
230
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
231
_syscall2(int,sys_tkill,int,tid,int,sig)
232
#endif
233
#ifdef __NR_exit_group
234
_syscall1(int,exit_group,int,error_code)
235
#endif
236
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
237
_syscall1(int,set_tid_address,int *,tidptr)
238
#endif
239
#if defined(CONFIG_USE_NPTL)
240
#if defined(TARGET_NR_futex) && defined(__NR_futex)
241
_syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
242
          const struct timespec *,timeout,int *,uaddr2,int,val3)
243
#endif
244
#endif
245
#define __NR_sys_sched_getaffinity __NR_sched_getaffinity
246
_syscall3(int, sys_sched_getaffinity, pid_t, pid, unsigned int, len,
247
          unsigned long *, user_mask_ptr);
248
#define __NR_sys_sched_setaffinity __NR_sched_setaffinity
249
_syscall3(int, sys_sched_setaffinity, pid_t, pid, unsigned int, len,
250
          unsigned long *, user_mask_ptr);
251
_syscall4(int, reboot, int, magic1, int, magic2, unsigned int, cmd,
252
          void *, arg);
253

    
254
static bitmask_transtbl fcntl_flags_tbl[] = {
255
  { TARGET_O_ACCMODE,   TARGET_O_WRONLY,    O_ACCMODE,   O_WRONLY,    },
256
  { TARGET_O_ACCMODE,   TARGET_O_RDWR,      O_ACCMODE,   O_RDWR,      },
257
  { TARGET_O_CREAT,     TARGET_O_CREAT,     O_CREAT,     O_CREAT,     },
258
  { TARGET_O_EXCL,      TARGET_O_EXCL,      O_EXCL,      O_EXCL,      },
259
  { TARGET_O_NOCTTY,    TARGET_O_NOCTTY,    O_NOCTTY,    O_NOCTTY,    },
260
  { TARGET_O_TRUNC,     TARGET_O_TRUNC,     O_TRUNC,     O_TRUNC,     },
261
  { TARGET_O_APPEND,    TARGET_O_APPEND,    O_APPEND,    O_APPEND,    },
262
  { TARGET_O_NONBLOCK,  TARGET_O_NONBLOCK,  O_NONBLOCK,  O_NONBLOCK,  },
263
  { TARGET_O_SYNC,      TARGET_O_SYNC,      O_SYNC,      O_SYNC,      },
264
  { TARGET_FASYNC,      TARGET_FASYNC,      FASYNC,      FASYNC,      },
265
  { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
266
  { TARGET_O_NOFOLLOW,  TARGET_O_NOFOLLOW,  O_NOFOLLOW,  O_NOFOLLOW,  },
267
  { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
268
#if defined(O_DIRECT)
269
  { TARGET_O_DIRECT,    TARGET_O_DIRECT,    O_DIRECT,    O_DIRECT,    },
270
#endif
271
  { 0, 0, 0, 0 }
272
};
273

    
274
#define COPY_UTSNAME_FIELD(dest, src) \
275
  do { \
276
      /* __NEW_UTS_LEN doesn't include terminating null */ \
277
      (void) strncpy((dest), (src), __NEW_UTS_LEN); \
278
      (dest)[__NEW_UTS_LEN] = '\0'; \
279
  } while (0)
280

    
281
static int sys_uname(struct new_utsname *buf)
282
{
283
  struct utsname uts_buf;
284

    
285
  if (uname(&uts_buf) < 0)
286
      return (-1);
287

    
288
  /*
289
   * Just in case these have some differences, we
290
   * translate utsname to new_utsname (which is the
291
   * struct linux kernel uses).
292
   */
293

    
294
  memset(buf, 0, sizeof(*buf));
295
  COPY_UTSNAME_FIELD(buf->sysname, uts_buf.sysname);
296
  COPY_UTSNAME_FIELD(buf->nodename, uts_buf.nodename);
297
  COPY_UTSNAME_FIELD(buf->release, uts_buf.release);
298
  COPY_UTSNAME_FIELD(buf->version, uts_buf.version);
299
  COPY_UTSNAME_FIELD(buf->machine, uts_buf.machine);
300
#ifdef _GNU_SOURCE
301
  COPY_UTSNAME_FIELD(buf->domainname, uts_buf.domainname);
302
#endif
303
  return (0);
304

    
305
#undef COPY_UTSNAME_FIELD
306
}
307

    
308
static int sys_getcwd1(char *buf, size_t size)
309
{
310
  if (getcwd(buf, size) == NULL) {
311
      /* getcwd() sets errno */
312
      return (-1);
313
  }
314
  return strlen(buf)+1;
315
}
316

    
317
#ifdef CONFIG_ATFILE
318
/*
319
 * Host system seems to have atfile syscall stubs available.  We
320
 * now enable them one by one as specified by target syscall_nr.h.
321
 */
322

    
323
#ifdef TARGET_NR_faccessat
324
static int sys_faccessat(int dirfd, const char *pathname, int mode)
325
{
326
  return (faccessat(dirfd, pathname, mode, 0));
327
}
328
#endif
329
#ifdef TARGET_NR_fchmodat
330
static int sys_fchmodat(int dirfd, const char *pathname, mode_t mode)
331
{
332
  return (fchmodat(dirfd, pathname, mode, 0));
333
}
334
#endif
335
#if defined(TARGET_NR_fchownat)
336
static int sys_fchownat(int dirfd, const char *pathname, uid_t owner,
337
    gid_t group, int flags)
338
{
339
  return (fchownat(dirfd, pathname, owner, group, flags));
340
}
341
#endif
342
#ifdef __NR_fstatat64
343
static int sys_fstatat64(int dirfd, const char *pathname, struct stat *buf,
344
    int flags)
345
{
346
  return (fstatat(dirfd, pathname, buf, flags));
347
}
348
#endif
349
#ifdef __NR_newfstatat
350
static int sys_newfstatat(int dirfd, const char *pathname, struct stat *buf,
351
    int flags)
352
{
353
  return (fstatat(dirfd, pathname, buf, flags));
354
}
355
#endif
356
#ifdef TARGET_NR_futimesat
357
static int sys_futimesat(int dirfd, const char *pathname,
358
    const struct timeval times[2])
359
{
360
  return (futimesat(dirfd, pathname, times));
361
}
362
#endif
363
#ifdef TARGET_NR_linkat
364
static int sys_linkat(int olddirfd, const char *oldpath,
365
    int newdirfd, const char *newpath, int flags)
366
{
367
  return (linkat(olddirfd, oldpath, newdirfd, newpath, flags));
368
}
369
#endif
370
#ifdef TARGET_NR_mkdirat
371
static int sys_mkdirat(int dirfd, const char *pathname, mode_t mode)
372
{
373
  return (mkdirat(dirfd, pathname, mode));
374
}
375
#endif
376
#ifdef TARGET_NR_mknodat
377
static int sys_mknodat(int dirfd, const char *pathname, mode_t mode,
378
    dev_t dev)
379
{
380
  return (mknodat(dirfd, pathname, mode, dev));
381
}
382
#endif
383
#ifdef TARGET_NR_openat
384
static int sys_openat(int dirfd, const char *pathname, int flags, mode_t mode)
385
{
386
  /*
387
   * open(2) has extra parameter 'mode' when called with
388
   * flag O_CREAT.
389
   */
390
  if ((flags & O_CREAT) != 0) {
391
      return (openat(dirfd, pathname, flags, mode));
392
  }
393
  return (openat(dirfd, pathname, flags));
394
}
395
#endif
396
#ifdef TARGET_NR_readlinkat
397
static int sys_readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz)
398
{
399
  return (readlinkat(dirfd, pathname, buf, bufsiz));
400
}
401
#endif
402
#ifdef TARGET_NR_renameat
403
static int sys_renameat(int olddirfd, const char *oldpath,
404
    int newdirfd, const char *newpath)
405
{
406
  return (renameat(olddirfd, oldpath, newdirfd, newpath));
407
}
408
#endif
409
#ifdef TARGET_NR_symlinkat
410
static int sys_symlinkat(const char *oldpath, int newdirfd, const char *newpath)
411
{
412
  return (symlinkat(oldpath, newdirfd, newpath));
413
}
414
#endif
415
#ifdef TARGET_NR_unlinkat
416
static int sys_unlinkat(int dirfd, const char *pathname, int flags)
417
{
418
  return (unlinkat(dirfd, pathname, flags));
419
}
420
#endif
421
#else /* !CONFIG_ATFILE */
422

    
423
/*
424
 * Try direct syscalls instead
425
 */
426
#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
427
_syscall3(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode)
428
#endif
429
#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
430
_syscall3(int,sys_fchmodat,int,dirfd,const char *,pathname, mode_t,mode)
431
#endif
432
#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
433
_syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
434
          uid_t,owner,gid_t,group,int,flags)
435
#endif
436
#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
437
        defined(__NR_fstatat64)
438
_syscall4(int,sys_fstatat64,int,dirfd,const char *,pathname,
439
          struct stat *,buf,int,flags)
440
#endif
441
#if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
442
_syscall3(int,sys_futimesat,int,dirfd,const char *,pathname,
443
         const struct timeval *,times)
444
#endif
445
#if (defined(TARGET_NR_newfstatat) || defined(TARGET_NR_fstatat64) ) && \
446
        defined(__NR_newfstatat)
447
_syscall4(int,sys_newfstatat,int,dirfd,const char *,pathname,
448
          struct stat *,buf,int,flags)
449
#endif
450
#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
451
_syscall5(int,sys_linkat,int,olddirfd,const char *,oldpath,
452
      int,newdirfd,const char *,newpath,int,flags)
453
#endif
454
#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
455
_syscall3(int,sys_mkdirat,int,dirfd,const char *,pathname,mode_t,mode)
456
#endif
457
#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
458
_syscall4(int,sys_mknodat,int,dirfd,const char *,pathname,
459
          mode_t,mode,dev_t,dev)
460
#endif
461
#if defined(TARGET_NR_openat) && defined(__NR_openat)
462
_syscall4(int,sys_openat,int,dirfd,const char *,pathname,int,flags,mode_t,mode)
463
#endif
464
#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
465
_syscall4(int,sys_readlinkat,int,dirfd,const char *,pathname,
466
          char *,buf,size_t,bufsize)
467
#endif
468
#if defined(TARGET_NR_renameat) && defined(__NR_renameat)
469
_syscall4(int,sys_renameat,int,olddirfd,const char *,oldpath,
470
          int,newdirfd,const char *,newpath)
471
#endif
472
#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
473
_syscall3(int,sys_symlinkat,const char *,oldpath,
474
          int,newdirfd,const char *,newpath)
475
#endif
476
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
477
_syscall3(int,sys_unlinkat,int,dirfd,const char *,pathname,int,flags)
478
#endif
479

    
480
#endif /* CONFIG_ATFILE */
481

    
482
#ifdef CONFIG_UTIMENSAT
483
static int sys_utimensat(int dirfd, const char *pathname,
484
    const struct timespec times[2], int flags)
485
{
486
    if (pathname == NULL)
487
        return futimens(dirfd, times);
488
    else
489
        return utimensat(dirfd, pathname, times, flags);
490
}
491
#else
492
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
493
_syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
494
          const struct timespec *,tsp,int,flags)
495
#endif
496
#endif /* CONFIG_UTIMENSAT  */
497

    
498
#ifdef CONFIG_INOTIFY
499
#include <sys/inotify.h>
500

    
501
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
502
static int sys_inotify_init(void)
503
{
504
  return (inotify_init());
505
}
506
#endif
507
#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
508
static int sys_inotify_add_watch(int fd,const char *pathname, int32_t mask)
509
{
510
  return (inotify_add_watch(fd, pathname, mask));
511
}
512
#endif
513
#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
514
static int sys_inotify_rm_watch(int fd, int32_t wd)
515
{
516
  return (inotify_rm_watch(fd, wd));
517
}
518
#endif
519
#ifdef CONFIG_INOTIFY1
520
#if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
521
static int sys_inotify_init1(int flags)
522
{
523
  return (inotify_init1(flags));
524
}
525
#endif
526
#endif
527
#else
528
/* Userspace can usually survive runtime without inotify */
529
#undef TARGET_NR_inotify_init
530
#undef TARGET_NR_inotify_init1
531
#undef TARGET_NR_inotify_add_watch
532
#undef TARGET_NR_inotify_rm_watch
533
#endif /* CONFIG_INOTIFY  */
534

    
535
#if defined(TARGET_NR_ppoll)
536
#ifndef __NR_ppoll
537
# define __NR_ppoll -1
538
#endif
539
#define __NR_sys_ppoll __NR_ppoll
540
_syscall5(int, sys_ppoll, struct pollfd *, fds, nfds_t, nfds,
541
          struct timespec *, timeout, const __sigset_t *, sigmask,
542
          size_t, sigsetsize)
543
#endif
544

    
545
#if defined(TARGET_NR_pselect6)
546
#ifndef __NR_pselect6
547
# define __NR_pselect6 -1
548
#endif
549
#define __NR_sys_pselect6 __NR_pselect6
550
_syscall6(int, sys_pselect6, int, nfds, fd_set *, readfds, fd_set *, writefds,
551
          fd_set *, exceptfds, struct timespec *, timeout, void *, sig);
552
#endif
553

    
554
#if defined(TARGET_NR_prlimit64)
555
#ifndef __NR_prlimit64
556
# define __NR_prlimit64 -1
557
#endif
558
#define __NR_sys_prlimit64 __NR_prlimit64
559
/* The glibc rlimit structure may not be that used by the underlying syscall */
560
struct host_rlimit64 {
561
    uint64_t rlim_cur;
562
    uint64_t rlim_max;
563
};
564
_syscall4(int, sys_prlimit64, pid_t, pid, int, resource,
565
          const struct host_rlimit64 *, new_limit,
566
          struct host_rlimit64 *, old_limit)
567
#endif
568

    
569
extern int personality(int);
570
extern int flock(int, int);
571
extern int setfsuid(int);
572
extern int setfsgid(int);
573
extern int setgroups(int, gid_t *);
574

    
575
/* ARM EABI and MIPS expect 64bit types aligned even on pairs or registers */
576
#ifdef TARGET_ARM 
577
static inline int regpairs_aligned(void *cpu_env) {
578
    return ((((CPUARMState *)cpu_env)->eabi) == 1) ;
579
}
580
#elif defined(TARGET_MIPS)
581
static inline int regpairs_aligned(void *cpu_env) { return 1; }
582
#else
583
static inline int regpairs_aligned(void *cpu_env) { return 0; }
584
#endif
585

    
586
#define ERRNO_TABLE_SIZE 1200
587

    
588
/* target_to_host_errno_table[] is initialized from
589
 * host_to_target_errno_table[] in syscall_init(). */
590
static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
591
};
592

    
593
/*
594
 * This list is the union of errno values overridden in asm-<arch>/errno.h
595
 * minus the errnos that are not actually generic to all archs.
596
 */
597
static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
598
    [EIDRM]                = TARGET_EIDRM,
599
    [ECHRNG]                = TARGET_ECHRNG,
600
    [EL2NSYNC]                = TARGET_EL2NSYNC,
601
    [EL3HLT]                = TARGET_EL3HLT,
602
    [EL3RST]                = TARGET_EL3RST,
603
    [ELNRNG]                = TARGET_ELNRNG,
604
    [EUNATCH]                = TARGET_EUNATCH,
605
    [ENOCSI]                = TARGET_ENOCSI,
606
    [EL2HLT]                = TARGET_EL2HLT,
607
    [EDEADLK]                = TARGET_EDEADLK,
608
    [ENOLCK]                = TARGET_ENOLCK,
609
    [EBADE]                = TARGET_EBADE,
610
    [EBADR]                = TARGET_EBADR,
611
    [EXFULL]                = TARGET_EXFULL,
612
    [ENOANO]                = TARGET_ENOANO,
613
    [EBADRQC]                = TARGET_EBADRQC,
614
    [EBADSLT]                = TARGET_EBADSLT,
615
    [EBFONT]                = TARGET_EBFONT,
616
    [ENOSTR]                = TARGET_ENOSTR,
617
    [ENODATA]                = TARGET_ENODATA,
618
    [ETIME]                = TARGET_ETIME,
619
    [ENOSR]                = TARGET_ENOSR,
620
    [ENONET]                = TARGET_ENONET,
621
    [ENOPKG]                = TARGET_ENOPKG,
622
    [EREMOTE]                = TARGET_EREMOTE,
623
    [ENOLINK]                = TARGET_ENOLINK,
624
    [EADV]                = TARGET_EADV,
625
    [ESRMNT]                = TARGET_ESRMNT,
626
    [ECOMM]                = TARGET_ECOMM,
627
    [EPROTO]                = TARGET_EPROTO,
628
    [EDOTDOT]                = TARGET_EDOTDOT,
629
    [EMULTIHOP]                = TARGET_EMULTIHOP,
630
    [EBADMSG]                = TARGET_EBADMSG,
631
    [ENAMETOOLONG]        = TARGET_ENAMETOOLONG,
632
    [EOVERFLOW]                = TARGET_EOVERFLOW,
633
    [ENOTUNIQ]                = TARGET_ENOTUNIQ,
634
    [EBADFD]                = TARGET_EBADFD,
635
    [EREMCHG]                = TARGET_EREMCHG,
636
    [ELIBACC]                = TARGET_ELIBACC,
637
    [ELIBBAD]                = TARGET_ELIBBAD,
638
    [ELIBSCN]                = TARGET_ELIBSCN,
639
    [ELIBMAX]                = TARGET_ELIBMAX,
640
    [ELIBEXEC]                = TARGET_ELIBEXEC,
641
    [EILSEQ]                = TARGET_EILSEQ,
642
    [ENOSYS]                = TARGET_ENOSYS,
643
    [ELOOP]                = TARGET_ELOOP,
644
    [ERESTART]                = TARGET_ERESTART,
645
    [ESTRPIPE]                = TARGET_ESTRPIPE,
646
    [ENOTEMPTY]                = TARGET_ENOTEMPTY,
647
    [EUSERS]                = TARGET_EUSERS,
648
    [ENOTSOCK]                = TARGET_ENOTSOCK,
649
    [EDESTADDRREQ]        = TARGET_EDESTADDRREQ,
650
    [EMSGSIZE]                = TARGET_EMSGSIZE,
651
    [EPROTOTYPE]        = TARGET_EPROTOTYPE,
652
    [ENOPROTOOPT]        = TARGET_ENOPROTOOPT,
653
    [EPROTONOSUPPORT]        = TARGET_EPROTONOSUPPORT,
654
    [ESOCKTNOSUPPORT]        = TARGET_ESOCKTNOSUPPORT,
655
    [EOPNOTSUPP]        = TARGET_EOPNOTSUPP,
656
    [EPFNOSUPPORT]        = TARGET_EPFNOSUPPORT,
657
    [EAFNOSUPPORT]        = TARGET_EAFNOSUPPORT,
658
    [EADDRINUSE]        = TARGET_EADDRINUSE,
659
    [EADDRNOTAVAIL]        = TARGET_EADDRNOTAVAIL,
660
    [ENETDOWN]                = TARGET_ENETDOWN,
661
    [ENETUNREACH]        = TARGET_ENETUNREACH,
662
    [ENETRESET]                = TARGET_ENETRESET,
663
    [ECONNABORTED]        = TARGET_ECONNABORTED,
664
    [ECONNRESET]        = TARGET_ECONNRESET,
665
    [ENOBUFS]                = TARGET_ENOBUFS,
666
    [EISCONN]                = TARGET_EISCONN,
667
    [ENOTCONN]                = TARGET_ENOTCONN,
668
    [EUCLEAN]                = TARGET_EUCLEAN,
669
    [ENOTNAM]                = TARGET_ENOTNAM,
670
    [ENAVAIL]                = TARGET_ENAVAIL,
671
    [EISNAM]                = TARGET_EISNAM,
672
    [EREMOTEIO]                = TARGET_EREMOTEIO,
673
    [ESHUTDOWN]                = TARGET_ESHUTDOWN,
674
    [ETOOMANYREFS]        = TARGET_ETOOMANYREFS,
675
    [ETIMEDOUT]                = TARGET_ETIMEDOUT,
676
    [ECONNREFUSED]        = TARGET_ECONNREFUSED,
677
    [EHOSTDOWN]                = TARGET_EHOSTDOWN,
678
    [EHOSTUNREACH]        = TARGET_EHOSTUNREACH,
679
    [EALREADY]                = TARGET_EALREADY,
680
    [EINPROGRESS]        = TARGET_EINPROGRESS,
681
    [ESTALE]                = TARGET_ESTALE,
682
    [ECANCELED]                = TARGET_ECANCELED,
683
    [ENOMEDIUM]                = TARGET_ENOMEDIUM,
684
    [EMEDIUMTYPE]        = TARGET_EMEDIUMTYPE,
685
#ifdef ENOKEY
686
    [ENOKEY]                = TARGET_ENOKEY,
687
#endif
688
#ifdef EKEYEXPIRED
689
    [EKEYEXPIRED]        = TARGET_EKEYEXPIRED,
690
#endif
691
#ifdef EKEYREVOKED
692
    [EKEYREVOKED]        = TARGET_EKEYREVOKED,
693
#endif
694
#ifdef EKEYREJECTED
695
    [EKEYREJECTED]        = TARGET_EKEYREJECTED,
696
#endif
697
#ifdef EOWNERDEAD
698
    [EOWNERDEAD]        = TARGET_EOWNERDEAD,
699
#endif
700
#ifdef ENOTRECOVERABLE
701
    [ENOTRECOVERABLE]        = TARGET_ENOTRECOVERABLE,
702
#endif
703
};
704

    
705
static inline int host_to_target_errno(int err)
706
{
707
    if(host_to_target_errno_table[err])
708
        return host_to_target_errno_table[err];
709
    return err;
710
}
711

    
712
static inline int target_to_host_errno(int err)
713
{
714
    if (target_to_host_errno_table[err])
715
        return target_to_host_errno_table[err];
716
    return err;
717
}
718

    
719
static inline abi_long get_errno(abi_long ret)
720
{
721
    if (ret == -1)
722
        return -host_to_target_errno(errno);
723
    else
724
        return ret;
725
}
726

    
727
static inline int is_error(abi_long ret)
728
{
729
    return (abi_ulong)ret >= (abi_ulong)(-4096);
730
}
731

    
732
char *target_strerror(int err)
733
{
734
    if ((err >= ERRNO_TABLE_SIZE) || (err < 0)) {
735
        return NULL;
736
    }
737
    return strerror(target_to_host_errno(err));
738
}
739

    
740
static abi_ulong target_brk;
741
static abi_ulong target_original_brk;
742
static abi_ulong brk_page;
743

    
744
void target_set_brk(abi_ulong new_brk)
745
{
746
    target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
747
    brk_page = HOST_PAGE_ALIGN(target_brk);
748
}
749

    
750
//#define DEBUGF_BRK(message, args...) do { fprintf(stderr, (message), ## args); } while (0)
751
#define DEBUGF_BRK(message, args...)
752

    
753
/* do_brk() must return target values and target errnos. */
754
abi_long do_brk(abi_ulong new_brk)
755
{
756
    abi_long mapped_addr;
757
    int        new_alloc_size;
758

    
759
    DEBUGF_BRK("do_brk(%#010x) -> ", new_brk);
760

    
761
    if (!new_brk) {
762
        DEBUGF_BRK("%#010x (!new_brk)\n", target_brk);
763
        return target_brk;
764
    }
765
    if (new_brk < target_original_brk) {
766
        DEBUGF_BRK("%#010x (new_brk < target_original_brk)\n", target_brk);
767
        return target_brk;
768
    }
769

    
770
    /* If the new brk is less than the highest page reserved to the
771
     * target heap allocation, set it and we're almost done...  */
772
    if (new_brk <= brk_page) {
773
        /* Heap contents are initialized to zero, as for anonymous
774
         * mapped pages.  */
775
        if (new_brk > target_brk) {
776
            memset(g2h(target_brk), 0, new_brk - target_brk);
777
        }
778
        target_brk = new_brk;
779
        DEBUGF_BRK("%#010x (new_brk <= brk_page)\n", target_brk);
780
            return target_brk;
781
    }
782

    
783
    /* We need to allocate more memory after the brk... Note that
784
     * we don't use MAP_FIXED because that will map over the top of
785
     * any existing mapping (like the one with the host libc or qemu
786
     * itself); instead we treat "mapped but at wrong address" as
787
     * a failure and unmap again.
788
     */
789
    new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page);
790
    mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
791
                                        PROT_READ|PROT_WRITE,
792
                                        MAP_ANON|MAP_PRIVATE, 0, 0));
793

    
794
    if (mapped_addr == brk_page) {
795
        /* Heap contents are initialized to zero, as for anonymous
796
         * mapped pages.  Technically the new pages are already
797
         * initialized to zero since they *are* anonymous mapped
798
         * pages, however we have to take care with the contents that
799
         * come from the remaining part of the previous page: it may
800
         * contains garbage data due to a previous heap usage (grown
801
         * then shrunken).  */
802
        memset(g2h(target_brk), 0, brk_page - target_brk);
803

    
804
        target_brk = new_brk;
805
        brk_page = HOST_PAGE_ALIGN(target_brk);
806
        DEBUGF_BRK("%#010x (mapped_addr == brk_page)\n", target_brk);
807
        return target_brk;
808
    } else if (mapped_addr != -1) {
809
        /* Mapped but at wrong address, meaning there wasn't actually
810
         * enough space for this brk.
811
         */
812
        target_munmap(mapped_addr, new_alloc_size);
813
        mapped_addr = -1;
814
        DEBUGF_BRK("%#010x (mapped_addr != -1)\n", target_brk);
815
    }
816
    else {
817
        DEBUGF_BRK("%#010x (otherwise)\n", target_brk);
818
    }
819

    
820
#if defined(TARGET_ALPHA)
821
    /* We (partially) emulate OSF/1 on Alpha, which requires we
822
       return a proper errno, not an unchanged brk value.  */
823
    return -TARGET_ENOMEM;
824
#endif
825
    /* For everything else, return the previous break. */
826
    return target_brk;
827
}
828

    
829
static inline abi_long copy_from_user_fdset(fd_set *fds,
830
                                            abi_ulong target_fds_addr,
831
                                            int n)
832
{
833
    int i, nw, j, k;
834
    abi_ulong b, *target_fds;
835

    
836
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
837
    if (!(target_fds = lock_user(VERIFY_READ,
838
                                 target_fds_addr,
839
                                 sizeof(abi_ulong) * nw,
840
                                 1)))
841
        return -TARGET_EFAULT;
842

    
843
    FD_ZERO(fds);
844
    k = 0;
845
    for (i = 0; i < nw; i++) {
846
        /* grab the abi_ulong */
847
        __get_user(b, &target_fds[i]);
848
        for (j = 0; j < TARGET_ABI_BITS; j++) {
849
            /* check the bit inside the abi_ulong */
850
            if ((b >> j) & 1)
851
                FD_SET(k, fds);
852
            k++;
853
        }
854
    }
855

    
856
    unlock_user(target_fds, target_fds_addr, 0);
857

    
858
    return 0;
859
}
860

    
861
static inline abi_ulong copy_from_user_fdset_ptr(fd_set *fds, fd_set **fds_ptr,
862
                                                 abi_ulong target_fds_addr,
863
                                                 int n)
864
{
865
    if (target_fds_addr) {
866
        if (copy_from_user_fdset(fds, target_fds_addr, n))
867
            return -TARGET_EFAULT;
868
        *fds_ptr = fds;
869
    } else {
870
        *fds_ptr = NULL;
871
    }
872
    return 0;
873
}
874

    
875
static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
876
                                          const fd_set *fds,
877
                                          int n)
878
{
879
    int i, nw, j, k;
880
    abi_long v;
881
    abi_ulong *target_fds;
882

    
883
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
884
    if (!(target_fds = lock_user(VERIFY_WRITE,
885
                                 target_fds_addr,
886
                                 sizeof(abi_ulong) * nw,
887
                                 0)))
888
        return -TARGET_EFAULT;
889

    
890
    k = 0;
891
    for (i = 0; i < nw; i++) {
892
        v = 0;
893
        for (j = 0; j < TARGET_ABI_BITS; j++) {
894
            v |= ((FD_ISSET(k, fds) != 0) << j);
895
            k++;
896
        }
897
        __put_user(v, &target_fds[i]);
898
    }
899

    
900
    unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
901

    
902
    return 0;
903
}
904

    
905
#if defined(__alpha__)
906
#define HOST_HZ 1024
907
#else
908
#define HOST_HZ 100
909
#endif
910

    
911
static inline abi_long host_to_target_clock_t(long ticks)
912
{
913
#if HOST_HZ == TARGET_HZ
914
    return ticks;
915
#else
916
    return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
917
#endif
918
}
919

    
920
static inline abi_long host_to_target_rusage(abi_ulong target_addr,
921
                                             const struct rusage *rusage)
922
{
923
    struct target_rusage *target_rusage;
924

    
925
    if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
926
        return -TARGET_EFAULT;
927
    target_rusage->ru_utime.tv_sec = tswapal(rusage->ru_utime.tv_sec);
928
    target_rusage->ru_utime.tv_usec = tswapal(rusage->ru_utime.tv_usec);
929
    target_rusage->ru_stime.tv_sec = tswapal(rusage->ru_stime.tv_sec);
930
    target_rusage->ru_stime.tv_usec = tswapal(rusage->ru_stime.tv_usec);
931
    target_rusage->ru_maxrss = tswapal(rusage->ru_maxrss);
932
    target_rusage->ru_ixrss = tswapal(rusage->ru_ixrss);
933
    target_rusage->ru_idrss = tswapal(rusage->ru_idrss);
934
    target_rusage->ru_isrss = tswapal(rusage->ru_isrss);
935
    target_rusage->ru_minflt = tswapal(rusage->ru_minflt);
936
    target_rusage->ru_majflt = tswapal(rusage->ru_majflt);
937
    target_rusage->ru_nswap = tswapal(rusage->ru_nswap);
938
    target_rusage->ru_inblock = tswapal(rusage->ru_inblock);
939
    target_rusage->ru_oublock = tswapal(rusage->ru_oublock);
940
    target_rusage->ru_msgsnd = tswapal(rusage->ru_msgsnd);
941
    target_rusage->ru_msgrcv = tswapal(rusage->ru_msgrcv);
942
    target_rusage->ru_nsignals = tswapal(rusage->ru_nsignals);
943
    target_rusage->ru_nvcsw = tswapal(rusage->ru_nvcsw);
944
    target_rusage->ru_nivcsw = tswapal(rusage->ru_nivcsw);
945
    unlock_user_struct(target_rusage, target_addr, 1);
946

    
947
    return 0;
948
}
949

    
950
static inline rlim_t target_to_host_rlim(abi_ulong target_rlim)
951
{
952
    abi_ulong target_rlim_swap;
953
    rlim_t result;
954
    
955
    target_rlim_swap = tswapal(target_rlim);
956
    if (target_rlim_swap == TARGET_RLIM_INFINITY)
957
        return RLIM_INFINITY;
958

    
959
    result = target_rlim_swap;
960
    if (target_rlim_swap != (rlim_t)result)
961
        return RLIM_INFINITY;
962
    
963
    return result;
964
}
965

    
966
static inline abi_ulong host_to_target_rlim(rlim_t rlim)
967
{
968
    abi_ulong target_rlim_swap;
969
    abi_ulong result;
970
    
971
    if (rlim == RLIM_INFINITY || rlim != (abi_long)rlim)
972
        target_rlim_swap = TARGET_RLIM_INFINITY;
973
    else
974
        target_rlim_swap = rlim;
975
    result = tswapal(target_rlim_swap);
976
    
977
    return result;
978
}
979

    
980
static inline int target_to_host_resource(int code)
981
{
982
    switch (code) {
983
    case TARGET_RLIMIT_AS:
984
        return RLIMIT_AS;
985
    case TARGET_RLIMIT_CORE:
986
        return RLIMIT_CORE;
987
    case TARGET_RLIMIT_CPU:
988
        return RLIMIT_CPU;
989
    case TARGET_RLIMIT_DATA:
990
        return RLIMIT_DATA;
991
    case TARGET_RLIMIT_FSIZE:
992
        return RLIMIT_FSIZE;
993
    case TARGET_RLIMIT_LOCKS:
994
        return RLIMIT_LOCKS;
995
    case TARGET_RLIMIT_MEMLOCK:
996
        return RLIMIT_MEMLOCK;
997
    case TARGET_RLIMIT_MSGQUEUE:
998
        return RLIMIT_MSGQUEUE;
999
    case TARGET_RLIMIT_NICE:
1000
        return RLIMIT_NICE;
1001
    case TARGET_RLIMIT_NOFILE:
1002
        return RLIMIT_NOFILE;
1003
    case TARGET_RLIMIT_NPROC:
1004
        return RLIMIT_NPROC;
1005
    case TARGET_RLIMIT_RSS:
1006
        return RLIMIT_RSS;
1007
    case TARGET_RLIMIT_RTPRIO:
1008
        return RLIMIT_RTPRIO;
1009
    case TARGET_RLIMIT_SIGPENDING:
1010
        return RLIMIT_SIGPENDING;
1011
    case TARGET_RLIMIT_STACK:
1012
        return RLIMIT_STACK;
1013
    default:
1014
        return code;
1015
    }
1016
}
1017

    
1018
static inline abi_long copy_from_user_timeval(struct timeval *tv,
1019
                                              abi_ulong target_tv_addr)
1020
{
1021
    struct target_timeval *target_tv;
1022

    
1023
    if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
1024
        return -TARGET_EFAULT;
1025

    
1026
    __get_user(tv->tv_sec, &target_tv->tv_sec);
1027
    __get_user(tv->tv_usec, &target_tv->tv_usec);
1028

    
1029
    unlock_user_struct(target_tv, target_tv_addr, 0);
1030

    
1031
    return 0;
1032
}
1033

    
1034
static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
1035
                                            const struct timeval *tv)
1036
{
1037
    struct target_timeval *target_tv;
1038

    
1039
    if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
1040
        return -TARGET_EFAULT;
1041

    
1042
    __put_user(tv->tv_sec, &target_tv->tv_sec);
1043
    __put_user(tv->tv_usec, &target_tv->tv_usec);
1044

    
1045
    unlock_user_struct(target_tv, target_tv_addr, 1);
1046

    
1047
    return 0;
1048
}
1049

    
1050
#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
1051
#include <mqueue.h>
1052

    
1053
static inline abi_long copy_from_user_mq_attr(struct mq_attr *attr,
1054
                                              abi_ulong target_mq_attr_addr)
1055
{
1056
    struct target_mq_attr *target_mq_attr;
1057

    
1058
    if (!lock_user_struct(VERIFY_READ, target_mq_attr,
1059
                          target_mq_attr_addr, 1))
1060
        return -TARGET_EFAULT;
1061

    
1062
    __get_user(attr->mq_flags, &target_mq_attr->mq_flags);
1063
    __get_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
1064
    __get_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
1065
    __get_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
1066

    
1067
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0);
1068

    
1069
    return 0;
1070
}
1071

    
1072
static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr,
1073
                                            const struct mq_attr *attr)
1074
{
1075
    struct target_mq_attr *target_mq_attr;
1076

    
1077
    if (!lock_user_struct(VERIFY_WRITE, target_mq_attr,
1078
                          target_mq_attr_addr, 0))
1079
        return -TARGET_EFAULT;
1080

    
1081
    __put_user(attr->mq_flags, &target_mq_attr->mq_flags);
1082
    __put_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
1083
    __put_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
1084
    __put_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
1085

    
1086
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1);
1087

    
1088
    return 0;
1089
}
1090
#endif
1091

    
1092
#if defined(TARGET_NR_select) || defined(TARGET_NR__newselect)
1093
/* do_select() must return target values and target errnos. */
1094
static abi_long do_select(int n,
1095
                          abi_ulong rfd_addr, abi_ulong wfd_addr,
1096
                          abi_ulong efd_addr, abi_ulong target_tv_addr)
1097
{
1098
    fd_set rfds, wfds, efds;
1099
    fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
1100
    struct timeval tv, *tv_ptr;
1101
    abi_long ret;
1102

    
1103
    ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
1104
    if (ret) {
1105
        return ret;
1106
    }
1107
    ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
1108
    if (ret) {
1109
        return ret;
1110
    }
1111
    ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
1112
    if (ret) {
1113
        return ret;
1114
    }
1115

    
1116
    if (target_tv_addr) {
1117
        if (copy_from_user_timeval(&tv, target_tv_addr))
1118
            return -TARGET_EFAULT;
1119
        tv_ptr = &tv;
1120
    } else {
1121
        tv_ptr = NULL;
1122
    }
1123

    
1124
    ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
1125

    
1126
    if (!is_error(ret)) {
1127
        if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
1128
            return -TARGET_EFAULT;
1129
        if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
1130
            return -TARGET_EFAULT;
1131
        if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
1132
            return -TARGET_EFAULT;
1133

    
1134
        if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
1135
            return -TARGET_EFAULT;
1136
    }
1137

    
1138
    return ret;
1139
}
1140
#endif
1141

    
1142
static abi_long do_pipe2(int host_pipe[], int flags)
1143
{
1144
#ifdef CONFIG_PIPE2
1145
    return pipe2(host_pipe, flags);
1146
#else
1147
    return -ENOSYS;
1148
#endif
1149
}
1150

    
1151
static abi_long do_pipe(void *cpu_env, abi_ulong pipedes,
1152
                        int flags, int is_pipe2)
1153
{
1154
    int host_pipe[2];
1155
    abi_long ret;
1156
    ret = flags ? do_pipe2(host_pipe, flags) : pipe(host_pipe);
1157

    
1158
    if (is_error(ret))
1159
        return get_errno(ret);
1160

    
1161
    /* Several targets have special calling conventions for the original
1162
       pipe syscall, but didn't replicate this into the pipe2 syscall.  */
1163
    if (!is_pipe2) {
1164
#if defined(TARGET_ALPHA)
1165
        ((CPUAlphaState *)cpu_env)->ir[IR_A4] = host_pipe[1];
1166
        return host_pipe[0];
1167
#elif defined(TARGET_MIPS)
1168
        ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1];
1169
        return host_pipe[0];
1170
#elif defined(TARGET_SH4)
1171
        ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
1172
        return host_pipe[0];
1173
#endif
1174
    }
1175

    
1176
    if (put_user_s32(host_pipe[0], pipedes)
1177
        || put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0])))
1178
        return -TARGET_EFAULT;
1179
    return get_errno(ret);
1180
}
1181

    
1182
static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn,
1183
                                              abi_ulong target_addr,
1184
                                              socklen_t len)
1185
{
1186
    struct target_ip_mreqn *target_smreqn;
1187

    
1188
    target_smreqn = lock_user(VERIFY_READ, target_addr, len, 1);
1189
    if (!target_smreqn)
1190
        return -TARGET_EFAULT;
1191
    mreqn->imr_multiaddr.s_addr = target_smreqn->imr_multiaddr.s_addr;
1192
    mreqn->imr_address.s_addr = target_smreqn->imr_address.s_addr;
1193
    if (len == sizeof(struct target_ip_mreqn))
1194
        mreqn->imr_ifindex = tswapal(target_smreqn->imr_ifindex);
1195
    unlock_user(target_smreqn, target_addr, 0);
1196

    
1197
    return 0;
1198
}
1199

    
1200
static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
1201
                                               abi_ulong target_addr,
1202
                                               socklen_t len)
1203
{
1204
    const socklen_t unix_maxlen = sizeof (struct sockaddr_un);
1205
    sa_family_t sa_family;
1206
    struct target_sockaddr *target_saddr;
1207

    
1208
    target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
1209
    if (!target_saddr)
1210
        return -TARGET_EFAULT;
1211

    
1212
    sa_family = tswap16(target_saddr->sa_family);
1213

    
1214
    /* Oops. The caller might send a incomplete sun_path; sun_path
1215
     * must be terminated by \0 (see the manual page), but
1216
     * unfortunately it is quite common to specify sockaddr_un
1217
     * length as "strlen(x->sun_path)" while it should be
1218
     * "strlen(...) + 1". We'll fix that here if needed.
1219
     * Linux kernel has a similar feature.
1220
     */
1221

    
1222
    if (sa_family == AF_UNIX) {
1223
        if (len < unix_maxlen && len > 0) {
1224
            char *cp = (char*)target_saddr;
1225

    
1226
            if ( cp[len-1] && !cp[len] )
1227
                len++;
1228
        }
1229
        if (len > unix_maxlen)
1230
            len = unix_maxlen;
1231
    }
1232

    
1233
    memcpy(addr, target_saddr, len);
1234
    addr->sa_family = sa_family;
1235
    unlock_user(target_saddr, target_addr, 0);
1236

    
1237
    return 0;
1238
}
1239

    
1240
static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
1241
                                               struct sockaddr *addr,
1242
                                               socklen_t len)
1243
{
1244
    struct target_sockaddr *target_saddr;
1245

    
1246
    target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
1247
    if (!target_saddr)
1248
        return -TARGET_EFAULT;
1249
    memcpy(target_saddr, addr, len);
1250
    target_saddr->sa_family = tswap16(addr->sa_family);
1251
    unlock_user(target_saddr, target_addr, len);
1252

    
1253
    return 0;
1254
}
1255

    
1256
/* ??? Should this also swap msgh->name?  */
1257
static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
1258
                                           struct target_msghdr *target_msgh)
1259
{
1260
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1261
    abi_long msg_controllen;
1262
    abi_ulong target_cmsg_addr;
1263
    struct target_cmsghdr *target_cmsg;
1264
    socklen_t space = 0;
1265
    
1266
    msg_controllen = tswapal(target_msgh->msg_controllen);
1267
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1268
        goto the_end;
1269
    target_cmsg_addr = tswapal(target_msgh->msg_control);
1270
    target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
1271
    if (!target_cmsg)
1272
        return -TARGET_EFAULT;
1273

    
1274
    while (cmsg && target_cmsg) {
1275
        void *data = CMSG_DATA(cmsg);
1276
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
1277

    
1278
        int len = tswapal(target_cmsg->cmsg_len)
1279
                  - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
1280

    
1281
        space += CMSG_SPACE(len);
1282
        if (space > msgh->msg_controllen) {
1283
            space -= CMSG_SPACE(len);
1284
            gemu_log("Host cmsg overflow\n");
1285
            break;
1286
        }
1287

    
1288
        cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
1289
        cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
1290
        cmsg->cmsg_len = CMSG_LEN(len);
1291

    
1292
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1293
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1294
            memcpy(data, target_data, len);
1295
        } else {
1296
            int *fd = (int *)data;
1297
            int *target_fd = (int *)target_data;
1298
            int i, numfds = len / sizeof(int);
1299

    
1300
            for (i = 0; i < numfds; i++)
1301
                fd[i] = tswap32(target_fd[i]);
1302
        }
1303

    
1304
        cmsg = CMSG_NXTHDR(msgh, cmsg);
1305
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1306
    }
1307
    unlock_user(target_cmsg, target_cmsg_addr, 0);
1308
 the_end:
1309
    msgh->msg_controllen = space;
1310
    return 0;
1311
}
1312

    
1313
/* ??? Should this also swap msgh->name?  */
1314
static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
1315
                                           struct msghdr *msgh)
1316
{
1317
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1318
    abi_long msg_controllen;
1319
    abi_ulong target_cmsg_addr;
1320
    struct target_cmsghdr *target_cmsg;
1321
    socklen_t space = 0;
1322

    
1323
    msg_controllen = tswapal(target_msgh->msg_controllen);
1324
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1325
        goto the_end;
1326
    target_cmsg_addr = tswapal(target_msgh->msg_control);
1327
    target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
1328
    if (!target_cmsg)
1329
        return -TARGET_EFAULT;
1330

    
1331
    while (cmsg && target_cmsg) {
1332
        void *data = CMSG_DATA(cmsg);
1333
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
1334

    
1335
        int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
1336

    
1337
        space += TARGET_CMSG_SPACE(len);
1338
        if (space > msg_controllen) {
1339
            space -= TARGET_CMSG_SPACE(len);
1340
            gemu_log("Target cmsg overflow\n");
1341
            break;
1342
        }
1343

    
1344
        target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
1345
        target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
1346
        target_cmsg->cmsg_len = tswapal(TARGET_CMSG_LEN(len));
1347

    
1348
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1349
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1350
            memcpy(target_data, data, len);
1351
        } else {
1352
            int *fd = (int *)data;
1353
            int *target_fd = (int *)target_data;
1354
            int i, numfds = len / sizeof(int);
1355

    
1356
            for (i = 0; i < numfds; i++)
1357
                target_fd[i] = tswap32(fd[i]);
1358
        }
1359

    
1360
        cmsg = CMSG_NXTHDR(msgh, cmsg);
1361
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1362
    }
1363
    unlock_user(target_cmsg, target_cmsg_addr, space);
1364
 the_end:
1365
    target_msgh->msg_controllen = tswapal(space);
1366
    return 0;
1367
}
1368

    
1369
/* do_setsockopt() Must return target values and target errnos. */
1370
static abi_long do_setsockopt(int sockfd, int level, int optname,
1371
                              abi_ulong optval_addr, socklen_t optlen)
1372
{
1373
    abi_long ret;
1374
    int val;
1375
    struct ip_mreqn *ip_mreq;
1376
    struct ip_mreq_source *ip_mreq_source;
1377

    
1378
    switch(level) {
1379
    case SOL_TCP:
1380
        /* TCP options all take an 'int' value.  */
1381
        if (optlen < sizeof(uint32_t))
1382
            return -TARGET_EINVAL;
1383

    
1384
        if (get_user_u32(val, optval_addr))
1385
            return -TARGET_EFAULT;
1386
        ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1387
        break;
1388
    case SOL_IP:
1389
        switch(optname) {
1390
        case IP_TOS:
1391
        case IP_TTL:
1392
        case IP_HDRINCL:
1393
        case IP_ROUTER_ALERT:
1394
        case IP_RECVOPTS:
1395
        case IP_RETOPTS:
1396
        case IP_PKTINFO:
1397
        case IP_MTU_DISCOVER:
1398
        case IP_RECVERR:
1399
        case IP_RECVTOS:
1400
#ifdef IP_FREEBIND
1401
        case IP_FREEBIND:
1402
#endif
1403
        case IP_MULTICAST_TTL:
1404
        case IP_MULTICAST_LOOP:
1405
            val = 0;
1406
            if (optlen >= sizeof(uint32_t)) {
1407
                if (get_user_u32(val, optval_addr))
1408
                    return -TARGET_EFAULT;
1409
            } else if (optlen >= 1) {
1410
                if (get_user_u8(val, optval_addr))
1411
                    return -TARGET_EFAULT;
1412
            }
1413
            ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1414
            break;
1415
        case IP_ADD_MEMBERSHIP:
1416
        case IP_DROP_MEMBERSHIP:
1417
            if (optlen < sizeof (struct target_ip_mreq) ||
1418
                optlen > sizeof (struct target_ip_mreqn))
1419
                return -TARGET_EINVAL;
1420

    
1421
            ip_mreq = (struct ip_mreqn *) alloca(optlen);
1422
            target_to_host_ip_mreq(ip_mreq, optval_addr, optlen);
1423
            ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq, optlen));
1424
            break;
1425

    
1426
        case IP_BLOCK_SOURCE:
1427
        case IP_UNBLOCK_SOURCE:
1428
        case IP_ADD_SOURCE_MEMBERSHIP:
1429
        case IP_DROP_SOURCE_MEMBERSHIP:
1430
            if (optlen != sizeof (struct target_ip_mreq_source))
1431
                return -TARGET_EINVAL;
1432

    
1433
            ip_mreq_source = lock_user(VERIFY_READ, optval_addr, optlen, 1);
1434
            ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq_source, optlen));
1435
            unlock_user (ip_mreq_source, optval_addr, 0);
1436
            break;
1437

    
1438
        default:
1439
            goto unimplemented;
1440
        }
1441
        break;
1442
    case TARGET_SOL_SOCKET:
1443
        switch (optname) {
1444
            /* Options with 'int' argument.  */
1445
        case TARGET_SO_DEBUG:
1446
                optname = SO_DEBUG;
1447
                break;
1448
        case TARGET_SO_REUSEADDR:
1449
                optname = SO_REUSEADDR;
1450
                break;
1451
        case TARGET_SO_TYPE:
1452
                optname = SO_TYPE;
1453
                break;
1454
        case TARGET_SO_ERROR:
1455
                optname = SO_ERROR;
1456
                break;
1457
        case TARGET_SO_DONTROUTE:
1458
                optname = SO_DONTROUTE;
1459
                break;
1460
        case TARGET_SO_BROADCAST:
1461
                optname = SO_BROADCAST;
1462
                break;
1463
        case TARGET_SO_SNDBUF:
1464
                optname = SO_SNDBUF;
1465
                break;
1466
        case TARGET_SO_RCVBUF:
1467
                optname = SO_RCVBUF;
1468
                break;
1469
        case TARGET_SO_KEEPALIVE:
1470
                optname = SO_KEEPALIVE;
1471
                break;
1472
        case TARGET_SO_OOBINLINE:
1473
                optname = SO_OOBINLINE;
1474
                break;
1475
        case TARGET_SO_NO_CHECK:
1476
                optname = SO_NO_CHECK;
1477
                break;
1478
        case TARGET_SO_PRIORITY:
1479
                optname = SO_PRIORITY;
1480
                break;
1481
#ifdef SO_BSDCOMPAT
1482
        case TARGET_SO_BSDCOMPAT:
1483
                optname = SO_BSDCOMPAT;
1484
                break;
1485
#endif
1486
        case TARGET_SO_PASSCRED:
1487
                optname = SO_PASSCRED;
1488
                break;
1489
        case TARGET_SO_TIMESTAMP:
1490
                optname = SO_TIMESTAMP;
1491
                break;
1492
        case TARGET_SO_RCVLOWAT:
1493
                optname = SO_RCVLOWAT;
1494
                break;
1495
        case TARGET_SO_RCVTIMEO:
1496
                optname = SO_RCVTIMEO;
1497
                break;
1498
        case TARGET_SO_SNDTIMEO:
1499
                optname = SO_SNDTIMEO;
1500
                break;
1501
            break;
1502
        default:
1503
            goto unimplemented;
1504
        }
1505
        if (optlen < sizeof(uint32_t))
1506
            return -TARGET_EINVAL;
1507

    
1508
        if (get_user_u32(val, optval_addr))
1509
            return -TARGET_EFAULT;
1510
        ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
1511
        break;
1512
    default:
1513
    unimplemented:
1514
        gemu_log("Unsupported setsockopt level=%d optname=%d\n", level, optname);
1515
        ret = -TARGET_ENOPROTOOPT;
1516
    }
1517
    return ret;
1518
}
1519

    
1520
/* do_getsockopt() Must return target values and target errnos. */
1521
static abi_long do_getsockopt(int sockfd, int level, int optname,
1522
                              abi_ulong optval_addr, abi_ulong optlen)
1523
{
1524
    abi_long ret;
1525
    int len, val;
1526
    socklen_t lv;
1527

    
1528
    switch(level) {
1529
    case TARGET_SOL_SOCKET:
1530
        level = SOL_SOCKET;
1531
        switch (optname) {
1532
        /* These don't just return a single integer */
1533
        case TARGET_SO_LINGER:
1534
        case TARGET_SO_RCVTIMEO:
1535
        case TARGET_SO_SNDTIMEO:
1536
        case TARGET_SO_PEERNAME:
1537
            goto unimplemented;
1538
        case TARGET_SO_PEERCRED: {
1539
            struct ucred cr;
1540
            socklen_t crlen;
1541
            struct target_ucred *tcr;
1542

    
1543
            if (get_user_u32(len, optlen)) {
1544
                return -TARGET_EFAULT;
1545
            }
1546
            if (len < 0) {
1547
                return -TARGET_EINVAL;
1548
            }
1549

    
1550
            crlen = sizeof(cr);
1551
            ret = get_errno(getsockopt(sockfd, level, SO_PEERCRED,
1552
                                       &cr, &crlen));
1553
            if (ret < 0) {
1554
                return ret;
1555
            }
1556
            if (len > crlen) {
1557
                len = crlen;
1558
            }
1559
            if (!lock_user_struct(VERIFY_WRITE, tcr, optval_addr, 0)) {
1560
                return -TARGET_EFAULT;
1561
            }
1562
            __put_user(cr.pid, &tcr->pid);
1563
            __put_user(cr.uid, &tcr->uid);
1564
            __put_user(cr.gid, &tcr->gid);
1565
            unlock_user_struct(tcr, optval_addr, 1);
1566
            if (put_user_u32(len, optlen)) {
1567
                return -TARGET_EFAULT;
1568
            }
1569
            break;
1570
        }
1571
        /* Options with 'int' argument.  */
1572
        case TARGET_SO_DEBUG:
1573
            optname = SO_DEBUG;
1574
            goto int_case;
1575
        case TARGET_SO_REUSEADDR:
1576
            optname = SO_REUSEADDR;
1577
            goto int_case;
1578
        case TARGET_SO_TYPE:
1579
            optname = SO_TYPE;
1580
            goto int_case;
1581
        case TARGET_SO_ERROR:
1582
            optname = SO_ERROR;
1583
            goto int_case;
1584
        case TARGET_SO_DONTROUTE:
1585
            optname = SO_DONTROUTE;
1586
            goto int_case;
1587
        case TARGET_SO_BROADCAST:
1588
            optname = SO_BROADCAST;
1589
            goto int_case;
1590
        case TARGET_SO_SNDBUF:
1591
            optname = SO_SNDBUF;
1592
            goto int_case;
1593
        case TARGET_SO_RCVBUF:
1594
            optname = SO_RCVBUF;
1595
            goto int_case;
1596
        case TARGET_SO_KEEPALIVE:
1597
            optname = SO_KEEPALIVE;
1598
            goto int_case;
1599
        case TARGET_SO_OOBINLINE:
1600
            optname = SO_OOBINLINE;
1601
            goto int_case;
1602
        case TARGET_SO_NO_CHECK:
1603
            optname = SO_NO_CHECK;
1604
            goto int_case;
1605
        case TARGET_SO_PRIORITY:
1606
            optname = SO_PRIORITY;
1607
            goto int_case;
1608
#ifdef SO_BSDCOMPAT
1609
        case TARGET_SO_BSDCOMPAT:
1610
            optname = SO_BSDCOMPAT;
1611
            goto int_case;
1612
#endif
1613
        case TARGET_SO_PASSCRED:
1614
            optname = SO_PASSCRED;
1615
            goto int_case;
1616
        case TARGET_SO_TIMESTAMP:
1617
            optname = SO_TIMESTAMP;
1618
            goto int_case;
1619
        case TARGET_SO_RCVLOWAT:
1620
            optname = SO_RCVLOWAT;
1621
            goto int_case;
1622
        default:
1623
            goto int_case;
1624
        }
1625
        break;
1626
    case SOL_TCP:
1627
        /* TCP options all take an 'int' value.  */
1628
    int_case:
1629
        if (get_user_u32(len, optlen))
1630
            return -TARGET_EFAULT;
1631
        if (len < 0)
1632
            return -TARGET_EINVAL;
1633
        lv = sizeof(lv);
1634
        ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1635
        if (ret < 0)
1636
            return ret;
1637
        if (len > lv)
1638
            len = lv;
1639
        if (len == 4) {
1640
            if (put_user_u32(val, optval_addr))
1641
                return -TARGET_EFAULT;
1642
        } else {
1643
            if (put_user_u8(val, optval_addr))
1644
                return -TARGET_EFAULT;
1645
        }
1646
        if (put_user_u32(len, optlen))
1647
            return -TARGET_EFAULT;
1648
        break;
1649
    case SOL_IP:
1650
        switch(optname) {
1651
        case IP_TOS:
1652
        case IP_TTL:
1653
        case IP_HDRINCL:
1654
        case IP_ROUTER_ALERT:
1655
        case IP_RECVOPTS:
1656
        case IP_RETOPTS:
1657
        case IP_PKTINFO:
1658
        case IP_MTU_DISCOVER:
1659
        case IP_RECVERR:
1660
        case IP_RECVTOS:
1661
#ifdef IP_FREEBIND
1662
        case IP_FREEBIND:
1663
#endif
1664
        case IP_MULTICAST_TTL:
1665
        case IP_MULTICAST_LOOP:
1666
            if (get_user_u32(len, optlen))
1667
                return -TARGET_EFAULT;
1668
            if (len < 0)
1669
                return -TARGET_EINVAL;
1670
            lv = sizeof(lv);
1671
            ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1672
            if (ret < 0)
1673
                return ret;
1674
            if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
1675
                len = 1;
1676
                if (put_user_u32(len, optlen)
1677
                    || put_user_u8(val, optval_addr))
1678
                    return -TARGET_EFAULT;
1679
            } else {
1680
                if (len > sizeof(int))
1681
                    len = sizeof(int);
1682
                if (put_user_u32(len, optlen)
1683
                    || put_user_u32(val, optval_addr))
1684
                    return -TARGET_EFAULT;
1685
            }
1686
            break;
1687
        default:
1688
            ret = -TARGET_ENOPROTOOPT;
1689
            break;
1690
        }
1691
        break;
1692
    default:
1693
    unimplemented:
1694
        gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1695
                 level, optname);
1696
        ret = -TARGET_EOPNOTSUPP;
1697
        break;
1698
    }
1699
    return ret;
1700
}
1701

    
1702
/* FIXME
1703
 * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1704
 * other lock functions have a return code of 0 for failure.
1705
 */
1706
static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1707
                           int count, int copy)
1708
{
1709
    struct target_iovec *target_vec;
1710
    abi_ulong base;
1711
    int i;
1712

    
1713
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1714
    if (!target_vec)
1715
        return -TARGET_EFAULT;
1716
    for(i = 0;i < count; i++) {
1717
        base = tswapal(target_vec[i].iov_base);
1718
        vec[i].iov_len = tswapal(target_vec[i].iov_len);
1719
        if (vec[i].iov_len != 0) {
1720
            vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
1721
            /* Don't check lock_user return value. We must call writev even
1722
               if a element has invalid base address. */
1723
        } else {
1724
            /* zero length pointer is ignored */
1725
            vec[i].iov_base = NULL;
1726
        }
1727
    }
1728
    unlock_user (target_vec, target_addr, 0);
1729
    return 0;
1730
}
1731

    
1732
static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1733
                             int count, int copy)
1734
{
1735
    struct target_iovec *target_vec;
1736
    abi_ulong base;
1737
    int i;
1738

    
1739
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1740
    if (!target_vec)
1741
        return -TARGET_EFAULT;
1742
    for(i = 0;i < count; i++) {
1743
        if (target_vec[i].iov_base) {
1744
            base = tswapal(target_vec[i].iov_base);
1745
            unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1746
        }
1747
    }
1748
    unlock_user (target_vec, target_addr, 0);
1749

    
1750
    return 0;
1751
}
1752

    
1753
/* do_socket() Must return target values and target errnos. */
1754
static abi_long do_socket(int domain, int type, int protocol)
1755
{
1756
#if defined(TARGET_MIPS)
1757
    switch(type) {
1758
    case TARGET_SOCK_DGRAM:
1759
        type = SOCK_DGRAM;
1760
        break;
1761
    case TARGET_SOCK_STREAM:
1762
        type = SOCK_STREAM;
1763
        break;
1764
    case TARGET_SOCK_RAW:
1765
        type = SOCK_RAW;
1766
        break;
1767
    case TARGET_SOCK_RDM:
1768
        type = SOCK_RDM;
1769
        break;
1770
    case TARGET_SOCK_SEQPACKET:
1771
        type = SOCK_SEQPACKET;
1772
        break;
1773
    case TARGET_SOCK_PACKET:
1774
        type = SOCK_PACKET;
1775
        break;
1776
    }
1777
#endif
1778
    if (domain == PF_NETLINK)
1779
        return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1780
    return get_errno(socket(domain, type, protocol));
1781
}
1782

    
1783
/* do_bind() Must return target values and target errnos. */
1784
static abi_long do_bind(int sockfd, abi_ulong target_addr,
1785
                        socklen_t addrlen)
1786
{
1787
    void *addr;
1788
    abi_long ret;
1789

    
1790
    if ((int)addrlen < 0) {
1791
        return -TARGET_EINVAL;
1792
    }
1793

    
1794
    addr = alloca(addrlen+1);
1795

    
1796
    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1797
    if (ret)
1798
        return ret;
1799

    
1800
    return get_errno(bind(sockfd, addr, addrlen));
1801
}
1802

    
1803
/* do_connect() Must return target values and target errnos. */
1804
static abi_long do_connect(int sockfd, abi_ulong target_addr,
1805
                           socklen_t addrlen)
1806
{
1807
    void *addr;
1808
    abi_long ret;
1809

    
1810
    if ((int)addrlen < 0) {
1811
        return -TARGET_EINVAL;
1812
    }
1813

    
1814
    addr = alloca(addrlen);
1815

    
1816
    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1817
    if (ret)
1818
        return ret;
1819

    
1820
    return get_errno(connect(sockfd, addr, addrlen));
1821
}
1822

    
1823
/* do_sendrecvmsg() Must return target values and target errnos. */
1824
static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1825
                               int flags, int send)
1826
{
1827
    abi_long ret, len;
1828
    struct target_msghdr *msgp;
1829
    struct msghdr msg;
1830
    int count;
1831
    struct iovec *vec;
1832
    abi_ulong target_vec;
1833

    
1834
    /* FIXME */
1835
    if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1836
                          msgp,
1837
                          target_msg,
1838
                          send ? 1 : 0))
1839
        return -TARGET_EFAULT;
1840
    if (msgp->msg_name) {
1841
        msg.msg_namelen = tswap32(msgp->msg_namelen);
1842
        msg.msg_name = alloca(msg.msg_namelen);
1843
        ret = target_to_host_sockaddr(msg.msg_name, tswapal(msgp->msg_name),
1844
                                msg.msg_namelen);
1845
        if (ret) {
1846
            unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1847
            return ret;
1848
        }
1849
    } else {
1850
        msg.msg_name = NULL;
1851
        msg.msg_namelen = 0;
1852
    }
1853
    msg.msg_controllen = 2 * tswapal(msgp->msg_controllen);
1854
    msg.msg_control = alloca(msg.msg_controllen);
1855
    msg.msg_flags = tswap32(msgp->msg_flags);
1856

    
1857
    count = tswapal(msgp->msg_iovlen);
1858
    vec = alloca(count * sizeof(struct iovec));
1859
    target_vec = tswapal(msgp->msg_iov);
1860
    lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1861
    msg.msg_iovlen = count;
1862
    msg.msg_iov = vec;
1863

    
1864
    if (send) {
1865
        ret = target_to_host_cmsg(&msg, msgp);
1866
        if (ret == 0)
1867
            ret = get_errno(sendmsg(fd, &msg, flags));
1868
    } else {
1869
        ret = get_errno(recvmsg(fd, &msg, flags));
1870
        if (!is_error(ret)) {
1871
            len = ret;
1872
            ret = host_to_target_cmsg(msgp, &msg);
1873
            if (!is_error(ret))
1874
                ret = len;
1875
        }
1876
    }
1877
    unlock_iovec(vec, target_vec, count, !send);
1878
    unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1879
    return ret;
1880
}
1881

    
1882
/* do_accept() Must return target values and target errnos. */
1883
static abi_long do_accept(int fd, abi_ulong target_addr,
1884
                          abi_ulong target_addrlen_addr)
1885
{
1886
    socklen_t addrlen;
1887
    void *addr;
1888
    abi_long ret;
1889

    
1890
    if (target_addr == 0)
1891
       return get_errno(accept(fd, NULL, NULL));
1892

    
1893
    /* linux returns EINVAL if addrlen pointer is invalid */
1894
    if (get_user_u32(addrlen, target_addrlen_addr))
1895
        return -TARGET_EINVAL;
1896

    
1897
    if ((int)addrlen < 0) {
1898
        return -TARGET_EINVAL;
1899
    }
1900

    
1901
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1902
        return -TARGET_EINVAL;
1903

    
1904
    addr = alloca(addrlen);
1905

    
1906
    ret = get_errno(accept(fd, addr, &addrlen));
1907
    if (!is_error(ret)) {
1908
        host_to_target_sockaddr(target_addr, addr, addrlen);
1909
        if (put_user_u32(addrlen, target_addrlen_addr))
1910
            ret = -TARGET_EFAULT;
1911
    }
1912
    return ret;
1913
}
1914

    
1915
/* do_getpeername() Must return target values and target errnos. */
1916
static abi_long do_getpeername(int fd, abi_ulong target_addr,
1917
                               abi_ulong target_addrlen_addr)
1918
{
1919
    socklen_t addrlen;
1920
    void *addr;
1921
    abi_long ret;
1922

    
1923
    if (get_user_u32(addrlen, target_addrlen_addr))
1924
        return -TARGET_EFAULT;
1925

    
1926
    if ((int)addrlen < 0) {
1927
        return -TARGET_EINVAL;
1928
    }
1929

    
1930
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1931
        return -TARGET_EFAULT;
1932

    
1933
    addr = alloca(addrlen);
1934

    
1935
    ret = get_errno(getpeername(fd, addr, &addrlen));
1936
    if (!is_error(ret)) {
1937
        host_to_target_sockaddr(target_addr, addr, addrlen);
1938
        if (put_user_u32(addrlen, target_addrlen_addr))
1939
            ret = -TARGET_EFAULT;
1940
    }
1941
    return ret;
1942
}
1943

    
1944
/* do_getsockname() Must return target values and target errnos. */
1945
static abi_long do_getsockname(int fd, abi_ulong target_addr,
1946
                               abi_ulong target_addrlen_addr)
1947
{
1948
    socklen_t addrlen;
1949
    void *addr;
1950
    abi_long ret;
1951

    
1952
    if (get_user_u32(addrlen, target_addrlen_addr))
1953
        return -TARGET_EFAULT;
1954

    
1955
    if ((int)addrlen < 0) {
1956
        return -TARGET_EINVAL;
1957
    }
1958

    
1959
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1960
        return -TARGET_EFAULT;
1961

    
1962
    addr = alloca(addrlen);
1963

    
1964
    ret = get_errno(getsockname(fd, addr, &addrlen));
1965
    if (!is_error(ret)) {
1966
        host_to_target_sockaddr(target_addr, addr, addrlen);
1967
        if (put_user_u32(addrlen, target_addrlen_addr))
1968
            ret = -TARGET_EFAULT;
1969
    }
1970
    return ret;
1971
}
1972

    
1973
/* do_socketpair() Must return target values and target errnos. */
1974
static abi_long do_socketpair(int domain, int type, int protocol,
1975
                              abi_ulong target_tab_addr)
1976
{
1977
    int tab[2];
1978
    abi_long ret;
1979

    
1980
    ret = get_errno(socketpair(domain, type, protocol, tab));
1981
    if (!is_error(ret)) {
1982
        if (put_user_s32(tab[0], target_tab_addr)
1983
            || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1984
            ret = -TARGET_EFAULT;
1985
    }
1986
    return ret;
1987
}
1988

    
1989
/* do_sendto() Must return target values and target errnos. */
1990
static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
1991
                          abi_ulong target_addr, socklen_t addrlen)
1992
{
1993
    void *addr;
1994
    void *host_msg;
1995
    abi_long ret;
1996

    
1997
    if ((int)addrlen < 0) {
1998
        return -TARGET_EINVAL;
1999
    }
2000

    
2001
    host_msg = lock_user(VERIFY_READ, msg, len, 1);
2002
    if (!host_msg)
2003
        return -TARGET_EFAULT;
2004
    if (target_addr) {
2005
        addr = alloca(addrlen);
2006
        ret = target_to_host_sockaddr(addr, target_addr, addrlen);
2007
        if (ret) {
2008
            unlock_user(host_msg, msg, 0);
2009
            return ret;
2010
        }
2011
        ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
2012
    } else {
2013
        ret = get_errno(send(fd, host_msg, len, flags));
2014
    }
2015
    unlock_user(host_msg, msg, 0);
2016
    return ret;
2017
}
2018

    
2019
/* do_recvfrom() Must return target values and target errnos. */
2020
static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
2021
                            abi_ulong target_addr,
2022
                            abi_ulong target_addrlen)
2023
{
2024
    socklen_t addrlen;
2025
    void *addr;
2026
    void *host_msg;
2027
    abi_long ret;
2028

    
2029
    host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
2030
    if (!host_msg)
2031
        return -TARGET_EFAULT;
2032
    if (target_addr) {
2033
        if (get_user_u32(addrlen, target_addrlen)) {
2034
            ret = -TARGET_EFAULT;
2035
            goto fail;
2036
        }
2037
        if ((int)addrlen < 0) {
2038
            ret = -TARGET_EINVAL;
2039
            goto fail;
2040
        }
2041
        addr = alloca(addrlen);
2042
        ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
2043
    } else {
2044
        addr = NULL; /* To keep compiler quiet.  */
2045
        ret = get_errno(qemu_recv(fd, host_msg, len, flags));
2046
    }
2047
    if (!is_error(ret)) {
2048
        if (target_addr) {
2049
            host_to_target_sockaddr(target_addr, addr, addrlen);
2050
            if (put_user_u32(addrlen, target_addrlen)) {
2051
                ret = -TARGET_EFAULT;
2052
                goto fail;
2053
            }
2054
        }
2055
        unlock_user(host_msg, msg, len);
2056
    } else {
2057
fail:
2058
        unlock_user(host_msg, msg, 0);
2059
    }
2060
    return ret;
2061
}
2062

    
2063
#ifdef TARGET_NR_socketcall
2064
/* do_socketcall() Must return target values and target errnos. */
2065
static abi_long do_socketcall(int num, abi_ulong vptr)
2066
{
2067
    abi_long ret;
2068
    const int n = sizeof(abi_ulong);
2069

    
2070
    switch(num) {
2071
    case SOCKOP_socket:
2072
        {
2073
            abi_ulong domain, type, protocol;
2074

    
2075
            if (get_user_ual(domain, vptr)
2076
                || get_user_ual(type, vptr + n)
2077
                || get_user_ual(protocol, vptr + 2 * n))
2078
                return -TARGET_EFAULT;
2079

    
2080
            ret = do_socket(domain, type, protocol);
2081
        }
2082
        break;
2083
    case SOCKOP_bind:
2084
        {
2085
            abi_ulong sockfd;
2086
            abi_ulong target_addr;
2087
            socklen_t addrlen;
2088

    
2089
            if (get_user_ual(sockfd, vptr)
2090
                || get_user_ual(target_addr, vptr + n)
2091
                || get_user_ual(addrlen, vptr + 2 * n))
2092
                return -TARGET_EFAULT;
2093

    
2094
            ret = do_bind(sockfd, target_addr, addrlen);
2095
        }
2096
        break;
2097
    case SOCKOP_connect:
2098
        {
2099
            abi_ulong sockfd;
2100
            abi_ulong target_addr;
2101
            socklen_t addrlen;
2102

    
2103
            if (get_user_ual(sockfd, vptr)
2104
                || get_user_ual(target_addr, vptr + n)
2105
                || get_user_ual(addrlen, vptr + 2 * n))
2106
                return -TARGET_EFAULT;
2107

    
2108
            ret = do_connect(sockfd, target_addr, addrlen);
2109
        }
2110
        break;
2111
    case SOCKOP_listen:
2112
        {
2113
            abi_ulong sockfd, backlog;
2114

    
2115
            if (get_user_ual(sockfd, vptr)
2116
                || get_user_ual(backlog, vptr + n))
2117
                return -TARGET_EFAULT;
2118

    
2119
            ret = get_errno(listen(sockfd, backlog));
2120
        }
2121
        break;
2122
    case SOCKOP_accept:
2123
        {
2124
            abi_ulong sockfd;
2125
            abi_ulong target_addr, target_addrlen;
2126

    
2127
            if (get_user_ual(sockfd, vptr)
2128
                || get_user_ual(target_addr, vptr + n)
2129
                || get_user_ual(target_addrlen, vptr + 2 * n))
2130
                return -TARGET_EFAULT;
2131

    
2132
            ret = do_accept(sockfd, target_addr, target_addrlen);
2133
        }
2134
        break;
2135
    case SOCKOP_getsockname:
2136
        {
2137
            abi_ulong sockfd;
2138
            abi_ulong target_addr, target_addrlen;
2139

    
2140
            if (get_user_ual(sockfd, vptr)
2141
                || get_user_ual(target_addr, vptr + n)
2142
                || get_user_ual(target_addrlen, vptr + 2 * n))
2143
                return -TARGET_EFAULT;
2144

    
2145
            ret = do_getsockname(sockfd, target_addr, target_addrlen);
2146
        }
2147
        break;
2148
    case SOCKOP_getpeername:
2149
        {
2150
            abi_ulong sockfd;
2151
            abi_ulong target_addr, target_addrlen;
2152

    
2153
            if (get_user_ual(sockfd, vptr)
2154
                || get_user_ual(target_addr, vptr + n)
2155
                || get_user_ual(target_addrlen, vptr + 2 * n))
2156
                return -TARGET_EFAULT;
2157

    
2158
            ret = do_getpeername(sockfd, target_addr, target_addrlen);
2159
        }
2160
        break;
2161
    case SOCKOP_socketpair:
2162
        {
2163
            abi_ulong domain, type, protocol;
2164
            abi_ulong tab;
2165

    
2166
            if (get_user_ual(domain, vptr)
2167
                || get_user_ual(type, vptr + n)
2168
                || get_user_ual(protocol, vptr + 2 * n)
2169
                || get_user_ual(tab, vptr + 3 * n))
2170
                return -TARGET_EFAULT;
2171

    
2172
            ret = do_socketpair(domain, type, protocol, tab);
2173
        }
2174
        break;
2175
    case SOCKOP_send:
2176
        {
2177
            abi_ulong sockfd;
2178
            abi_ulong msg;
2179
            size_t len;
2180
            abi_ulong flags;
2181

    
2182
            if (get_user_ual(sockfd, vptr)
2183
                || get_user_ual(msg, vptr + n)
2184
                || get_user_ual(len, vptr + 2 * n)
2185
                || get_user_ual(flags, vptr + 3 * n))
2186
                return -TARGET_EFAULT;
2187

    
2188
            ret = do_sendto(sockfd, msg, len, flags, 0, 0);
2189
        }
2190
        break;
2191
    case SOCKOP_recv:
2192
        {
2193
            abi_ulong sockfd;
2194
            abi_ulong msg;
2195
            size_t len;
2196
            abi_ulong flags;
2197

    
2198
            if (get_user_ual(sockfd, vptr)
2199
                || get_user_ual(msg, vptr + n)
2200
                || get_user_ual(len, vptr + 2 * n)
2201
                || get_user_ual(flags, vptr + 3 * n))
2202
                return -TARGET_EFAULT;
2203

    
2204
            ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
2205
        }
2206
        break;
2207
    case SOCKOP_sendto:
2208
        {
2209
            abi_ulong sockfd;
2210
            abi_ulong msg;
2211
            size_t len;
2212
            abi_ulong flags;
2213
            abi_ulong addr;
2214
            socklen_t addrlen;
2215

    
2216
            if (get_user_ual(sockfd, vptr)
2217
                || get_user_ual(msg, vptr + n)
2218
                || get_user_ual(len, vptr + 2 * n)
2219
                || get_user_ual(flags, vptr + 3 * n)
2220
                || get_user_ual(addr, vptr + 4 * n)
2221
                || get_user_ual(addrlen, vptr + 5 * n))
2222
                return -TARGET_EFAULT;
2223

    
2224
            ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
2225
        }
2226
        break;
2227
    case SOCKOP_recvfrom:
2228
        {
2229
            abi_ulong sockfd;
2230
            abi_ulong msg;
2231
            size_t len;
2232
            abi_ulong flags;
2233
            abi_ulong addr;
2234
            socklen_t addrlen;
2235

    
2236
            if (get_user_ual(sockfd, vptr)
2237
                || get_user_ual(msg, vptr + n)
2238
                || get_user_ual(len, vptr + 2 * n)
2239
                || get_user_ual(flags, vptr + 3 * n)
2240
                || get_user_ual(addr, vptr + 4 * n)
2241
                || get_user_ual(addrlen, vptr + 5 * n))
2242
                return -TARGET_EFAULT;
2243

    
2244
            ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
2245
        }
2246
        break;
2247
    case SOCKOP_shutdown:
2248
        {
2249
            abi_ulong sockfd, how;
2250

    
2251
            if (get_user_ual(sockfd, vptr)
2252
                || get_user_ual(how, vptr + n))
2253
                return -TARGET_EFAULT;
2254

    
2255
            ret = get_errno(shutdown(sockfd, how));
2256
        }
2257
        break;
2258
    case SOCKOP_sendmsg:
2259
    case SOCKOP_recvmsg:
2260
        {
2261
            abi_ulong fd;
2262
            abi_ulong target_msg;
2263
            abi_ulong flags;
2264

    
2265
            if (get_user_ual(fd, vptr)
2266
                || get_user_ual(target_msg, vptr + n)
2267
                || get_user_ual(flags, vptr + 2 * n))
2268
                return -TARGET_EFAULT;
2269

    
2270
            ret = do_sendrecvmsg(fd, target_msg, flags,
2271
                                 (num == SOCKOP_sendmsg));
2272
        }
2273
        break;
2274
    case SOCKOP_setsockopt:
2275
        {
2276
            abi_ulong sockfd;
2277
            abi_ulong level;
2278
            abi_ulong optname;
2279
            abi_ulong optval;
2280
            socklen_t optlen;
2281

    
2282
            if (get_user_ual(sockfd, vptr)
2283
                || get_user_ual(level, vptr + n)
2284
                || get_user_ual(optname, vptr + 2 * n)
2285
                || get_user_ual(optval, vptr + 3 * n)
2286
                || get_user_ual(optlen, vptr + 4 * n))
2287
                return -TARGET_EFAULT;
2288

    
2289
            ret = do_setsockopt(sockfd, level, optname, optval, optlen);
2290
        }
2291
        break;
2292
    case SOCKOP_getsockopt:
2293
        {
2294
            abi_ulong sockfd;
2295
            abi_ulong level;
2296
            abi_ulong optname;
2297
            abi_ulong optval;
2298
            socklen_t optlen;
2299

    
2300
            if (get_user_ual(sockfd, vptr)
2301
                || get_user_ual(level, vptr + n)
2302
                || get_user_ual(optname, vptr + 2 * n)
2303
                || get_user_ual(optval, vptr + 3 * n)
2304
                || get_user_ual(optlen, vptr + 4 * n))
2305
                return -TARGET_EFAULT;
2306

    
2307
            ret = do_getsockopt(sockfd, level, optname, optval, optlen);
2308
        }
2309
        break;
2310
    default:
2311
        gemu_log("Unsupported socketcall: %d\n", num);
2312
        ret = -TARGET_ENOSYS;
2313
        break;
2314
    }
2315
    return ret;
2316
}
2317
#endif
2318

    
2319
#define N_SHM_REGIONS        32
2320

    
2321
static struct shm_region {
2322
    abi_ulong        start;
2323
    abi_ulong        size;
2324
} shm_regions[N_SHM_REGIONS];
2325

    
2326
struct target_ipc_perm
2327
{
2328
    abi_long __key;
2329
    abi_ulong uid;
2330
    abi_ulong gid;
2331
    abi_ulong cuid;
2332
    abi_ulong cgid;
2333
    unsigned short int mode;
2334
    unsigned short int __pad1;
2335
    unsigned short int __seq;
2336
    unsigned short int __pad2;
2337
    abi_ulong __unused1;
2338
    abi_ulong __unused2;
2339
};
2340

    
2341
struct target_semid_ds
2342
{
2343
  struct target_ipc_perm sem_perm;
2344
  abi_ulong sem_otime;
2345
  abi_ulong __unused1;
2346
  abi_ulong sem_ctime;
2347
  abi_ulong __unused2;
2348
  abi_ulong sem_nsems;
2349
  abi_ulong __unused3;
2350
  abi_ulong __unused4;
2351
};
2352

    
2353
static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
2354
                                               abi_ulong target_addr)
2355
{
2356
    struct target_ipc_perm *target_ip;
2357
    struct target_semid_ds *target_sd;
2358

    
2359
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2360
        return -TARGET_EFAULT;
2361
    target_ip = &(target_sd->sem_perm);
2362
    host_ip->__key = tswapal(target_ip->__key);
2363
    host_ip->uid = tswapal(target_ip->uid);
2364
    host_ip->gid = tswapal(target_ip->gid);
2365
    host_ip->cuid = tswapal(target_ip->cuid);
2366
    host_ip->cgid = tswapal(target_ip->cgid);
2367
    host_ip->mode = tswap16(target_ip->mode);
2368
    unlock_user_struct(target_sd, target_addr, 0);
2369
    return 0;
2370
}
2371

    
2372
static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
2373
                                               struct ipc_perm *host_ip)
2374
{
2375
    struct target_ipc_perm *target_ip;
2376
    struct target_semid_ds *target_sd;
2377

    
2378
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2379
        return -TARGET_EFAULT;
2380
    target_ip = &(target_sd->sem_perm);
2381
    target_ip->__key = tswapal(host_ip->__key);
2382
    target_ip->uid = tswapal(host_ip->uid);
2383
    target_ip->gid = tswapal(host_ip->gid);
2384
    target_ip->cuid = tswapal(host_ip->cuid);
2385
    target_ip->cgid = tswapal(host_ip->cgid);
2386
    target_ip->mode = tswap16(host_ip->mode);
2387
    unlock_user_struct(target_sd, target_addr, 1);
2388
    return 0;
2389
}
2390

    
2391
static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
2392
                                               abi_ulong target_addr)
2393
{
2394
    struct target_semid_ds *target_sd;
2395

    
2396
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2397
        return -TARGET_EFAULT;
2398
    if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr))
2399
        return -TARGET_EFAULT;
2400
    host_sd->sem_nsems = tswapal(target_sd->sem_nsems);
2401
    host_sd->sem_otime = tswapal(target_sd->sem_otime);
2402
    host_sd->sem_ctime = tswapal(target_sd->sem_ctime);
2403
    unlock_user_struct(target_sd, target_addr, 0);
2404
    return 0;
2405
}
2406

    
2407
static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
2408
                                               struct semid_ds *host_sd)
2409
{
2410
    struct target_semid_ds *target_sd;
2411

    
2412
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2413
        return -TARGET_EFAULT;
2414
    if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
2415
        return -TARGET_EFAULT;
2416
    target_sd->sem_nsems = tswapal(host_sd->sem_nsems);
2417
    target_sd->sem_otime = tswapal(host_sd->sem_otime);
2418
    target_sd->sem_ctime = tswapal(host_sd->sem_ctime);
2419
    unlock_user_struct(target_sd, target_addr, 1);
2420
    return 0;
2421
}
2422

    
2423
struct target_seminfo {
2424
    int semmap;
2425
    int semmni;
2426
    int semmns;
2427
    int semmnu;
2428
    int semmsl;
2429
    int semopm;
2430
    int semume;
2431
    int semusz;
2432
    int semvmx;
2433
    int semaem;
2434
};
2435

    
2436
static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
2437
                                              struct seminfo *host_seminfo)
2438
{
2439
    struct target_seminfo *target_seminfo;
2440
    if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
2441
        return -TARGET_EFAULT;
2442
    __put_user(host_seminfo->semmap, &target_seminfo->semmap);
2443
    __put_user(host_seminfo->semmni, &target_seminfo->semmni);
2444
    __put_user(host_seminfo->semmns, &target_seminfo->semmns);
2445
    __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
2446
    __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
2447
    __put_user(host_seminfo->semopm, &target_seminfo->semopm);
2448
    __put_user(host_seminfo->semume, &target_seminfo->semume);
2449
    __put_user(host_seminfo->semusz, &target_seminfo->semusz);
2450
    __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
2451
    __put_user(host_seminfo->semaem, &target_seminfo->semaem);
2452
    unlock_user_struct(target_seminfo, target_addr, 1);
2453
    return 0;
2454
}
2455

    
2456
union semun {
2457
        int val;
2458
        struct semid_ds *buf;
2459
        unsigned short *array;
2460
        struct seminfo *__buf;
2461
};
2462

    
2463
union target_semun {
2464
        int val;
2465
        abi_ulong buf;
2466
        abi_ulong array;
2467
        abi_ulong __buf;
2468
};
2469

    
2470
static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
2471
                                               abi_ulong target_addr)
2472
{
2473
    int nsems;
2474
    unsigned short *array;
2475
    union semun semun;
2476
    struct semid_ds semid_ds;
2477
    int i, ret;
2478

    
2479
    semun.buf = &semid_ds;
2480

    
2481
    ret = semctl(semid, 0, IPC_STAT, semun);
2482
    if (ret == -1)
2483
        return get_errno(ret);
2484

    
2485
    nsems = semid_ds.sem_nsems;
2486

    
2487
    *host_array = malloc(nsems*sizeof(unsigned short));
2488
    array = lock_user(VERIFY_READ, target_addr,
2489
                      nsems*sizeof(unsigned short), 1);
2490
    if (!array)
2491
        return -TARGET_EFAULT;
2492

    
2493
    for(i=0; i<nsems; i++) {
2494
        __get_user((*host_array)[i], &array[i]);
2495
    }
2496
    unlock_user(array, target_addr, 0);
2497

    
2498
    return 0;
2499
}
2500

    
2501
static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
2502
                                               unsigned short **host_array)
2503
{
2504
    int nsems;
2505
    unsigned short *array;
2506
    union semun semun;
2507
    struct semid_ds semid_ds;
2508
    int i, ret;
2509

    
2510
    semun.buf = &semid_ds;
2511

    
2512
    ret = semctl(semid, 0, IPC_STAT, semun);
2513
    if (ret == -1)
2514
        return get_errno(ret);
2515

    
2516
    nsems = semid_ds.sem_nsems;
2517

    
2518
    array = lock_user(VERIFY_WRITE, target_addr,
2519
                      nsems*sizeof(unsigned short), 0);
2520
    if (!array)
2521
        return -TARGET_EFAULT;
2522

    
2523
    for(i=0; i<nsems; i++) {
2524
        __put_user((*host_array)[i], &array[i]);
2525
    }
2526
    free(*host_array);
2527
    unlock_user(array, target_addr, 1);
2528

    
2529
    return 0;
2530
}
2531

    
2532
static inline abi_long do_semctl(int semid, int semnum, int cmd,
2533
                                 union target_semun target_su)
2534
{
2535
    union semun arg;
2536
    struct semid_ds dsarg;
2537
    unsigned short *array = NULL;
2538
    struct seminfo seminfo;
2539
    abi_long ret = -TARGET_EINVAL;
2540
    abi_long err;
2541
    cmd &= 0xff;
2542

    
2543
    switch( cmd ) {
2544
        case GETVAL:
2545
        case SETVAL:
2546
            arg.val = tswap32(target_su.val);
2547
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2548
            target_su.val = tswap32(arg.val);
2549
            break;
2550
        case GETALL:
2551
        case SETALL:
2552
            err = target_to_host_semarray(semid, &array, target_su.array);
2553
            if (err)
2554
                return err;
2555
            arg.array = array;
2556
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2557
            err = host_to_target_semarray(semid, target_su.array, &array);
2558
            if (err)
2559
                return err;
2560
            break;
2561
        case IPC_STAT:
2562
        case IPC_SET:
2563
        case SEM_STAT:
2564
            err = target_to_host_semid_ds(&dsarg, target_su.buf);
2565
            if (err)
2566
                return err;
2567
            arg.buf = &dsarg;
2568
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2569
            err = host_to_target_semid_ds(target_su.buf, &dsarg);
2570
            if (err)
2571
                return err;
2572
            break;
2573
        case IPC_INFO:
2574
        case SEM_INFO:
2575
            arg.__buf = &seminfo;
2576
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2577
            err = host_to_target_seminfo(target_su.__buf, &seminfo);
2578
            if (err)
2579
                return err;
2580
            break;
2581
        case IPC_RMID:
2582
        case GETPID:
2583
        case GETNCNT:
2584
        case GETZCNT:
2585
            ret = get_errno(semctl(semid, semnum, cmd, NULL));
2586
            break;
2587
    }
2588

    
2589
    return ret;
2590
}
2591

    
2592
struct target_sembuf {
2593
    unsigned short sem_num;
2594
    short sem_op;
2595
    short sem_flg;
2596
};
2597

    
2598
static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
2599
                                             abi_ulong target_addr,
2600
                                             unsigned nsops)
2601
{
2602
    struct target_sembuf *target_sembuf;
2603
    int i;
2604

    
2605
    target_sembuf = lock_user(VERIFY_READ, target_addr,
2606
                              nsops*sizeof(struct target_sembuf), 1);
2607
    if (!target_sembuf)
2608
        return -TARGET_EFAULT;
2609

    
2610
    for(i=0; i<nsops; i++) {
2611
        __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
2612
        __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
2613
        __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
2614
    }
2615

    
2616
    unlock_user(target_sembuf, target_addr, 0);
2617

    
2618
    return 0;
2619
}
2620

    
2621
static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
2622
{
2623
    struct sembuf sops[nsops];
2624

    
2625
    if (target_to_host_sembuf(sops, ptr, nsops))
2626
        return -TARGET_EFAULT;
2627

    
2628
    return semop(semid, sops, nsops);
2629
}
2630

    
2631
struct target_msqid_ds
2632
{
2633
    struct target_ipc_perm msg_perm;
2634
    abi_ulong msg_stime;
2635
#if TARGET_ABI_BITS == 32
2636
    abi_ulong __unused1;
2637
#endif
2638
    abi_ulong msg_rtime;
2639
#if TARGET_ABI_BITS == 32
2640
    abi_ulong __unused2;
2641
#endif
2642
    abi_ulong msg_ctime;
2643
#if TARGET_ABI_BITS == 32
2644
    abi_ulong __unused3;
2645
#endif
2646
    abi_ulong __msg_cbytes;
2647
    abi_ulong msg_qnum;
2648
    abi_ulong msg_qbytes;
2649
    abi_ulong msg_lspid;
2650
    abi_ulong msg_lrpid;
2651
    abi_ulong __unused4;
2652
    abi_ulong __unused5;
2653
};
2654

    
2655
static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
2656
                                               abi_ulong target_addr)
2657
{
2658
    struct target_msqid_ds *target_md;
2659

    
2660
    if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
2661
        return -TARGET_EFAULT;
2662
    if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
2663
        return -TARGET_EFAULT;
2664
    host_md->msg_stime = tswapal(target_md->msg_stime);
2665
    host_md->msg_rtime = tswapal(target_md->msg_rtime);
2666
    host_md->msg_ctime = tswapal(target_md->msg_ctime);
2667
    host_md->__msg_cbytes = tswapal(target_md->__msg_cbytes);
2668
    host_md->msg_qnum = tswapal(target_md->msg_qnum);
2669
    host_md->msg_qbytes = tswapal(target_md->msg_qbytes);
2670
    host_md->msg_lspid = tswapal(target_md->msg_lspid);
2671
    host_md->msg_lrpid = tswapal(target_md->msg_lrpid);
2672
    unlock_user_struct(target_md, target_addr, 0);
2673
    return 0;
2674
}
2675

    
2676
static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
2677
                                               struct msqid_ds *host_md)
2678
{
2679
    struct target_msqid_ds *target_md;
2680

    
2681
    if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
2682
        return -TARGET_EFAULT;
2683
    if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
2684
        return -TARGET_EFAULT;
2685
    target_md->msg_stime = tswapal(host_md->msg_stime);
2686
    target_md->msg_rtime = tswapal(host_md->msg_rtime);
2687
    target_md->msg_ctime = tswapal(host_md->msg_ctime);
2688
    target_md->__msg_cbytes = tswapal(host_md->__msg_cbytes);
2689
    target_md->msg_qnum = tswapal(host_md->msg_qnum);
2690
    target_md->msg_qbytes = tswapal(host_md->msg_qbytes);
2691
    target_md->msg_lspid = tswapal(host_md->msg_lspid);
2692
    target_md->msg_lrpid = tswapal(host_md->msg_lrpid);
2693
    unlock_user_struct(target_md, target_addr, 1);
2694
    return 0;
2695
}
2696

    
2697
struct target_msginfo {
2698
    int msgpool;
2699
    int msgmap;
2700
    int msgmax;
2701
    int msgmnb;
2702
    int msgmni;
2703
    int msgssz;
2704
    int msgtql;
2705
    unsigned short int msgseg;
2706
};
2707

    
2708
static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
2709
                                              struct msginfo *host_msginfo)
2710
{
2711
    struct target_msginfo *target_msginfo;
2712
    if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
2713
        return -TARGET_EFAULT;
2714
    __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
2715
    __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
2716
    __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
2717
    __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
2718
    __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
2719
    __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
2720
    __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
2721
    __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
2722
    unlock_user_struct(target_msginfo, target_addr, 1);
2723
    return 0;
2724
}
2725

    
2726
static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
2727
{
2728
    struct msqid_ds dsarg;
2729
    struct msginfo msginfo;
2730
    abi_long ret = -TARGET_EINVAL;
2731

    
2732
    cmd &= 0xff;
2733

    
2734
    switch (cmd) {
2735
    case IPC_STAT:
2736
    case IPC_SET:
2737
    case MSG_STAT:
2738
        if (target_to_host_msqid_ds(&dsarg,ptr))
2739
            return -TARGET_EFAULT;
2740
        ret = get_errno(msgctl(msgid, cmd, &dsarg));
2741
        if (host_to_target_msqid_ds(ptr,&dsarg))
2742
            return -TARGET_EFAULT;
2743
        break;
2744
    case IPC_RMID:
2745
        ret = get_errno(msgctl(msgid, cmd, NULL));
2746
        break;
2747
    case IPC_INFO:
2748
    case MSG_INFO:
2749
        ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
2750
        if (host_to_target_msginfo(ptr, &msginfo))
2751
            return -TARGET_EFAULT;
2752
        break;
2753
    }
2754

    
2755
    return ret;
2756
}
2757

    
2758
struct target_msgbuf {
2759
    abi_long mtype;
2760
    char        mtext[1];
2761
};
2762

    
2763
static inline abi_long do_msgsnd(int msqid, abi_long msgp,
2764
                                 unsigned int msgsz, int msgflg)
2765
{
2766
    struct target_msgbuf *target_mb;
2767
    struct msgbuf *host_mb;
2768
    abi_long ret = 0;
2769

    
2770
    if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
2771
        return -TARGET_EFAULT;
2772
    host_mb = malloc(msgsz+sizeof(long));
2773
    host_mb->mtype = (abi_long) tswapal(target_mb->mtype);
2774
    memcpy(host_mb->mtext, target_mb->mtext, msgsz);
2775
    ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
2776
    free(host_mb);
2777
    unlock_user_struct(target_mb, msgp, 0);
2778

    
2779
    return ret;
2780
}
2781

    
2782
static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2783
                                 unsigned int msgsz, abi_long msgtyp,
2784
                                 int msgflg)
2785
{
2786
    struct target_msgbuf *target_mb;
2787
    char *target_mtext;
2788
    struct msgbuf *host_mb;
2789
    abi_long ret = 0;
2790

    
2791
    if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2792
        return -TARGET_EFAULT;
2793

    
2794
    host_mb = malloc(msgsz+sizeof(long));
2795
    ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapal(msgtyp), msgflg));
2796

    
2797
    if (ret > 0) {
2798
        abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2799
        target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2800
        if (!target_mtext) {
2801
            ret = -TARGET_EFAULT;
2802
            goto end;
2803
        }
2804
        memcpy(target_mb->mtext, host_mb->mtext, ret);
2805
        unlock_user(target_mtext, target_mtext_addr, ret);
2806
    }
2807

    
2808
    target_mb->mtype = tswapal(host_mb->mtype);
2809
    free(host_mb);
2810

    
2811
end:
2812
    if (target_mb)
2813
        unlock_user_struct(target_mb, msgp, 1);
2814
    return ret;
2815
}
2816

    
2817
struct target_shmid_ds
2818
{
2819
    struct target_ipc_perm shm_perm;
2820
    abi_ulong shm_segsz;
2821
    abi_ulong shm_atime;
2822
#if TARGET_ABI_BITS == 32
2823
    abi_ulong __unused1;
2824
#endif
2825
    abi_ulong shm_dtime;
2826
#if TARGET_ABI_BITS == 32
2827
    abi_ulong __unused2;
2828
#endif
2829
    abi_ulong shm_ctime;
2830
#if TARGET_ABI_BITS == 32
2831
    abi_ulong __unused3;
2832
#endif
2833
    int shm_cpid;
2834
    int shm_lpid;
2835
    abi_ulong shm_nattch;
2836
    unsigned long int __unused4;
2837
    unsigned long int __unused5;
2838
};
2839

    
2840
static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
2841
                                               abi_ulong target_addr)
2842
{
2843
    struct target_shmid_ds *target_sd;
2844

    
2845
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2846
        return -TARGET_EFAULT;
2847
    if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr))
2848
        return -TARGET_EFAULT;
2849
    __get_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2850
    __get_user(host_sd->shm_atime, &target_sd->shm_atime);
2851
    __get_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2852
    __get_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2853
    __get_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2854
    __get_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2855
    __get_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2856
    unlock_user_struct(target_sd, target_addr, 0);
2857
    return 0;
2858
}
2859

    
2860
static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
2861
                                               struct shmid_ds *host_sd)
2862
{
2863
    struct target_shmid_ds *target_sd;
2864

    
2865
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2866
        return -TARGET_EFAULT;
2867
    if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm)))
2868
        return -TARGET_EFAULT;
2869
    __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2870
    __put_user(host_sd->shm_atime, &target_sd->shm_atime);
2871
    __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2872
    __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2873
    __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2874
    __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2875
    __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2876
    unlock_user_struct(target_sd, target_addr, 1);
2877
    return 0;
2878
}
2879

    
2880
struct  target_shminfo {
2881
    abi_ulong shmmax;
2882
    abi_ulong shmmin;
2883
    abi_ulong shmmni;
2884
    abi_ulong shmseg;
2885
    abi_ulong shmall;
2886
};
2887

    
2888
static inline abi_long host_to_target_shminfo(abi_ulong target_addr,
2889
                                              struct shminfo *host_shminfo)
2890
{
2891
    struct target_shminfo *target_shminfo;
2892
    if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0))
2893
        return -TARGET_EFAULT;
2894
    __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
2895
    __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
2896
    __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
2897
    __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
2898
    __put_user(host_shminfo->shmall, &target_shminfo->shmall);
2899
    unlock_user_struct(target_shminfo, target_addr, 1);
2900
    return 0;
2901
}
2902

    
2903
struct target_shm_info {
2904
    int used_ids;
2905
    abi_ulong shm_tot;
2906
    abi_ulong shm_rss;
2907
    abi_ulong shm_swp;
2908
    abi_ulong swap_attempts;
2909
    abi_ulong swap_successes;
2910
};
2911

    
2912
static inline abi_long host_to_target_shm_info(abi_ulong target_addr,
2913
                                               struct shm_info *host_shm_info)
2914
{
2915
    struct target_shm_info *target_shm_info;
2916
    if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0))
2917
        return -TARGET_EFAULT;
2918
    __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
2919
    __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
2920
    __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
2921
    __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
2922
    __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts);
2923
    __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes);
2924
    unlock_user_struct(target_shm_info, target_addr, 1);
2925
    return 0;
2926
}
2927

    
2928
static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
2929
{
2930
    struct shmid_ds dsarg;
2931
    struct shminfo shminfo;
2932
    struct shm_info shm_info;
2933
    abi_long ret = -TARGET_EINVAL;
2934

    
2935
    cmd &= 0xff;
2936

    
2937
    switch(cmd) {
2938
    case IPC_STAT:
2939
    case IPC_SET:
2940
    case SHM_STAT:
2941
        if (target_to_host_shmid_ds(&dsarg, buf))
2942
            return -TARGET_EFAULT;
2943
        ret = get_errno(shmctl(shmid, cmd, &dsarg));
2944
        if (host_to_target_shmid_ds(buf, &dsarg))
2945
            return -TARGET_EFAULT;
2946
        break;
2947
    case IPC_INFO:
2948
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
2949
        if (host_to_target_shminfo(buf, &shminfo))
2950
            return -TARGET_EFAULT;
2951
        break;
2952
    case SHM_INFO:
2953
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
2954
        if (host_to_target_shm_info(buf, &shm_info))
2955
            return -TARGET_EFAULT;
2956
        break;
2957
    case IPC_RMID:
2958
    case SHM_LOCK:
2959
    case SHM_UNLOCK:
2960
        ret = get_errno(shmctl(shmid, cmd, NULL));
2961
        break;
2962
    }
2963

    
2964
    return ret;
2965
}
2966

    
2967
static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
2968
{
2969
    abi_long raddr;
2970
    void *host_raddr;
2971
    struct shmid_ds shm_info;
2972
    int i,ret;
2973

    
2974
    /* find out the length of the shared memory segment */
2975
    ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
2976
    if (is_error(ret)) {
2977
        /* can't get length, bail out */
2978
        return ret;
2979
    }
2980

    
2981
    mmap_lock();
2982

    
2983
    if (shmaddr)
2984
        host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
2985
    else {
2986
        abi_ulong mmap_start;
2987

    
2988
        mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
2989

    
2990
        if (mmap_start == -1) {
2991
            errno = ENOMEM;
2992
            host_raddr = (void *)-1;
2993
        } else
2994
            host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);
2995
    }
2996

    
2997
    if (host_raddr == (void *)-1) {
2998
        mmap_unlock();
2999
        return get_errno((long)host_raddr);
3000
    }
3001
    raddr=h2g((unsigned long)host_raddr);
3002

    
3003
    page_set_flags(raddr, raddr + shm_info.shm_segsz,
3004
                   PAGE_VALID | PAGE_READ |
3005
                   ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
3006

    
3007
    for (i = 0; i < N_SHM_REGIONS; i++) {
3008
        if (shm_regions[i].start == 0) {
3009
            shm_regions[i].start = raddr;
3010
            shm_regions[i].size = shm_info.shm_segsz;
3011
            break;
3012
        }
3013
    }
3014

    
3015
    mmap_unlock();
3016
    return raddr;
3017

    
3018
}
3019

    
3020
static inline abi_long do_shmdt(abi_ulong shmaddr)
3021
{
3022
    int i;
3023

    
3024
    for (i = 0; i < N_SHM_REGIONS; ++i) {
3025
        if (shm_regions[i].start == shmaddr) {
3026
            shm_regions[i].start = 0;
3027
            page_set_flags(shmaddr, shmaddr + shm_regions[i].size, 0);
3028
            break;
3029
        }
3030
    }
3031

    
3032
    return get_errno(shmdt(g2h(shmaddr)));
3033
}
3034

    
3035
#ifdef TARGET_NR_ipc
3036
/* ??? This only works with linear mappings.  */
3037
/* do_ipc() must return target values and target errnos. */
3038
static abi_long do_ipc(unsigned int call, int first,
3039
                       int second, int third,
3040
                       abi_long ptr, abi_long fifth)
3041
{
3042
    int version;
3043
    abi_long ret = 0;
3044

    
3045
    version = call >> 16;
3046
    call &= 0xffff;
3047

    
3048
    switch (call) {
3049
    case IPCOP_semop:
3050
        ret = do_semop(first, ptr, second);
3051
        break;
3052

    
3053
    case IPCOP_semget:
3054
        ret = get_errno(semget(first, second, third));
3055
        break;
3056

    
3057
    case IPCOP_semctl:
3058
        ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr);
3059
        break;
3060

    
3061
    case IPCOP_msgget:
3062
        ret = get_errno(msgget(first, second));
3063
        break;
3064

    
3065
    case IPCOP_msgsnd:
3066
        ret = do_msgsnd(first, ptr, second, third);
3067
        break;
3068

    
3069
    case IPCOP_msgctl:
3070
        ret = do_msgctl(first, second, ptr);
3071
        break;
3072

    
3073
    case IPCOP_msgrcv:
3074
        switch (version) {
3075
        case 0:
3076
            {
3077
                struct target_ipc_kludge {
3078
                    abi_long msgp;
3079
                    abi_long msgtyp;
3080
                } *tmp;
3081

    
3082
                if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
3083
                    ret = -TARGET_EFAULT;
3084
                    break;
3085
                }
3086

    
3087
                ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
3088

    
3089
                unlock_user_struct(tmp, ptr, 0);
3090
                break;
3091
            }
3092
        default:
3093
            ret = do_msgrcv(first, ptr, second, fifth, third);
3094
        }
3095
        break;
3096

    
3097
    case IPCOP_shmat:
3098
        switch (version) {
3099
        default:
3100
        {
3101
            abi_ulong raddr;
3102
            raddr = do_shmat(first, ptr, second);
3103
            if (is_error(raddr))
3104
                return get_errno(raddr);
3105
            if (put_user_ual(raddr, third))
3106
                return -TARGET_EFAULT;
3107
            break;
3108
        }
3109
        case 1:
3110
            ret = -TARGET_EINVAL;
3111
            break;
3112
        }
3113
        break;
3114
    case IPCOP_shmdt:
3115
        ret = do_shmdt(ptr);
3116
        break;
3117

    
3118
    case IPCOP_shmget:
3119
        /* IPC_* flag values are the same on all linux platforms */
3120
        ret = get_errno(shmget(first, second, third));
3121
        break;
3122

    
3123
        /* IPC_* and SHM_* command values are the same on all linux platforms */
3124
    case IPCOP_shmctl:
3125
        ret = do_shmctl(first, second, third);
3126
        break;
3127
    default:
3128
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
3129
        ret = -TARGET_ENOSYS;
3130
        break;
3131
    }
3132
    return ret;
3133
}
3134
#endif
3135

    
3136
/* kernel structure types definitions */
3137

    
3138
#define STRUCT(name, ...) STRUCT_ ## name,
3139
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
3140
enum {
3141
#include "syscall_types.h"
3142
};
3143
#undef STRUCT
3144
#undef STRUCT_SPECIAL
3145

    
3146
#define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = {  __VA_ARGS__, TYPE_NULL };
3147
#define STRUCT_SPECIAL(name)
3148
#include "syscall_types.h"
3149
#undef STRUCT
3150
#undef STRUCT_SPECIAL
3151

    
3152
typedef struct IOCTLEntry IOCTLEntry;
3153

    
3154
typedef abi_long do_ioctl_fn(const IOCTLEntry *ie, uint8_t *buf_temp,
3155
                             int fd, abi_long cmd, abi_long arg);
3156

    
3157
struct IOCTLEntry {
3158
    unsigned int target_cmd;
3159
    unsigned int host_cmd;
3160
    const char *name;
3161
    int access;
3162
    do_ioctl_fn *do_ioctl;
3163
    const argtype arg_type[5];
3164
};
3165

    
3166
#define IOC_R 0x0001
3167
#define IOC_W 0x0002
3168
#define IOC_RW (IOC_R | IOC_W)
3169

    
3170
#define MAX_STRUCT_SIZE 4096
3171

    
3172
#ifdef CONFIG_FIEMAP
3173
/* So fiemap access checks don't overflow on 32 bit systems.
3174
 * This is very slightly smaller than the limit imposed by
3175
 * the underlying kernel.
3176
 */
3177
#define FIEMAP_MAX_EXTENTS ((UINT_MAX - sizeof(struct fiemap))  \
3178
                            / sizeof(struct fiemap_extent))
3179

    
3180
static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp,
3181
                                       int fd, abi_long cmd, abi_long arg)
3182
{
3183
    /* The parameter for this ioctl is a struct fiemap followed
3184
     * by an array of struct fiemap_extent whose size is set
3185
     * in fiemap->fm_extent_count. The array is filled in by the
3186
     * ioctl.
3187
     */
3188
    int target_size_in, target_size_out;
3189
    struct fiemap *fm;
3190
    const argtype *arg_type = ie->arg_type;
3191
    const argtype extent_arg_type[] = { MK_STRUCT(STRUCT_fiemap_extent) };
3192
    void *argptr, *p;
3193
    abi_long ret;
3194
    int i, extent_size = thunk_type_size(extent_arg_type, 0);
3195
    uint32_t outbufsz;
3196
    int free_fm = 0;
3197

    
3198
    assert(arg_type[0] == TYPE_PTR);
3199
    assert(ie->access == IOC_RW);
3200
    arg_type++;
3201
    target_size_in = thunk_type_size(arg_type, 0);
3202
    argptr = lock_user(VERIFY_READ, arg, target_size_in, 1);
3203
    if (!argptr) {
3204
        return -TARGET_EFAULT;
3205
    }
3206
    thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3207
    unlock_user(argptr, arg, 0);
3208
    fm = (struct fiemap *)buf_temp;
3209
    if (fm->fm_extent_count > FIEMAP_MAX_EXTENTS) {
3210
        return -TARGET_EINVAL;
3211
    }
3212

    
3213
    outbufsz = sizeof (*fm) +
3214
        (sizeof(struct fiemap_extent) * fm->fm_extent_count);
3215

    
3216
    if (outbufsz > MAX_STRUCT_SIZE) {
3217
        /* We can't fit all the extents into the fixed size buffer.
3218
         * Allocate one that is large enough and use it instead.
3219
         */
3220
        fm = malloc(outbufsz);
3221
        if (!fm) {
3222
            return -TARGET_ENOMEM;
3223
        }
3224
        memcpy(fm, buf_temp, sizeof(struct fiemap));
3225
        free_fm = 1;
3226
    }
3227
    ret = get_errno(ioctl(fd, ie->host_cmd, fm));
3228
    if (!is_error(ret)) {
3229
        target_size_out = target_size_in;
3230
        /* An extent_count of 0 means we were only counting the extents
3231
         * so there are no structs to copy
3232
         */
3233
        if (fm->fm_extent_count != 0) {
3234
            target_size_out += fm->fm_mapped_extents * extent_size;
3235
        }
3236
        argptr = lock_user(VERIFY_WRITE, arg, target_size_out, 0);
3237
        if (!argptr) {
3238
            ret = -TARGET_EFAULT;
3239
        } else {
3240
            /* Convert the struct fiemap */
3241
            thunk_convert(argptr, fm, arg_type, THUNK_TARGET);
3242
            if (fm->fm_extent_count != 0) {
3243
                p = argptr + target_size_in;
3244
                /* ...and then all the struct fiemap_extents */
3245
                for (i = 0; i < fm->fm_mapped_extents; i++) {
3246
                    thunk_convert(p, &fm->fm_extents[i], extent_arg_type,
3247
                                  THUNK_TARGET);
3248
                    p += extent_size;
3249
                }
3250
            }
3251
            unlock_user(argptr, arg, target_size_out);
3252
        }
3253
    }
3254
    if (free_fm) {
3255
        free(fm);
3256
    }
3257
    return ret;
3258
}
3259
#endif
3260

    
3261
static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp,
3262
                                int fd, abi_long cmd, abi_long arg)
3263
{
3264
    const argtype *arg_type = ie->arg_type;
3265
    int target_size;
3266
    void *argptr;
3267
    int ret;
3268
    struct ifconf *host_ifconf;
3269
    uint32_t outbufsz;
3270
    const argtype ifreq_arg_type[] = { MK_STRUCT(STRUCT_sockaddr_ifreq) };
3271
    int target_ifreq_size;
3272
    int nb_ifreq;
3273
    int free_buf = 0;
3274
    int i;
3275
    int target_ifc_len;
3276
    abi_long target_ifc_buf;
3277
    int host_ifc_len;
3278
    char *host_ifc_buf;
3279

    
3280
    assert(arg_type[0] == TYPE_PTR);
3281
    assert(ie->access == IOC_RW);
3282

    
3283
    arg_type++;
3284
    target_size = thunk_type_size(arg_type, 0);
3285

    
3286
    argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3287
    if (!argptr)
3288
        return -TARGET_EFAULT;
3289
    thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3290
    unlock_user(argptr, arg, 0);
3291

    
3292
    host_ifconf = (struct ifconf *)(unsigned long)buf_temp;
3293
    target_ifc_len = host_ifconf->ifc_len;
3294
    target_ifc_buf = (abi_long)(unsigned long)host_ifconf->ifc_buf;
3295

    
3296
    target_ifreq_size = thunk_type_size(ifreq_arg_type, 0);
3297
    nb_ifreq = target_ifc_len / target_ifreq_size;
3298
    host_ifc_len = nb_ifreq * sizeof(struct ifreq);
3299

    
3300
    outbufsz = sizeof(*host_ifconf) + host_ifc_len;
3301
    if (outbufsz > MAX_STRUCT_SIZE) {
3302
        /* We can't fit all the extents into the fixed size buffer.
3303
         * Allocate one that is large enough and use it instead.
3304
         */
3305
        host_ifconf = malloc(outbufsz);
3306
        if (!host_ifconf) {
3307
            return -TARGET_ENOMEM;
3308
        }
3309
        memcpy(host_ifconf, buf_temp, sizeof(*host_ifconf));
3310
        free_buf = 1;
3311
    }
3312
    host_ifc_buf = (char*)host_ifconf + sizeof(*host_ifconf);
3313

    
3314
    host_ifconf->ifc_len = host_ifc_len;
3315
    host_ifconf->ifc_buf = host_ifc_buf;
3316

    
3317
    ret = get_errno(ioctl(fd, ie->host_cmd, host_ifconf));
3318
    if (!is_error(ret)) {
3319
        /* convert host ifc_len to target ifc_len */
3320

    
3321
        nb_ifreq = host_ifconf->ifc_len / sizeof(struct ifreq);
3322
        target_ifc_len = nb_ifreq * target_ifreq_size;
3323
        host_ifconf->ifc_len = target_ifc_len;
3324

    
3325
        /* restore target ifc_buf */
3326

    
3327
        host_ifconf->ifc_buf = (char *)(unsigned long)target_ifc_buf;
3328

    
3329
        /* copy struct ifconf to target user */
3330

    
3331
        argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3332
        if (!argptr)
3333
            return -TARGET_EFAULT;
3334
        thunk_convert(argptr, host_ifconf, arg_type, THUNK_TARGET);
3335
        unlock_user(argptr, arg, target_size);
3336

    
3337
        /* copy ifreq[] to target user */
3338

    
3339
        argptr = lock_user(VERIFY_WRITE, target_ifc_buf, target_ifc_len, 0);
3340
        for (i = 0; i < nb_ifreq ; i++) {
3341
            thunk_convert(argptr + i * target_ifreq_size,
3342
                          host_ifc_buf + i * sizeof(struct ifreq),
3343
                          ifreq_arg_type, THUNK_TARGET);
3344
        }
3345
        unlock_user(argptr, target_ifc_buf, target_ifc_len);
3346
    }
3347

    
3348
    if (free_buf) {
3349
        free(host_ifconf);
3350
    }
3351

    
3352
    return ret;
3353
}
3354

    
3355
static IOCTLEntry ioctl_entries[] = {
3356
#define IOCTL(cmd, access, ...) \
3357
    { TARGET_ ## cmd, cmd, #cmd, access, 0, {  __VA_ARGS__ } },
3358
#define IOCTL_SPECIAL(cmd, access, dofn, ...)                      \
3359
    { TARGET_ ## cmd, cmd, #cmd, access, dofn, {  __VA_ARGS__ } },
3360
#include "ioctls.h"
3361
    { 0, 0, },
3362
};
3363

    
3364
/* ??? Implement proper locking for ioctls.  */
3365
/* do_ioctl() Must return target values and target errnos. */
3366
static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
3367
{
3368
    const IOCTLEntry *ie;
3369
    const argtype *arg_type;
3370
    abi_long ret;
3371
    uint8_t buf_temp[MAX_STRUCT_SIZE];
3372
    int target_size;
3373
    void *argptr;
3374

    
3375
    ie = ioctl_entries;
3376
    for(;;) {
3377
        if (ie->target_cmd == 0) {
3378
            gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
3379
            return -TARGET_ENOSYS;
3380
        }
3381
        if (ie->target_cmd == cmd)
3382
            break;
3383
        ie++;
3384
    }
3385
    arg_type = ie->arg_type;
3386
#if defined(DEBUG)
3387
    gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
3388
#endif
3389
    if (ie->do_ioctl) {
3390
        return ie->do_ioctl(ie, buf_temp, fd, cmd, arg);
3391
    }
3392

    
3393
    switch(arg_type[0]) {
3394
    case TYPE_NULL:
3395
        /* no argument */
3396
        ret = get_errno(ioctl(fd, ie->host_cmd));
3397
        break;
3398
    case TYPE_PTRVOID:
3399
    case TYPE_INT:
3400
        /* int argment */
3401
        ret = get_errno(ioctl(fd, ie->host_cmd, arg));
3402
        break;
3403
    case TYPE_PTR:
3404
        arg_type++;
3405
        target_size = thunk_type_size(arg_type, 0);
3406
        switch(ie->access) {
3407
        case IOC_R:
3408
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3409
            if (!is_error(ret)) {
3410
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3411
                if (!argptr)
3412
                    return -TARGET_EFAULT;
3413
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
3414
                unlock_user(argptr, arg, target_size);
3415
            }
3416
            break;
3417
        case IOC_W:
3418
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3419
            if (!argptr)
3420
                return -TARGET_EFAULT;
3421
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3422
            unlock_user(argptr, arg, 0);
3423
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3424
            break;
3425
        default:
3426
        case IOC_RW:
3427
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3428
            if (!argptr)
3429
                return -TARGET_EFAULT;
3430
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3431
            unlock_user(argptr, arg, 0);
3432
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3433
            if (!is_error(ret)) {
3434
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3435
                if (!argptr)
3436
                    return -TARGET_EFAULT;
3437
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
3438
                unlock_user(argptr, arg, target_size);
3439
            }
3440
            break;
3441
        }
3442
        break;
3443
    default:
3444
        gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
3445
                 (long)cmd, arg_type[0]);
3446
        ret = -TARGET_ENOSYS;
3447
        break;
3448
    }
3449
    return ret;
3450
}
3451

    
3452
static const bitmask_transtbl iflag_tbl[] = {
3453
        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
3454
        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
3455
        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
3456
        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
3457
        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
3458
        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
3459
        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
3460
        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
3461
        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
3462
        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
3463
        { TARGET_IXON, TARGET_IXON, IXON, IXON },
3464
        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
3465
        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
3466
        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
3467
        { 0, 0, 0, 0 }
3468
};
3469

    
3470
static const bitmask_transtbl oflag_tbl[] = {
3471
        { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
3472
        { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
3473
        { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
3474
        { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
3475
        { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
3476
        { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
3477
        { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
3478
        { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
3479
        { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
3480
        { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
3481
        { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
3482
        { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
3483
        { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
3484
        { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
3485
        { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
3486
        { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
3487
        { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
3488
        { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
3489
        { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
3490
        { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
3491
        { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
3492
        { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
3493
        { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
3494
        { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
3495
        { 0, 0, 0, 0 }
3496
};
3497

    
3498
static const bitmask_transtbl cflag_tbl[] = {
3499
        { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
3500
        { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
3501
        { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
3502
        { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
3503
        { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
3504
        { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
3505
        { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
3506
        { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
3507
        { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
3508
        { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
3509
        { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
3510
        { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
3511
        { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
3512
        { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
3513
        { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
3514
        { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
3515
        { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
3516
        { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
3517
        { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
3518
        { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
3519
        { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
3520
        { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
3521
        { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
3522
        { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
3523
        { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
3524
        { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
3525
        { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
3526
        { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
3527
        { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
3528
        { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
3529
        { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
3530
        { 0, 0, 0, 0 }
3531
};
3532

    
3533
static const bitmask_transtbl lflag_tbl[] = {
3534
        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
3535
        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
3536
        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
3537
        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
3538
        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
3539
        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
3540
        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
3541
        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
3542
        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
3543
        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
3544
        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
3545
        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
3546
        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
3547
        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
3548
        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
3549
        { 0, 0, 0, 0 }
3550
};
3551

    
3552
static void target_to_host_termios (void *dst, const void *src)
3553
{
3554
    struct host_termios *host = dst;
3555
    const struct target_termios *target = src;
3556

    
3557
    host->c_iflag =
3558
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
3559
    host->c_oflag =
3560
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
3561
    host->c_cflag =
3562
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
3563
    host->c_lflag =
3564
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
3565
    host->c_line = target->c_line;
3566

    
3567
    memset(host->c_cc, 0, sizeof(host->c_cc));
3568
    host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
3569
    host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
3570
    host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
3571
    host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
3572
    host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
3573
    host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
3574
    host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
3575
    host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
3576
    host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
3577
    host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
3578
    host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
3579
    host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
3580
    host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
3581
    host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
3582
    host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
3583
    host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
3584
    host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
3585
}
3586

    
3587
static void host_to_target_termios (void *dst, const void *src)
3588
{
3589
    struct target_termios *target = dst;
3590
    const struct host_termios *host = src;
3591

    
3592
    target->c_iflag =
3593
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
3594
    target->c_oflag =
3595
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
3596
    target->c_cflag =
3597
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
3598
    target->c_lflag =
3599
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
3600
    target->c_line = host->c_line;
3601

    
3602
    memset(target->c_cc, 0, sizeof(target->c_cc));
3603
    target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
3604
    target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
3605
    target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
3606
    target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
3607
    target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
3608
    target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
3609
    target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
3610
    target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
3611
    target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
3612
    target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
3613
    target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
3614
    target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
3615
    target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
3616
    target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
3617
    target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
3618
    target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
3619
    target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
3620
}
3621

    
3622
static const StructEntry struct_termios_def = {
3623
    .convert = { host_to_target_termios, target_to_host_termios },
3624
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
3625
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
3626
};
3627

    
3628
static bitmask_transtbl mmap_flags_tbl[] = {
3629
        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
3630
        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
3631
        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
3632
        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
3633
        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
3634
        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
3635
        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
3636
        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
3637
        { 0, 0, 0, 0 }
3638
};
3639

    
3640
#if defined(TARGET_I386)
3641

    
3642
/* NOTE: there is really one LDT for all the threads */
3643
static uint8_t *ldt_table;
3644

    
3645
static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
3646
{
3647
    int size;
3648
    void *p;
3649

    
3650
    if (!ldt_table)
3651
        return 0;
3652
    size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
3653
    if (size > bytecount)
3654
        size = bytecount;
3655
    p = lock_user(VERIFY_WRITE, ptr, size, 0);
3656
    if (!p)
3657
        return -TARGET_EFAULT;
3658
    /* ??? Should this by byteswapped?  */
3659
    memcpy(p, ldt_table, size);
3660
    unlock_user(p, ptr, size);
3661
    return size;
3662
}
3663

    
3664
/* XXX: add locking support */
3665
static abi_long write_ldt(CPUX86State *env,
3666
                          abi_ulong ptr, unsigned long bytecount, int oldmode)
3667
{
3668
    struct target_modify_ldt_ldt_s ldt_info;
3669
    struct target_modify_ldt_ldt_s *target_ldt_info;
3670
    int seg_32bit, contents, read_exec_only, limit_in_pages;
3671
    int seg_not_present, useable, lm;
3672
    uint32_t *lp, entry_1, entry_2;
3673

    
3674
    if (bytecount != sizeof(ldt_info))
3675
        return -TARGET_EINVAL;
3676
    if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
3677
        return -TARGET_EFAULT;
3678
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3679
    ldt_info.base_addr = tswapal(target_ldt_info->base_addr);
3680
    ldt_info.limit = tswap32(target_ldt_info->limit);
3681
    ldt_info.flags = tswap32(target_ldt_info->flags);
3682
    unlock_user_struct(target_ldt_info, ptr, 0);
3683

    
3684
    if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
3685
        return -TARGET_EINVAL;
3686
    seg_32bit = ldt_info.flags & 1;
3687
    contents = (ldt_info.flags >> 1) & 3;
3688
    read_exec_only = (ldt_info.flags >> 3) & 1;
3689
    limit_in_pages = (ldt_info.flags >> 4) & 1;
3690
    seg_not_present = (ldt_info.flags >> 5) & 1;
3691
    useable = (ldt_info.flags >> 6) & 1;
3692
#ifdef TARGET_ABI32
3693
    lm = 0;
3694
#else
3695
    lm = (ldt_info.flags >> 7) & 1;
3696
#endif
3697
    if (contents == 3) {
3698
        if (oldmode)
3699
            return -TARGET_EINVAL;
3700
        if (seg_not_present == 0)
3701
            return -TARGET_EINVAL;
3702
    }
3703
    /* allocate the LDT */
3704
    if (!ldt_table) {
3705
        env->ldt.base = target_mmap(0,
3706
                                    TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
3707
                                    PROT_READ|PROT_WRITE,
3708
                                    MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
3709
        if (env->ldt.base == -1)
3710
            return -TARGET_ENOMEM;
3711
        memset(g2h(env->ldt.base), 0,
3712
               TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
3713
        env->ldt.limit = 0xffff;
3714
        ldt_table = g2h(env->ldt.base);
3715
    }
3716

    
3717
    /* NOTE: same code as Linux kernel */
3718
    /* Allow LDTs to be cleared by the user. */
3719
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3720
        if (oldmode ||
3721
            (contents == 0                &&
3722
             read_exec_only == 1        &&
3723
             seg_32bit == 0                &&
3724
             limit_in_pages == 0        &&
3725
             seg_not_present == 1        &&
3726
             useable == 0 )) {
3727
            entry_1 = 0;
3728
            entry_2 = 0;
3729
            goto install;
3730
        }
3731
    }
3732

    
3733
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
3734
        (ldt_info.limit & 0x0ffff);
3735
    entry_2 = (ldt_info.base_addr & 0xff000000) |
3736
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3737
        (ldt_info.limit & 0xf0000) |
3738
        ((read_exec_only ^ 1) << 9) |
3739
        (contents << 10) |
3740
        ((seg_not_present ^ 1) << 15) |
3741
        (seg_32bit << 22) |
3742
        (limit_in_pages << 23) |
3743
        (lm << 21) |
3744
        0x7000;
3745
    if (!oldmode)
3746
        entry_2 |= (useable << 20);
3747

    
3748
    /* Install the new entry ...  */
3749
install:
3750
    lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
3751
    lp[0] = tswap32(entry_1);
3752
    lp[1] = tswap32(entry_2);
3753
    return 0;
3754
}
3755

    
3756
/* specific and weird i386 syscalls */
3757
static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
3758
                              unsigned long bytecount)
3759
{
3760
    abi_long ret;
3761

    
3762
    switch (func) {
3763
    case 0:
3764
        ret = read_ldt(ptr, bytecount);
3765
        break;
3766
    case 1:
3767
        ret = write_ldt(env, ptr, bytecount, 1);
3768
        break;
3769
    case 0x11:
3770
        ret = write_ldt(env, ptr, bytecount, 0);
3771
        break;
3772
    default:
3773
        ret = -TARGET_ENOSYS;
3774
        break;
3775
    }
3776
    return ret;
3777
}
3778

    
3779
#if defined(TARGET_I386) && defined(TARGET_ABI32)
3780
static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
3781
{
3782
    uint64_t *gdt_table = g2h(env->gdt.base);
3783
    struct target_modify_ldt_ldt_s ldt_info;
3784
    struct target_modify_ldt_ldt_s *target_ldt_info;
3785
    int seg_32bit, contents, read_exec_only, limit_in_pages;
3786
    int seg_not_present, useable, lm;
3787
    uint32_t *lp, entry_1, entry_2;
3788
    int i;
3789

    
3790
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3791
    if (!target_ldt_info)
3792
        return -TARGET_EFAULT;
3793
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3794
    ldt_info.base_addr = tswapal(target_ldt_info->base_addr);
3795
    ldt_info.limit = tswap32(target_ldt_info->limit);
3796
    ldt_info.flags = tswap32(target_ldt_info->flags);
3797
    if (ldt_info.entry_number == -1) {
3798
        for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
3799
            if (gdt_table[i] == 0) {
3800
                ldt_info.entry_number = i;
3801
                target_ldt_info->entry_number = tswap32(i);
3802
                break;
3803
            }
3804
        }
3805
    }
3806
    unlock_user_struct(target_ldt_info, ptr, 1);
3807

    
3808
    if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || 
3809
        ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
3810
           return -TARGET_EINVAL;
3811
    seg_32bit = ldt_info.flags & 1;
3812
    contents = (ldt_info.flags >> 1) & 3;
3813
    read_exec_only = (ldt_info.flags >> 3) & 1;
3814
    limit_in_pages = (ldt_info.flags >> 4) & 1;
3815
    seg_not_present = (ldt_info.flags >> 5) & 1;
3816
    useable = (ldt_info.flags >> 6) & 1;
3817
#ifdef TARGET_ABI32
3818
    lm = 0;
3819
#else
3820
    lm = (ldt_info.flags >> 7) & 1;
3821
#endif
3822

    
3823
    if (contents == 3) {
3824
        if (seg_not_present == 0)
3825
            return -TARGET_EINVAL;
3826
    }
3827

    
3828
    /* NOTE: same code as Linux kernel */
3829
    /* Allow LDTs to be cleared by the user. */
3830
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3831
        if ((contents == 0             &&
3832
             read_exec_only == 1       &&
3833
             seg_32bit == 0            &&
3834
             limit_in_pages == 0       &&
3835
             seg_not_present == 1      &&
3836
             useable == 0 )) {
3837
            entry_1 = 0;
3838
            entry_2 = 0;
3839
            goto install;
3840
        }
3841
    }
3842

    
3843
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
3844
        (ldt_info.limit & 0x0ffff);
3845
    entry_2 = (ldt_info.base_addr & 0xff000000) |
3846
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3847
        (ldt_info.limit & 0xf0000) |
3848
        ((read_exec_only ^ 1) << 9) |
3849
        (contents << 10) |
3850
        ((seg_not_present ^ 1) << 15) |
3851
        (seg_32bit << 22) |
3852
        (limit_in_pages << 23) |
3853
        (useable << 20) |
3854
        (lm << 21) |
3855
        0x7000;
3856

    
3857
    /* Install the new entry ...  */
3858
install:
3859
    lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
3860
    lp[0] = tswap32(entry_1);
3861
    lp[1] = tswap32(entry_2);
3862
    return 0;
3863
}
3864

    
3865
static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
3866
{
3867
    struct target_modify_ldt_ldt_s *target_ldt_info;
3868
    uint64_t *gdt_table = g2h(env->gdt.base);
3869
    uint32_t base_addr, limit, flags;
3870
    int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
3871
    int seg_not_present, useable, lm;
3872
    uint32_t *lp, entry_1, entry_2;
3873

    
3874
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3875
    if (!target_ldt_info)
3876
        return -TARGET_EFAULT;
3877
    idx = tswap32(target_ldt_info->entry_number);
3878
    if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
3879
        idx > TARGET_GDT_ENTRY_TLS_MAX) {
3880
        unlock_user_struct(target_ldt_info, ptr, 1);
3881
        return -TARGET_EINVAL;
3882
    }
3883
    lp = (uint32_t *)(gdt_table + idx);
3884
    entry_1 = tswap32(lp[0]);
3885
    entry_2 = tswap32(lp[1]);
3886
    
3887
    read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
3888
    contents = (entry_2 >> 10) & 3;
3889
    seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
3890
    seg_32bit = (entry_2 >> 22) & 1;
3891
    limit_in_pages = (entry_2 >> 23) & 1;
3892
    useable = (entry_2 >> 20) & 1;
3893
#ifdef TARGET_ABI32
3894
    lm = 0;
3895
#else
3896
    lm = (entry_2 >> 21) & 1;
3897
#endif
3898
    flags = (seg_32bit << 0) | (contents << 1) |
3899
        (read_exec_only << 3) | (limit_in_pages << 4) |
3900
        (seg_not_present << 5) | (useable << 6) | (lm << 7);
3901
    limit = (entry_1 & 0xffff) | (entry_2  & 0xf0000);
3902
    base_addr = (entry_1 >> 16) | 
3903
        (entry_2 & 0xff000000) | 
3904
        ((entry_2 & 0xff) << 16);
3905
    target_ldt_info->base_addr = tswapal(base_addr);
3906
    target_ldt_info->limit = tswap32(limit);
3907
    target_ldt_info->flags = tswap32(flags);
3908
    unlock_user_struct(target_ldt_info, ptr, 1);
3909
    return 0;
3910
}
3911
#endif /* TARGET_I386 && TARGET_ABI32 */
3912

    
3913
#ifndef TARGET_ABI32
3914
static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
3915
{
3916
    abi_long ret = 0;
3917
    abi_ulong val;
3918
    int idx;
3919

    
3920
    switch(code) {
3921
    case TARGET_ARCH_SET_GS:
3922
    case TARGET_ARCH_SET_FS:
3923
        if (code == TARGET_ARCH_SET_GS)
3924
            idx = R_GS;
3925
        else
3926
            idx = R_FS;
3927
        cpu_x86_load_seg(env, idx, 0);
3928
        env->segs[idx].base = addr;
3929
        break;
3930
    case TARGET_ARCH_GET_GS:
3931
    case TARGET_ARCH_GET_FS:
3932
        if (code == TARGET_ARCH_GET_GS)
3933
            idx = R_GS;
3934
        else
3935
            idx = R_FS;
3936
        val = env->segs[idx].base;
3937
        if (put_user(val, addr, abi_ulong))
3938
            ret = -TARGET_EFAULT;
3939
        break;
3940
    default:
3941
        ret = -TARGET_EINVAL;
3942
        break;
3943
    }
3944
    return ret;
3945
}
3946
#endif
3947

    
3948
#endif /* defined(TARGET_I386) */
3949

    
3950
#define NEW_STACK_SIZE 0x40000
3951

    
3952
#if defined(CONFIG_USE_NPTL)
3953

    
3954
static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
3955
typedef struct {
3956
    CPUState *env;
3957
    pthread_mutex_t mutex;
3958
    pthread_cond_t cond;
3959
    pthread_t thread;
3960
    uint32_t tid;
3961
    abi_ulong child_tidptr;
3962
    abi_ulong parent_tidptr;
3963
    sigset_t sigmask;
3964
} new_thread_info;
3965

    
3966
static void *clone_func(void *arg)
3967
{
3968
    new_thread_info *info = arg;
3969
    CPUState *env;
3970
    TaskState *ts;
3971

    
3972
    env = info->env;
3973
    thread_env = env;
3974
    ts = (TaskState *)thread_env->opaque;
3975
    info->tid = gettid();
3976
    env->host_tid = info->tid;
3977
    task_settid(ts);
3978
    if (info->child_tidptr)
3979
        put_user_u32(info->tid, info->child_tidptr);
3980
    if (info->parent_tidptr)
3981
        put_user_u32(info->tid, info->parent_tidptr);
3982
    /* Enable signals.  */
3983
    sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
3984
    /* Signal to the parent that we're ready.  */
3985
    pthread_mutex_lock(&info->mutex);
3986
    pthread_cond_broadcast(&info->cond);
3987
    pthread_mutex_unlock(&info->mutex);
3988
    /* Wait until the parent has finshed initializing the tls state.  */
3989
    pthread_mutex_lock(&clone_lock);
3990
    pthread_mutex_unlock(&clone_lock);
3991
    cpu_loop(env);
3992
    /* never exits */
3993
    return NULL;
3994
}
3995
#else
3996

    
3997
static int clone_func(void *arg)
3998
{
3999
    CPUState *env = arg;
4000
    cpu_loop(env);
4001
    /* never exits */
4002
    return 0;
4003
}
4004
#endif
4005

    
4006
/* do_fork() Must return host values and target errnos (unlike most
4007
   do_*() functions). */
4008
static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
4009
                   abi_ulong parent_tidptr, target_ulong newtls,
4010
                   abi_ulong child_tidptr)
4011
{
4012
    int ret;
4013
    TaskState *ts;
4014
    CPUState *new_env;
4015
#if defined(CONFIG_USE_NPTL)
4016
    unsigned int nptl_flags;
4017
    sigset_t sigmask;
4018
#else
4019
    uint8_t *new_stack;
4020
#endif
4021

    
4022
    /* Emulate vfork() with fork() */
4023
    if (flags & CLONE_VFORK)
4024
        flags &= ~(CLONE_VFORK | CLONE_VM);
4025

    
4026
    if (flags & CLONE_VM) {
4027
        TaskState *parent_ts = (TaskState *)env->opaque;
4028
#if defined(CONFIG_USE_NPTL)
4029
        new_thread_info info;
4030
        pthread_attr_t attr;
4031
#endif
4032
        ts = g_malloc0(sizeof(TaskState));
4033
        init_task_state(ts);
4034
        /* we create a new CPU instance. */
4035
        new_env = cpu_copy(env);
4036
#if defined(TARGET_I386) || defined(TARGET_SPARC) || defined(TARGET_PPC)
4037
        cpu_reset(new_env);
4038
#endif
4039
        /* Init regs that differ from the parent.  */
4040
        cpu_clone_regs(new_env, newsp);
4041
        new_env->opaque = ts;
4042
        ts->bprm = parent_ts->bprm;
4043
        ts->info = parent_ts->info;
4044
#if defined(CONFIG_USE_NPTL)
4045
        nptl_flags = flags;
4046
        flags &= ~CLONE_NPTL_FLAGS2;
4047

    
4048
        if (nptl_flags & CLONE_CHILD_CLEARTID) {
4049
            ts->child_tidptr = child_tidptr;
4050
        }
4051

    
4052
        if (nptl_flags & CLONE_SETTLS)
4053
            cpu_set_tls (new_env, newtls);
4054

    
4055
        /* Grab a mutex so that thread setup appears atomic.  */
4056
        pthread_mutex_lock(&clone_lock);
4057

    
4058
        memset(&info, 0, sizeof(info));
4059
        pthread_mutex_init(&info.mutex, NULL);
4060
        pthread_mutex_lock(&info.mutex);
4061
        pthread_cond_init(&info.cond, NULL);
4062
        info.env = new_env;
4063
        if (nptl_flags & CLONE_CHILD_SETTID)
4064
            info.child_tidptr = child_tidptr;
4065
        if (nptl_flags & CLONE_PARENT_SETTID)
4066
            info.parent_tidptr = parent_tidptr;
4067

    
4068
        ret = pthread_attr_init(&attr);
4069
        ret = pthread_attr_setstacksize(&attr, NEW_STACK_SIZE);
4070
        ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
4071
        /* It is not safe to deliver signals until the child has finished
4072
           initializing, so temporarily block all signals.  */
4073
        sigfillset(&sigmask);
4074
        sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
4075

    
4076
        ret = pthread_create(&info.thread, &attr, clone_func, &info);
4077
        /* TODO: Free new CPU state if thread creation failed.  */
4078

    
4079
        sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
4080
        pthread_attr_destroy(&attr);
4081
        if (ret == 0) {
4082
            /* Wait for the child to initialize.  */
4083
            pthread_cond_wait(&info.cond, &info.mutex);
4084
            ret = info.tid;
4085
            if (flags & CLONE_PARENT_SETTID)
4086
                put_user_u32(ret, parent_tidptr);
4087
        } else {
4088
            ret = -1;
4089
        }
4090
        pthread_mutex_unlock(&info.mutex);
4091
        pthread_cond_destroy(&info.cond);
4092
        pthread_mutex_destroy(&info.mutex);
4093
        pthread_mutex_unlock(&clone_lock);
4094
#else
4095
        if (flags & CLONE_NPTL_FLAGS2)
4096
            return -EINVAL;
4097
        /* This is probably going to die very quickly, but do it anyway.  */
4098
        new_stack = g_malloc0 (NEW_STACK_SIZE);
4099
#ifdef __ia64__
4100
        ret = __clone2(clone_func, new_stack, NEW_STACK_SIZE, flags, new_env);
4101
#else
4102
        ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
4103
#endif
4104
#endif
4105
    } else {
4106
        /* if no CLONE_VM, we consider it is a fork */
4107
        if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
4108
            return -EINVAL;
4109
        fork_start();
4110
        ret = fork();
4111
        if (ret == 0) {
4112
            /* Child Process.  */
4113
            cpu_clone_regs(env, newsp);
4114
            fork_end(1);
4115
#if defined(CONFIG_USE_NPTL)
4116
            /* There is a race condition here.  The parent process could
4117
               theoretically read the TID in the child process before the child
4118
               tid is set.  This would require using either ptrace
4119
               (not implemented) or having *_tidptr to point at a shared memory
4120
               mapping.  We can't repeat the spinlock hack used above because
4121
               the child process gets its own copy of the lock.  */
4122
            if (flags & CLONE_CHILD_SETTID)
4123
                put_user_u32(gettid(), child_tidptr);
4124
            if (flags & CLONE_PARENT_SETTID)
4125
                put_user_u32(gettid(), parent_tidptr);
4126
            ts = (TaskState *)env->opaque;
4127
            if (flags & CLONE_SETTLS)
4128
                cpu_set_tls (env, newtls);
4129
            if (flags & CLONE_CHILD_CLEARTID)
4130
                ts->child_tidptr = child_tidptr;
4131
#endif
4132
        } else {
4133
            fork_end(0);
4134
        }
4135
    }
4136
    return ret;
4137
}
4138

    
4139
/* warning : doesn't handle linux specific flags... */
4140
static int target_to_host_fcntl_cmd(int cmd)
4141
{
4142
    switch(cmd) {
4143
        case TARGET_F_DUPFD:
4144
        case TARGET_F_GETFD:
4145
        case TARGET_F_SETFD:
4146
        case TARGET_F_GETFL:
4147
        case TARGET_F_SETFL:
4148
            return cmd;
4149
        case TARGET_F_GETLK:
4150
            return F_GETLK;
4151
        case TARGET_F_SETLK:
4152
            return F_SETLK;
4153
        case TARGET_F_SETLKW:
4154
            return F_SETLKW;
4155
        case TARGET_F_GETOWN:
4156
            return F_GETOWN;
4157
        case TARGET_F_SETOWN:
4158
            return F_SETOWN;
4159
        case TARGET_F_GETSIG:
4160
            return F_GETSIG;
4161
        case TARGET_F_SETSIG:
4162
            return F_SETSIG;
4163
#if TARGET_ABI_BITS == 32
4164
        case TARGET_F_GETLK64:
4165
            return F_GETLK64;
4166
        case TARGET_F_SETLK64:
4167
            return F_SETLK64;
4168
        case TARGET_F_SETLKW64:
4169
            return F_SETLKW64;
4170
#endif
4171
        case TARGET_F_SETLEASE:
4172
            return F_SETLEASE;
4173
        case TARGET_F_GETLEASE:
4174
            return F_GETLEASE;
4175
#ifdef F_DUPFD_CLOEXEC
4176
        case TARGET_F_DUPFD_CLOEXEC:
4177
            return F_DUPFD_CLOEXEC;
4178
#endif
4179
        case TARGET_F_NOTIFY:
4180
            return F_NOTIFY;
4181
        default:
4182
            return -TARGET_EINVAL;
4183
    }
4184
    return -TARGET_EINVAL;
4185
}
4186

    
4187
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
4188
{
4189
    struct flock fl;
4190
    struct target_flock *target_fl;
4191
    struct flock64 fl64;
4192
    struct target_flock64 *target_fl64;
4193
    abi_long ret;
4194
    int host_cmd = target_to_host_fcntl_cmd(cmd);
4195

    
4196
    if (host_cmd == -TARGET_EINVAL)
4197
            return host_cmd;
4198

    
4199
    switch(cmd) {
4200
    case TARGET_F_GETLK:
4201
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
4202
            return -TARGET_EFAULT;
4203
        fl.l_type = tswap16(target_fl->l_type);
4204
        fl.l_whence = tswap16(target_fl->l_whence);
4205
        fl.l_start = tswapal(target_fl->l_start);
4206
        fl.l_len = tswapal(target_fl->l_len);
4207
        fl.l_pid = tswap32(target_fl->l_pid);
4208
        unlock_user_struct(target_fl, arg, 0);
4209
        ret = get_errno(fcntl(fd, host_cmd, &fl));
4210
        if (ret == 0) {
4211
            if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
4212
                return -TARGET_EFAULT;
4213
            target_fl->l_type = tswap16(fl.l_type);
4214
            target_fl->l_whence = tswap16(fl.l_whence);
4215
            target_fl->l_start = tswapal(fl.l_start);
4216
            target_fl->l_len = tswapal(fl.l_len);
4217
            target_fl->l_pid = tswap32(fl.l_pid);
4218
            unlock_user_struct(target_fl, arg, 1);
4219
        }
4220
        break;
4221

    
4222
    case TARGET_F_SETLK:
4223
    case TARGET_F_SETLKW:
4224
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
4225
            return -TARGET_EFAULT;
4226
        fl.l_type = tswap16(target_fl->l_type);
4227
        fl.l_whence = tswap16(target_fl->l_whence);
4228
        fl.l_start = tswapal(target_fl->l_start);
4229
        fl.l_len = tswapal(target_fl->l_len);
4230
        fl.l_pid = tswap32(target_fl->l_pid);
4231
        unlock_user_struct(target_fl, arg, 0);
4232
        ret = get_errno(fcntl(fd, host_cmd, &fl));
4233
        break;
4234

    
4235
    case TARGET_F_GETLK64:
4236
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
4237
            return -TARGET_EFAULT;
4238
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
4239
        fl64.l_whence = tswap16(target_fl64->l_whence);
4240
        fl64.l_start = tswap64(target_fl64->l_start);
4241
        fl64.l_len = tswap64(target_fl64->l_len);
4242
        fl64.l_pid = tswap32(target_fl64->l_pid);
4243
        unlock_user_struct(target_fl64, arg, 0);
4244
        ret = get_errno(fcntl(fd, host_cmd, &fl64));
4245
        if (ret == 0) {
4246
            if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
4247
                return -TARGET_EFAULT;
4248
            target_fl64->l_type = tswap16(fl64.l_type) >> 1;
4249
            target_fl64->l_whence = tswap16(fl64.l_whence);
4250
            target_fl64->l_start = tswap64(fl64.l_start);
4251
            target_fl64->l_len = tswap64(fl64.l_len);
4252
            target_fl64->l_pid = tswap32(fl64.l_pid);
4253
            unlock_user_struct(target_fl64, arg, 1);
4254
        }
4255
        break;
4256
    case TARGET_F_SETLK64:
4257
    case TARGET_F_SETLKW64:
4258
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
4259
            return -TARGET_EFAULT;
4260
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
4261
        fl64.l_whence = tswap16(target_fl64->l_whence);
4262
        fl64.l_start = tswap64(target_fl64->l_start);
4263
        fl64.l_len = tswap64(target_fl64->l_len);
4264
        fl64.l_pid = tswap32(target_fl64->l_pid);
4265
        unlock_user_struct(target_fl64, arg, 0);
4266
        ret = get_errno(fcntl(fd, host_cmd, &fl64));
4267
        break;
4268

    
4269
    case TARGET_F_GETFL:
4270
        ret = get_errno(fcntl(fd, host_cmd, arg));
4271
        if (ret >= 0) {
4272
            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
4273
        }
4274
        break;
4275

    
4276
    case TARGET_F_SETFL:
4277
        ret = get_errno(fcntl(fd, host_cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
4278
        break;
4279

    
4280
    case TARGET_F_SETOWN:
4281
    case TARGET_F_GETOWN:
4282
    case TARGET_F_SETSIG:
4283
    case TARGET_F_GETSIG:
4284
    case TARGET_F_SETLEASE:
4285
    case TARGET_F_GETLEASE:
4286
        ret = get_errno(fcntl(fd, host_cmd, arg));
4287
        break;
4288

    
4289
    default:
4290
        ret = get_errno(fcntl(fd, cmd, arg));
4291
        break;
4292
    }
4293
    return ret;
4294
}
4295

    
4296
#ifdef USE_UID16
4297

    
4298
static inline int high2lowuid(int uid)
4299
{
4300
    if (uid > 65535)
4301
        return 65534;
4302
    else
4303
        return uid;
4304
}
4305

    
4306
static inline int high2lowgid(int gid)
4307
{
4308
    if (gid > 65535)
4309
        return 65534;
4310
    else
4311
        return gid;
4312
}
4313

    
4314
static inline int low2highuid(int uid)
4315
{
4316
    if ((int16_t)uid == -1)
4317
        return -1;
4318
    else
4319
        return uid;
4320
}
4321

    
4322
static inline int low2highgid(int gid)
4323
{
4324
    if ((int16_t)gid == -1)
4325
        return -1;
4326
    else
4327
        return gid;
4328
}
4329
static inline int tswapid(int id)
4330
{
4331
    return tswap16(id);
4332
}
4333
#else /* !USE_UID16 */
4334
static inline int high2lowuid(int uid)
4335
{
4336
    return uid;
4337
}
4338
static inline int high2lowgid(int gid)
4339
{
4340
    return gid;
4341
}
4342
static inline int low2highuid(int uid)
4343
{
4344
    return uid;
4345
}
4346
static inline int low2highgid(int gid)
4347
{
4348
    return gid;
4349
}
4350
static inline int tswapid(int id)
4351
{
4352
    return tswap32(id);
4353
}
4354
#endif /* USE_UID16 */
4355

    
4356
void syscall_init(void)
4357
{
4358
    IOCTLEntry *ie;
4359
    const argtype *arg_type;
4360
    int size;
4361
    int i;
4362

    
4363
#define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
4364
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
4365
#include "syscall_types.h"
4366
#undef STRUCT
4367
#undef STRUCT_SPECIAL
4368

    
4369
    /* we patch the ioctl size if necessary. We rely on the fact that
4370
       no ioctl has all the bits at '1' in the size field */
4371
    ie = ioctl_entries;
4372
    while (ie->target_cmd != 0) {
4373
        if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
4374
            TARGET_IOC_SIZEMASK) {
4375
            arg_type = ie->arg_type;
4376
            if (arg_type[0] != TYPE_PTR) {
4377
                fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
4378
                        ie->target_cmd);
4379
                exit(1);
4380
            }
4381
            arg_type++;
4382
            size = thunk_type_size(arg_type, 0);
4383
            ie->target_cmd = (ie->target_cmd &
4384
                              ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
4385
                (size << TARGET_IOC_SIZESHIFT);
4386
        }
4387

    
4388
        /* Build target_to_host_errno_table[] table from
4389
         * host_to_target_errno_table[]. */
4390
        for (i=0; i < ERRNO_TABLE_SIZE; i++)
4391
                target_to_host_errno_table[host_to_target_errno_table[i]] = i;
4392

    
4393
        /* automatic consistency check if same arch */
4394
#if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
4395
    (defined(__x86_64__) && defined(TARGET_X86_64))
4396
        if (unlikely(ie->target_cmd != ie->host_cmd)) {
4397
            fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
4398
                    ie->name, ie->target_cmd, ie->host_cmd);
4399
        }
4400
#endif
4401
        ie++;
4402
    }
4403
}
4404

    
4405
#if TARGET_ABI_BITS == 32
4406
static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
4407
{
4408
#ifdef TARGET_WORDS_BIGENDIAN
4409
    return ((uint64_t)word0 << 32) | word1;
4410
#else
4411
    return ((uint64_t)word1 << 32) | word0;
4412
#endif
4413
}
4414
#else /* TARGET_ABI_BITS == 32 */
4415
static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
4416
{
4417
    return word0;
4418
}
4419
#endif /* TARGET_ABI_BITS != 32 */
4420

    
4421
#ifdef TARGET_NR_truncate64
4422
static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
4423
                                         abi_long arg2,
4424
                                         abi_long arg3,
4425
                                         abi_long arg4)
4426
{
4427
    if (regpairs_aligned(cpu_env)) {
4428
        arg2 = arg3;
4429
        arg3 = arg4;
4430
    }
4431
    return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
4432
}
4433
#endif
4434

    
4435
#ifdef TARGET_NR_ftruncate64
4436
static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
4437
                                          abi_long arg2,
4438
                                          abi_long arg3,
4439
                                          abi_long arg4)
4440
{
4441
    if (regpairs_aligned(cpu_env)) {
4442
        arg2 = arg3;
4443
        arg3 = arg4;
4444
    }
4445
    return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
4446
}
4447
#endif
4448

    
4449
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
4450
                                               abi_ulong target_addr)
4451
{
4452
    struct target_timespec *target_ts;
4453

    
4454
    if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
4455
        return -TARGET_EFAULT;
4456
    host_ts->tv_sec = tswapal(target_ts->tv_sec);
4457
    host_ts->tv_nsec = tswapal(target_ts->tv_nsec);
4458
    unlock_user_struct(target_ts, target_addr, 0);
4459
    return 0;
4460
}
4461

    
4462
static inline abi_long host_to_target_timespec(abi_ulong target_addr,
4463
                                               struct timespec *host_ts)
4464
{
4465
    struct target_timespec *target_ts;
4466

    
4467
    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
4468
        return -TARGET_EFAULT;
4469
    target_ts->tv_sec = tswapal(host_ts->tv_sec);
4470
    target_ts->tv_nsec = tswapal(host_ts->tv_nsec);
4471
    unlock_user_struct(target_ts, target_addr, 1);
4472
    return 0;
4473
}
4474

    
4475
#if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
4476
static inline abi_long host_to_target_stat64(void *cpu_env,
4477
                                             abi_ulong target_addr,
4478
                                             struct stat *host_st)
4479
{
4480
#ifdef TARGET_ARM
4481
    if (((CPUARMState *)cpu_env)->eabi) {
4482
        struct target_eabi_stat64 *target_st;
4483

    
4484
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
4485
            return -TARGET_EFAULT;
4486
        memset(target_st, 0, sizeof(struct target_eabi_stat64));
4487
        __put_user(host_st->st_dev, &target_st->st_dev);
4488
        __put_user(host_st->st_ino, &target_st->st_ino);
4489
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4490
        __put_user(host_st->st_ino, &target_st->__st_ino);
4491
#endif
4492
        __put_user(host_st->st_mode, &target_st->st_mode);
4493
        __put_user(host_st->st_nlink, &target_st->st_nlink);
4494
        __put_user(host_st->st_uid, &target_st->st_uid);
4495
        __put_user(host_st->st_gid, &target_st->st_gid);
4496
        __put_user(host_st->st_rdev, &target_st->st_rdev);
4497
        __put_user(host_st->st_size, &target_st->st_size);
4498
        __put_user(host_st->st_blksize, &target_st->st_blksize);
4499
        __put_user(host_st->st_blocks, &target_st->st_blocks);
4500
        __put_user(host_st->st_atime, &target_st->target_st_atime);
4501
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
4502
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
4503
        unlock_user_struct(target_st, target_addr, 1);
4504
    } else
4505
#endif
4506
    {
4507
#if TARGET_ABI_BITS == 64 && !defined(TARGET_ALPHA)
4508
        struct target_stat *target_st;
4509
#else
4510
        struct target_stat64 *target_st;
4511
#endif
4512

    
4513
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
4514
            return -TARGET_EFAULT;
4515
        memset(target_st, 0, sizeof(*target_st));
4516
        __put_user(host_st->st_dev, &target_st->st_dev);
4517
        __put_user(host_st->st_ino, &target_st->st_ino);
4518
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4519
        __put_user(host_st->st_ino, &target_st->__st_ino);
4520
#endif
4521
        __put_user(host_st->st_mode, &target_st->st_mode);
4522
        __put_user(host_st->st_nlink, &target_st->st_nlink);
4523
        __put_user(host_st->st_uid, &target_st->st_uid);
4524
        __put_user(host_st->st_gid, &target_st->st_gid);
4525
        __put_user(host_st->st_rdev, &target_st->st_rdev);
4526
        /* XXX: better use of kernel struct */
4527
        __put_user(host_st->st_size, &target_st->st_size);
4528
        __put_user(host_st->st_blksize, &target_st->st_blksize);
4529
        __put_user(host_st->st_blocks, &target_st->st_blocks);
4530
        __put_user(host_st->st_atime, &target_st->target_st_atime);
4531
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
4532
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
4533
        unlock_user_struct(target_st, target_addr, 1);
4534
    }
4535

    
4536
    return 0;
4537
}
4538
#endif
4539

    
4540
#if defined(CONFIG_USE_NPTL)
4541
/* ??? Using host futex calls even when target atomic operations
4542
   are not really atomic probably breaks things.  However implementing
4543
   futexes locally would make futexes shared between multiple processes
4544
   tricky.  However they're probably useless because guest atomic
4545
   operations won't work either.  */
4546
static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
4547
                    target_ulong uaddr2, int val3)
4548
{
4549
    struct timespec ts, *pts;
4550
    int base_op;
4551

    
4552
    /* ??? We assume FUTEX_* constants are the same on both host
4553
       and target.  */
4554
#ifdef FUTEX_CMD_MASK
4555
    base_op = op & FUTEX_CMD_MASK;
4556
#else
4557
    base_op = op;
4558
#endif
4559
    switch (base_op) {
4560
    case FUTEX_WAIT:
4561
        if (timeout) {
4562
            pts = &ts;
4563
            target_to_host_timespec(pts, timeout);
4564
        } else {
4565
            pts = NULL;
4566
        }
4567
        return get_errno(sys_futex(g2h(uaddr), op, tswap32(val),
4568
                         pts, NULL, 0));
4569
    case FUTEX_WAKE:
4570
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4571
    case FUTEX_FD:
4572
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4573
    case FUTEX_REQUEUE:
4574
    case FUTEX_CMP_REQUEUE:
4575
    case FUTEX_WAKE_OP:
4576
        /* For FUTEX_REQUEUE, FUTEX_CMP_REQUEUE, and FUTEX_WAKE_OP, the
4577
           TIMEOUT parameter is interpreted as a uint32_t by the kernel.
4578
           But the prototype takes a `struct timespec *'; insert casts
4579
           to satisfy the compiler.  We do not need to tswap TIMEOUT
4580
           since it's not compared to guest memory.  */
4581
        pts = (struct timespec *)(uintptr_t) timeout;
4582
        return get_errno(sys_futex(g2h(uaddr), op, val, pts,
4583
                                   g2h(uaddr2),
4584
                                   (base_op == FUTEX_CMP_REQUEUE
4585
                                    ? tswap32(val3)
4586
                                    : val3)));
4587
    default:
4588
        return -TARGET_ENOSYS;
4589
    }
4590
}
4591
#endif
4592

    
4593
/* Map host to target signal numbers for the wait family of syscalls.
4594
   Assume all other status bits are the same.  */
4595
static int host_to_target_waitstatus(int status)
4596
{
4597
    if (WIFSIGNALED(status)) {
4598
        return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f);
4599
    }
4600
    if (WIFSTOPPED(status)) {
4601
        return (host_to_target_signal(WSTOPSIG(status)) << 8)
4602
               | (status & 0xff);
4603
    }
4604
    return status;
4605
}
4606

    
4607
int get_osversion(void)
4608
{
4609
    static int osversion;
4610
    struct new_utsname buf;
4611
    const char *s;
4612
    int i, n, tmp;
4613
    if (osversion)
4614
        return osversion;
4615
    if (qemu_uname_release && *qemu_uname_release) {
4616
        s = qemu_uname_release;
4617
    } else {
4618
        if (sys_uname(&buf))
4619
            return 0;
4620
        s = buf.release;
4621
    }
4622
    tmp = 0;
4623
    for (i = 0; i < 3; i++) {
4624
        n = 0;
4625
        while (*s >= '0' && *s <= '9') {
4626
            n *= 10;
4627
            n += *s - '0';
4628
            s++;
4629
        }
4630
        tmp = (tmp << 8) + n;
4631
        if (*s == '.')
4632
            s++;
4633
    }
4634
    osversion = tmp;
4635
    return osversion;
4636
}
4637

    
4638

    
4639
static int open_self_maps(void *cpu_env, int fd)
4640
{
4641
    TaskState *ts = ((CPUState *)cpu_env)->opaque;
4642

    
4643
    dprintf(fd, "%08llx-%08llx rw-p %08llx 00:00 0          [stack]\n",
4644
                (unsigned long long)ts->info->stack_limit,
4645
                (unsigned long long)(ts->stack_base + (TARGET_PAGE_SIZE - 1))
4646
                                     & TARGET_PAGE_MASK,
4647
                (unsigned long long)ts->stack_base);
4648

    
4649
    return 0;
4650
}
4651

    
4652
static int open_self_stat(void *cpu_env, int fd)
4653
{
4654
    TaskState *ts = ((CPUState *)cpu_env)->opaque;
4655
    abi_ulong start_stack = ts->info->start_stack;
4656
    int i;
4657

    
4658
    for (i = 0; i < 44; i++) {
4659
      char buf[128];
4660
      int len;
4661
      uint64_t val = 0;
4662

    
4663
      if (i == 27) {
4664
          /* stack bottom */
4665
          val = start_stack;
4666
      }
4667
      snprintf(buf, sizeof(buf), "%"PRId64 "%c", val, i == 43 ? '\n' : ' ');
4668
      len = strlen(buf);
4669
      if (write(fd, buf, len) != len) {
4670
          return -1;
4671
      }
4672
    }
4673

    
4674
    return 0;
4675
}
4676

    
4677
static int open_self_auxv(void *cpu_env, int fd)
4678
{
4679
    TaskState *ts = ((CPUState *)cpu_env)->opaque;
4680
    abi_ulong auxv = ts->info->saved_auxv;
4681
    abi_ulong len = ts->info->auxv_len;
4682
    char *ptr;
4683

    
4684
    /*
4685
     * Auxiliary vector is stored in target process stack.
4686
     * read in whole auxv vector and copy it to file
4687
     */
4688
    ptr = lock_user(VERIFY_READ, auxv, len, 0);
4689
    if (ptr != NULL) {
4690
        while (len > 0) {
4691
            ssize_t r;
4692
            r = write(fd, ptr, len);
4693
            if (r <= 0) {
4694
                break;
4695
            }
4696
            len -= r;
4697
            ptr += r;
4698
        }
4699
        lseek(fd, 0, SEEK_SET);
4700
        unlock_user(ptr, auxv, len);
4701
    }
4702

    
4703
    return 0;
4704
}
4705

    
4706
static int do_open(void *cpu_env, const char *pathname, int flags, mode_t mode)
4707
{
4708
    struct fake_open {
4709
        const char *filename;
4710
        int (*fill)(void *cpu_env, int fd);
4711
    };
4712
    const struct fake_open *fake_open;
4713
    static const struct fake_open fakes[] = {
4714
        { "/proc/self/maps", open_self_maps },
4715
        { "/proc/self/stat", open_self_stat },
4716
        { "/proc/self/auxv", open_self_auxv },
4717
        { NULL, NULL }
4718
    };
4719

    
4720
    for (fake_open = fakes; fake_open->filename; fake_open++) {
4721
        if (!strncmp(pathname, fake_open->filename,
4722
                     strlen(fake_open->filename))) {
4723
            break;
4724
        }
4725
    }
4726

    
4727
    if (fake_open->filename) {
4728
        const char *tmpdir;
4729
        char filename[PATH_MAX];
4730
        int fd, r;
4731

    
4732
        /* create temporary file to map stat to */
4733
        tmpdir = getenv("TMPDIR");
4734
        if (!tmpdir)
4735
            tmpdir = "/tmp";
4736
        snprintf(filename, sizeof(filename), "%s/qemu-open.XXXXXX", tmpdir);
4737
        fd = mkstemp(filename);
4738
        if (fd < 0) {
4739
            return fd;
4740
        }
4741
        unlink(filename);
4742

    
4743
        if ((r = fake_open->fill(cpu_env, fd))) {
4744
            close(fd);
4745
            return r;
4746
        }
4747
        lseek(fd, 0, SEEK_SET);
4748

    
4749
        return fd;
4750
    }
4751

    
4752
    return get_errno(open(path(pathname), flags, mode));
4753
}
4754

    
4755
/* do_syscall() should always have a single exit point at the end so
4756
   that actions, such as logging of syscall results, can be performed.
4757
   All errnos that do_syscall() returns must be -TARGET_<errcode>. */
4758
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4759
                    abi_long arg2, abi_long arg3, abi_long arg4,
4760
                    abi_long arg5, abi_long arg6, abi_long arg7,
4761
                    abi_long arg8)
4762
{
4763
    abi_long ret;
4764
    struct stat st;
4765
    struct statfs stfs;
4766
    void *p;
4767

    
4768
#ifdef DEBUG
4769
    gemu_log("syscall %d", num);
4770
#endif
4771
    if(do_strace)
4772
        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
4773

    
4774
    switch(num) {
4775
    case TARGET_NR_exit:
4776
#ifdef CONFIG_USE_NPTL
4777
      /* In old applications this may be used to implement _exit(2).
4778
         However in threaded applictions it is used for thread termination,
4779
         and _exit_group is used for application termination.
4780
         Do thread termination if we have more then one thread.  */
4781
      /* FIXME: This probably breaks if a signal arrives.  We should probably
4782
         be disabling signals.  */
4783
      if (first_cpu->next_cpu) {
4784
          TaskState *ts;
4785
          CPUState **lastp;
4786
          CPUState *p;
4787

    
4788
          cpu_list_lock();
4789
          lastp = &first_cpu;
4790
          p = first_cpu;
4791
          while (p && p != (CPUState *)cpu_env) {
4792
              lastp = &p->next_cpu;
4793
              p = p->next_cpu;
4794
          }
4795
          /* If we didn't find the CPU for this thread then something is
4796
             horribly wrong.  */
4797
          if (!p)
4798
              abort();
4799
          /* Remove the CPU from the list.  */
4800
          *lastp = p->next_cpu;
4801
          cpu_list_unlock();
4802
          ts = ((CPUState *)cpu_env)->opaque;
4803
          if (ts->child_tidptr) {
4804
              put_user_u32(0, ts->child_tidptr);
4805
              sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
4806
                        NULL, NULL, 0);
4807
          }
4808
          thread_env = NULL;
4809
          g_free(cpu_env);
4810
          g_free(ts);
4811
          pthread_exit(NULL);
4812
      }
4813
#endif
4814
#ifdef TARGET_GPROF
4815
        _mcleanup();
4816
#endif
4817
        gdb_exit(cpu_env, arg1);
4818
        _exit(arg1);
4819
        ret = 0; /* avoid warning */
4820
        break;
4821
    case TARGET_NR_read:
4822
        if (arg3 == 0)
4823
            ret = 0;
4824
        else {
4825
            if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
4826
                goto efault;
4827
            ret = get_errno(read(arg1, p, arg3));
4828
            unlock_user(p, arg2, ret);
4829
        }
4830
        break;
4831
    case TARGET_NR_write:
4832
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
4833
            goto efault;
4834
        ret = get_errno(write(arg1, p, arg3));
4835
        unlock_user(p, arg2, 0);
4836
        break;
4837
    case TARGET_NR_open:
4838
        if (!(p = lock_user_string(arg1)))
4839
            goto efault;
4840
        ret = get_errno(do_open(cpu_env, p,
4841
                                target_to_host_bitmask(arg2, fcntl_flags_tbl),
4842
                                arg3));
4843
        unlock_user(p, arg1, 0);
4844
        break;
4845
#if defined(TARGET_NR_openat) && defined(__NR_openat)
4846
    case TARGET_NR_openat:
4847
        if (!(p = lock_user_string(arg2)))
4848
            goto efault;
4849
        ret = get_errno(sys_openat(arg1,
4850
                                   path(p),
4851
                                   target_to_host_bitmask(arg3, fcntl_flags_tbl),
4852
                                   arg4));
4853
        unlock_user(p, arg2, 0);
4854
        break;
4855
#endif
4856
    case TARGET_NR_close:
4857
        ret = get_errno(close(arg1));
4858
        break;
4859
    case TARGET_NR_brk:
4860
        ret = do_brk(arg1);
4861
        break;
4862
    case TARGET_NR_fork:
4863
        ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
4864
        break;
4865
#ifdef TARGET_NR_waitpid
4866
    case TARGET_NR_waitpid:
4867
        {
4868
            int status;
4869
            ret = get_errno(waitpid(arg1, &status, arg3));
4870
            if (!is_error(ret) && arg2 && ret
4871
                && put_user_s32(host_to_target_waitstatus(status), arg2))
4872
                goto efault;
4873
        }
4874
        break;
4875
#endif
4876
#ifdef TARGET_NR_waitid
4877
    case TARGET_NR_waitid:
4878
        {
4879
            siginfo_t info;
4880
            info.si_pid = 0;
4881
            ret = get_errno(waitid(arg1, arg2, &info, arg4));
4882
            if (!is_error(ret) && arg3 && info.si_pid != 0) {
4883
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
4884
                    goto efault;
4885
                host_to_target_siginfo(p, &info);
4886
                unlock_user(p, arg3, sizeof(target_siginfo_t));
4887
            }
4888
        }
4889
        break;
4890
#endif
4891
#ifdef TARGET_NR_creat /* not on alpha */
4892
    case TARGET_NR_creat:
4893
        if (!(p = lock_user_string(arg1)))
4894
            goto efault;
4895
        ret = get_errno(creat(p, arg2));
4896
        unlock_user(p, arg1, 0);
4897
        break;
4898
#endif
4899
    case TARGET_NR_link:
4900
        {
4901
            void * p2;
4902
            p = lock_user_string(arg1);
4903
            p2 = lock_user_string(arg2);
4904
            if (!p || !p2)
4905
                ret = -TARGET_EFAULT;
4906
            else
4907
                ret = get_errno(link(p, p2));
4908
            unlock_user(p2, arg2, 0);
4909
            unlock_user(p, arg1, 0);
4910
        }
4911
        break;
4912
#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
4913
    case TARGET_NR_linkat:
4914
        {
4915
            void * p2 = NULL;
4916
            if (!arg2 || !arg4)
4917
                goto efault;
4918
            p  = lock_user_string(arg2);
4919
            p2 = lock_user_string(arg4);
4920
            if (!p || !p2)
4921
                ret = -TARGET_EFAULT;
4922
            else
4923
                ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
4924
            unlock_user(p, arg2, 0);
4925
            unlock_user(p2, arg4, 0);
4926
        }
4927
        break;
4928
#endif
4929
    case TARGET_NR_unlink:
4930
        if (!(p = lock_user_string(arg1)))
4931
            goto efault;
4932
        ret = get_errno(unlink(p));
4933
        unlock_user(p, arg1, 0);
4934
        break;
4935
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
4936
    case TARGET_NR_unlinkat:
4937
        if (!(p = lock_user_string(arg2)))
4938
            goto efault;
4939
        ret = get_errno(sys_unlinkat(arg1, p, arg3));
4940
        unlock_user(p, arg2, 0);
4941
        break;
4942
#endif
4943
    case TARGET_NR_execve:
4944
        {
4945
            char **argp, **envp;
4946
            int argc, envc;
4947
            abi_ulong gp;
4948
            abi_ulong guest_argp;
4949
            abi_ulong guest_envp;
4950
            abi_ulong addr;
4951
            char **q;
4952
            int total_size = 0;
4953

    
4954
            argc = 0;
4955
            guest_argp = arg2;
4956
            for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
4957
                if (get_user_ual(addr, gp))
4958
                    goto efault;
4959
                if (!addr)
4960
                    break;
4961
                argc++;
4962
            }
4963
            envc = 0;
4964
            guest_envp = arg3;
4965
            for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
4966
                if (get_user_ual(addr, gp))
4967
                    goto efault;
4968
                if (!addr)
4969
                    break;
4970
                envc++;
4971
            }
4972

    
4973
            argp = alloca((argc + 1) * sizeof(void *));
4974
            envp = alloca((envc + 1) * sizeof(void *));
4975

    
4976
            for (gp = guest_argp, q = argp; gp;
4977
                  gp += sizeof(abi_ulong), q++) {
4978
                if (get_user_ual(addr, gp))
4979
                    goto execve_efault;
4980
                if (!addr)