Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ 95b33b2f

History | View | Annotate | Download (248.7 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

    
74
#define termios host_termios
75
#define winsize host_winsize
76
#define termio host_termio
77
#define sgttyb host_sgttyb /* same as target */
78
#define tchars host_tchars /* same as target */
79
#define ltchars host_ltchars /* same as target */
80

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

    
98
#include "qemu.h"
99
#include "qemu-common.h"
100

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

    
109
//#define DEBUG
110

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

    
115

    
116
#undef _syscall0
117
#undef _syscall1
118
#undef _syscall2
119
#undef _syscall3
120
#undef _syscall4
121
#undef _syscall5
122
#undef _syscall6
123

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

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

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

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

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

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

    
161

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

    
170

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

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

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

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

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

    
277
static int sys_uname(struct new_utsname *buf)
278
{
279
  struct utsname uts_buf;
280

    
281
  if (uname(&uts_buf) < 0)
282
      return (-1);
283

    
284
  /*
285
   * Just in case these have some differences, we
286
   * translate utsname to new_utsname (which is the
287
   * struct linux kernel uses).
288
   */
289

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

    
301
#undef COPY_UTSNAME_FIELD
302
}
303

    
304
static int sys_getcwd1(char *buf, size_t size)
305
{
306
  if (getcwd(buf, size) == NULL) {
307
      /* getcwd() sets errno */
308
      return (-1);
309
  }
310
  return strlen(buf)+1;
311
}
312

    
313
#ifdef CONFIG_ATFILE
314
/*
315
 * Host system seems to have atfile syscall stubs available.  We
316
 * now enable them one by one as specified by target syscall_nr.h.
317
 */
318

    
319
#ifdef TARGET_NR_faccessat
320
static int sys_faccessat(int dirfd, const char *pathname, int mode)
321
{
322
  return (faccessat(dirfd, pathname, mode, 0));
323
}
324
#endif
325
#ifdef TARGET_NR_fchmodat
326
static int sys_fchmodat(int dirfd, const char *pathname, mode_t mode)
327
{
328
  return (fchmodat(dirfd, pathname, mode, 0));
329
}
330
#endif
331
#if defined(TARGET_NR_fchownat)
332
static int sys_fchownat(int dirfd, const char *pathname, uid_t owner,
333
    gid_t group, int flags)
334
{
335
  return (fchownat(dirfd, pathname, owner, group, flags));
336
}
337
#endif
338
#ifdef __NR_fstatat64
339
static int sys_fstatat64(int dirfd, const char *pathname, struct stat *buf,
340
    int flags)
341
{
342
  return (fstatat(dirfd, pathname, buf, flags));
343
}
344
#endif
345
#ifdef __NR_newfstatat
346
static int sys_newfstatat(int dirfd, const char *pathname, struct stat *buf,
347
    int flags)
348
{
349
  return (fstatat(dirfd, pathname, buf, flags));
350
}
351
#endif
352
#ifdef TARGET_NR_futimesat
353
static int sys_futimesat(int dirfd, const char *pathname,
354
    const struct timeval times[2])
355
{
356
  return (futimesat(dirfd, pathname, times));
357
}
358
#endif
359
#ifdef TARGET_NR_linkat
360
static int sys_linkat(int olddirfd, const char *oldpath,
361
    int newdirfd, const char *newpath, int flags)
362
{
363
  return (linkat(olddirfd, oldpath, newdirfd, newpath, flags));
364
}
365
#endif
366
#ifdef TARGET_NR_mkdirat
367
static int sys_mkdirat(int dirfd, const char *pathname, mode_t mode)
368
{
369
  return (mkdirat(dirfd, pathname, mode));
370
}
371
#endif
372
#ifdef TARGET_NR_mknodat
373
static int sys_mknodat(int dirfd, const char *pathname, mode_t mode,
374
    dev_t dev)
375
{
376
  return (mknodat(dirfd, pathname, mode, dev));
377
}
378
#endif
379
#ifdef TARGET_NR_openat
380
static int sys_openat(int dirfd, const char *pathname, int flags, ...)
381
{
382
  /*
383
   * open(2) has extra parameter 'mode' when called with
384
   * flag O_CREAT.
385
   */
386
  if ((flags & O_CREAT) != 0) {
387
      va_list ap;
388
      mode_t mode;
389

    
390
      /*
391
       * Get the 'mode' parameter and translate it to
392
       * host bits.
393
       */
394
      va_start(ap, flags);
395
      mode = va_arg(ap, mode_t);
396
      mode = target_to_host_bitmask(mode, fcntl_flags_tbl);
397
      va_end(ap);
398

    
399
      return (openat(dirfd, pathname, flags, mode));
400
  }
401
  return (openat(dirfd, pathname, flags));
402
}
403
#endif
404
#ifdef TARGET_NR_readlinkat
405
static int sys_readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz)
406
{
407
  return (readlinkat(dirfd, pathname, buf, bufsiz));
408
}
409
#endif
410
#ifdef TARGET_NR_renameat
411
static int sys_renameat(int olddirfd, const char *oldpath,
412
    int newdirfd, const char *newpath)
413
{
414
  return (renameat(olddirfd, oldpath, newdirfd, newpath));
415
}
416
#endif
417
#ifdef TARGET_NR_symlinkat
418
static int sys_symlinkat(const char *oldpath, int newdirfd, const char *newpath)
419
{
420
  return (symlinkat(oldpath, newdirfd, newpath));
421
}
422
#endif
423
#ifdef TARGET_NR_unlinkat
424
static int sys_unlinkat(int dirfd, const char *pathname, int flags)
425
{
426
  return (unlinkat(dirfd, pathname, flags));
427
}
428
#endif
429
#else /* !CONFIG_ATFILE */
430

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

    
488
#endif /* CONFIG_ATFILE */
489

    
490
#ifdef CONFIG_UTIMENSAT
491
static int sys_utimensat(int dirfd, const char *pathname,
492
    const struct timespec times[2], int flags)
493
{
494
    if (pathname == NULL)
495
        return futimens(dirfd, times);
496
    else
497
        return utimensat(dirfd, pathname, times, flags);
498
}
499
#else
500
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
501
_syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
502
          const struct timespec *,tsp,int,flags)
503
#endif
504
#endif /* CONFIG_UTIMENSAT  */
505

    
506
#ifdef CONFIG_INOTIFY
507
#include <sys/inotify.h>
508

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

    
543
#if defined(TARGET_NR_ppoll)
544
#ifndef __NR_ppoll
545
# define __NR_ppoll -1
546
#endif
547
#define __NR_sys_ppoll __NR_ppoll
548
_syscall5(int, sys_ppoll, struct pollfd *, fds, nfds_t, nfds,
549
          struct timespec *, timeout, const __sigset_t *, sigmask,
550
          size_t, sigsetsize)
551
#endif
552

    
553
#if defined(TARGET_NR_pselect6)
554
#ifndef __NR_pselect6
555
# define __NR_pselect6 -1
556
#endif
557
#define __NR_sys_pselect6 __NR_pselect6
558
_syscall6(int, sys_pselect6, int, nfds, fd_set *, readfds, fd_set *, writefds,
559
          fd_set *, exceptfds, struct timespec *, timeout, void *, sig);
560
#endif
561

    
562
#if defined(TARGET_NR_prlimit64)
563
#ifndef __NR_prlimit64
564
# define __NR_prlimit64 -1
565
#endif
566
#define __NR_sys_prlimit64 __NR_prlimit64
567
/* The glibc rlimit structure may not be that used by the underlying syscall */
568
struct host_rlimit64 {
569
    uint64_t rlim_cur;
570
    uint64_t rlim_max;
571
};
572
_syscall4(int, sys_prlimit64, pid_t, pid, int, resource,
573
          const struct host_rlimit64 *, new_limit,
574
          struct host_rlimit64 *, old_limit)
575
#endif
576

    
577
extern int personality(int);
578
extern int flock(int, int);
579
extern int setfsuid(int);
580
extern int setfsgid(int);
581
extern int setgroups(int, gid_t *);
582

    
583
#define ERRNO_TABLE_SIZE 1200
584

    
585
/* target_to_host_errno_table[] is initialized from
586
 * host_to_target_errno_table[] in syscall_init(). */
587
static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
588
};
589

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

    
702
static inline int host_to_target_errno(int err)
703
{
704
    if(host_to_target_errno_table[err])
705
        return host_to_target_errno_table[err];
706
    return err;
707
}
708

    
709
static inline int target_to_host_errno(int err)
710
{
711
    if (target_to_host_errno_table[err])
712
        return target_to_host_errno_table[err];
713
    return err;
714
}
715

    
716
static inline abi_long get_errno(abi_long ret)
717
{
718
    if (ret == -1)
719
        return -host_to_target_errno(errno);
720
    else
721
        return ret;
722
}
723

    
724
static inline int is_error(abi_long ret)
725
{
726
    return (abi_ulong)ret >= (abi_ulong)(-4096);
727
}
728

    
729
char *target_strerror(int err)
730
{
731
    return strerror(target_to_host_errno(err));
732
}
733

    
734
static abi_ulong target_brk;
735
static abi_ulong target_original_brk;
736
static abi_ulong brk_page;
737

    
738
void target_set_brk(abi_ulong new_brk)
739
{
740
    target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
741
    brk_page = HOST_PAGE_ALIGN(target_brk);
742
}
743

    
744
//#define DEBUGF_BRK(message, args...) do { fprintf(stderr, (message), ## args); } while (0)
745
#define DEBUGF_BRK(message, args...)
746

    
747
/* do_brk() must return target values and target errnos. */
748
abi_long do_brk(abi_ulong new_brk)
749
{
750
    abi_long mapped_addr;
751
    int        new_alloc_size;
752

    
753
    DEBUGF_BRK("do_brk(%#010x) -> ", new_brk);
754

    
755
    if (!new_brk) {
756
        DEBUGF_BRK("%#010x (!new_brk)\n", target_brk);
757
        return target_brk;
758
    }
759
    if (new_brk < target_original_brk) {
760
        DEBUGF_BRK("%#010x (new_brk < target_original_brk)\n", target_brk);
761
        return target_brk;
762
    }
763

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

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

    
788
    if (mapped_addr == brk_page) {
789
        target_brk = new_brk;
790
        brk_page = HOST_PAGE_ALIGN(target_brk);
791
        DEBUGF_BRK("%#010x (mapped_addr == brk_page)\n", target_brk);
792
        return target_brk;
793
    } else if (mapped_addr != -1) {
794
        /* Mapped but at wrong address, meaning there wasn't actually
795
         * enough space for this brk.
796
         */
797
        target_munmap(mapped_addr, new_alloc_size);
798
        mapped_addr = -1;
799
        DEBUGF_BRK("%#010x (mapped_addr != -1)\n", target_brk);
800
    }
801
    else {
802
        DEBUGF_BRK("%#010x (otherwise)\n", target_brk);
803
    }
804

    
805
#if defined(TARGET_ALPHA)
806
    /* We (partially) emulate OSF/1 on Alpha, which requires we
807
       return a proper errno, not an unchanged brk value.  */
808
    return -TARGET_ENOMEM;
809
#endif
810
    /* For everything else, return the previous break. */
811
    return target_brk;
812
}
813

    
814
static inline abi_long copy_from_user_fdset(fd_set *fds,
815
                                            abi_ulong target_fds_addr,
816
                                            int n)
817
{
818
    int i, nw, j, k;
819
    abi_ulong b, *target_fds;
820

    
821
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
822
    if (!(target_fds = lock_user(VERIFY_READ,
823
                                 target_fds_addr,
824
                                 sizeof(abi_ulong) * nw,
825
                                 1)))
826
        return -TARGET_EFAULT;
827

    
828
    FD_ZERO(fds);
829
    k = 0;
830
    for (i = 0; i < nw; i++) {
831
        /* grab the abi_ulong */
832
        __get_user(b, &target_fds[i]);
833
        for (j = 0; j < TARGET_ABI_BITS; j++) {
834
            /* check the bit inside the abi_ulong */
835
            if ((b >> j) & 1)
836
                FD_SET(k, fds);
837
            k++;
838
        }
839
    }
840

    
841
    unlock_user(target_fds, target_fds_addr, 0);
842

    
843
    return 0;
844
}
845

    
846
static inline abi_ulong copy_from_user_fdset_ptr(fd_set *fds, fd_set **fds_ptr,
847
                                                 abi_ulong target_fds_addr,
848
                                                 int n)
849
{
850
    if (target_fds_addr) {
851
        if (copy_from_user_fdset(fds, target_fds_addr, n))
852
            return -TARGET_EFAULT;
853
        *fds_ptr = fds;
854
    } else {
855
        *fds_ptr = NULL;
856
    }
857
    return 0;
858
}
859

    
860
static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
861
                                          const fd_set *fds,
862
                                          int n)
863
{
864
    int i, nw, j, k;
865
    abi_long v;
866
    abi_ulong *target_fds;
867

    
868
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
869
    if (!(target_fds = lock_user(VERIFY_WRITE,
870
                                 target_fds_addr,
871
                                 sizeof(abi_ulong) * nw,
872
                                 0)))
873
        return -TARGET_EFAULT;
874

    
875
    k = 0;
876
    for (i = 0; i < nw; i++) {
877
        v = 0;
878
        for (j = 0; j < TARGET_ABI_BITS; j++) {
879
            v |= ((FD_ISSET(k, fds) != 0) << j);
880
            k++;
881
        }
882
        __put_user(v, &target_fds[i]);
883
    }
884

    
885
    unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
886

    
887
    return 0;
888
}
889

    
890
#if defined(__alpha__)
891
#define HOST_HZ 1024
892
#else
893
#define HOST_HZ 100
894
#endif
895

    
896
static inline abi_long host_to_target_clock_t(long ticks)
897
{
898
#if HOST_HZ == TARGET_HZ
899
    return ticks;
900
#else
901
    return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
902
#endif
903
}
904

    
905
static inline abi_long host_to_target_rusage(abi_ulong target_addr,
906
                                             const struct rusage *rusage)
907
{
908
    struct target_rusage *target_rusage;
909

    
910
    if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
911
        return -TARGET_EFAULT;
912
    target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
913
    target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
914
    target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
915
    target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec);
916
    target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss);
917
    target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss);
918
    target_rusage->ru_idrss = tswapl(rusage->ru_idrss);
919
    target_rusage->ru_isrss = tswapl(rusage->ru_isrss);
920
    target_rusage->ru_minflt = tswapl(rusage->ru_minflt);
921
    target_rusage->ru_majflt = tswapl(rusage->ru_majflt);
922
    target_rusage->ru_nswap = tswapl(rusage->ru_nswap);
923
    target_rusage->ru_inblock = tswapl(rusage->ru_inblock);
924
    target_rusage->ru_oublock = tswapl(rusage->ru_oublock);
925
    target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd);
926
    target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv);
927
    target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);
928
    target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
929
    target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
930
    unlock_user_struct(target_rusage, target_addr, 1);
931

    
932
    return 0;
933
}
934

    
935
static inline rlim_t target_to_host_rlim(target_ulong target_rlim)
936
{
937
    target_ulong target_rlim_swap;
938
    rlim_t result;
939
    
940
    target_rlim_swap = tswapl(target_rlim);
941
    if (target_rlim_swap == TARGET_RLIM_INFINITY || target_rlim_swap != (rlim_t)target_rlim_swap)
942
        result = RLIM_INFINITY;
943
    else
944
        result = target_rlim_swap;
945
    
946
    return result;
947
}
948

    
949
static inline target_ulong host_to_target_rlim(rlim_t rlim)
950
{
951
    target_ulong target_rlim_swap;
952
    target_ulong result;
953
    
954
    if (rlim == RLIM_INFINITY || rlim != (target_long)rlim)
955
        target_rlim_swap = TARGET_RLIM_INFINITY;
956
    else
957
        target_rlim_swap = rlim;
958
    result = tswapl(target_rlim_swap);
959
    
960
    return result;
961
}
962

    
963
static inline abi_long copy_from_user_timeval(struct timeval *tv,
964
                                              abi_ulong target_tv_addr)
965
{
966
    struct target_timeval *target_tv;
967

    
968
    if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
969
        return -TARGET_EFAULT;
970

    
971
    __get_user(tv->tv_sec, &target_tv->tv_sec);
972
    __get_user(tv->tv_usec, &target_tv->tv_usec);
973

    
974
    unlock_user_struct(target_tv, target_tv_addr, 0);
975

    
976
    return 0;
977
}
978

    
979
static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
980
                                            const struct timeval *tv)
981
{
982
    struct target_timeval *target_tv;
983

    
984
    if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
985
        return -TARGET_EFAULT;
986

    
987
    __put_user(tv->tv_sec, &target_tv->tv_sec);
988
    __put_user(tv->tv_usec, &target_tv->tv_usec);
989

    
990
    unlock_user_struct(target_tv, target_tv_addr, 1);
991

    
992
    return 0;
993
}
994

    
995
#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
996
#include <mqueue.h>
997

    
998
static inline abi_long copy_from_user_mq_attr(struct mq_attr *attr,
999
                                              abi_ulong target_mq_attr_addr)
1000
{
1001
    struct target_mq_attr *target_mq_attr;
1002

    
1003
    if (!lock_user_struct(VERIFY_READ, target_mq_attr,
1004
                          target_mq_attr_addr, 1))
1005
        return -TARGET_EFAULT;
1006

    
1007
    __get_user(attr->mq_flags, &target_mq_attr->mq_flags);
1008
    __get_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
1009
    __get_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
1010
    __get_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
1011

    
1012
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0);
1013

    
1014
    return 0;
1015
}
1016

    
1017
static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr,
1018
                                            const struct mq_attr *attr)
1019
{
1020
    struct target_mq_attr *target_mq_attr;
1021

    
1022
    if (!lock_user_struct(VERIFY_WRITE, target_mq_attr,
1023
                          target_mq_attr_addr, 0))
1024
        return -TARGET_EFAULT;
1025

    
1026
    __put_user(attr->mq_flags, &target_mq_attr->mq_flags);
1027
    __put_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
1028
    __put_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
1029
    __put_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
1030

    
1031
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1);
1032

    
1033
    return 0;
1034
}
1035
#endif
1036

    
1037
#if defined(TARGET_NR_select) || defined(TARGET_NR__newselect)
1038
/* do_select() must return target values and target errnos. */
1039
static abi_long do_select(int n,
1040
                          abi_ulong rfd_addr, abi_ulong wfd_addr,
1041
                          abi_ulong efd_addr, abi_ulong target_tv_addr)
1042
{
1043
    fd_set rfds, wfds, efds;
1044
    fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
1045
    struct timeval tv, *tv_ptr;
1046
    abi_long ret;
1047

    
1048
    ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
1049
    if (ret) {
1050
        return ret;
1051
    }
1052
    ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
1053
    if (ret) {
1054
        return ret;
1055
    }
1056
    ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
1057
    if (ret) {
1058
        return ret;
1059
    }
1060

    
1061
    if (target_tv_addr) {
1062
        if (copy_from_user_timeval(&tv, target_tv_addr))
1063
            return -TARGET_EFAULT;
1064
        tv_ptr = &tv;
1065
    } else {
1066
        tv_ptr = NULL;
1067
    }
1068

    
1069
    ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
1070

    
1071
    if (!is_error(ret)) {
1072
        if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
1073
            return -TARGET_EFAULT;
1074
        if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
1075
            return -TARGET_EFAULT;
1076
        if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
1077
            return -TARGET_EFAULT;
1078

    
1079
        if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
1080
            return -TARGET_EFAULT;
1081
    }
1082

    
1083
    return ret;
1084
}
1085
#endif
1086

    
1087
static abi_long do_pipe2(int host_pipe[], int flags)
1088
{
1089
#ifdef CONFIG_PIPE2
1090
    return pipe2(host_pipe, flags);
1091
#else
1092
    return -ENOSYS;
1093
#endif
1094
}
1095

    
1096
static abi_long do_pipe(void *cpu_env, abi_ulong pipedes,
1097
                        int flags, int is_pipe2)
1098
{
1099
    int host_pipe[2];
1100
    abi_long ret;
1101
    ret = flags ? do_pipe2(host_pipe, flags) : pipe(host_pipe);
1102

    
1103
    if (is_error(ret))
1104
        return get_errno(ret);
1105

    
1106
    /* Several targets have special calling conventions for the original
1107
       pipe syscall, but didn't replicate this into the pipe2 syscall.  */
1108
    if (!is_pipe2) {
1109
#if defined(TARGET_ALPHA)
1110
        ((CPUAlphaState *)cpu_env)->ir[IR_A4] = host_pipe[1];
1111
        return host_pipe[0];
1112
#elif defined(TARGET_MIPS)
1113
        ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1];
1114
        return host_pipe[0];
1115
#elif defined(TARGET_SH4)
1116
        ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
1117
        return host_pipe[0];
1118
#endif
1119
    }
1120

    
1121
    if (put_user_s32(host_pipe[0], pipedes)
1122
        || put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0])))
1123
        return -TARGET_EFAULT;
1124
    return get_errno(ret);
1125
}
1126

    
1127
static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn,
1128
                                              abi_ulong target_addr,
1129
                                              socklen_t len)
1130
{
1131
    struct target_ip_mreqn *target_smreqn;
1132

    
1133
    target_smreqn = lock_user(VERIFY_READ, target_addr, len, 1);
1134
    if (!target_smreqn)
1135
        return -TARGET_EFAULT;
1136
    mreqn->imr_multiaddr.s_addr = target_smreqn->imr_multiaddr.s_addr;
1137
    mreqn->imr_address.s_addr = target_smreqn->imr_address.s_addr;
1138
    if (len == sizeof(struct target_ip_mreqn))
1139
        mreqn->imr_ifindex = tswapl(target_smreqn->imr_ifindex);
1140
    unlock_user(target_smreqn, target_addr, 0);
1141

    
1142
    return 0;
1143
}
1144

    
1145
static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
1146
                                               abi_ulong target_addr,
1147
                                               socklen_t len)
1148
{
1149
    const socklen_t unix_maxlen = sizeof (struct sockaddr_un);
1150
    sa_family_t sa_family;
1151
    struct target_sockaddr *target_saddr;
1152

    
1153
    target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
1154
    if (!target_saddr)
1155
        return -TARGET_EFAULT;
1156

    
1157
    sa_family = tswap16(target_saddr->sa_family);
1158

    
1159
    /* Oops. The caller might send a incomplete sun_path; sun_path
1160
     * must be terminated by \0 (see the manual page), but
1161
     * unfortunately it is quite common to specify sockaddr_un
1162
     * length as "strlen(x->sun_path)" while it should be
1163
     * "strlen(...) + 1". We'll fix that here if needed.
1164
     * Linux kernel has a similar feature.
1165
     */
1166

    
1167
    if (sa_family == AF_UNIX) {
1168
        if (len < unix_maxlen && len > 0) {
1169
            char *cp = (char*)target_saddr;
1170

    
1171
            if ( cp[len-1] && !cp[len] )
1172
                len++;
1173
        }
1174
        if (len > unix_maxlen)
1175
            len = unix_maxlen;
1176
    }
1177

    
1178
    memcpy(addr, target_saddr, len);
1179
    addr->sa_family = sa_family;
1180
    unlock_user(target_saddr, target_addr, 0);
1181

    
1182
    return 0;
1183
}
1184

    
1185
static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
1186
                                               struct sockaddr *addr,
1187
                                               socklen_t len)
1188
{
1189
    struct target_sockaddr *target_saddr;
1190

    
1191
    target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
1192
    if (!target_saddr)
1193
        return -TARGET_EFAULT;
1194
    memcpy(target_saddr, addr, len);
1195
    target_saddr->sa_family = tswap16(addr->sa_family);
1196
    unlock_user(target_saddr, target_addr, len);
1197

    
1198
    return 0;
1199
}
1200

    
1201
/* ??? Should this also swap msgh->name?  */
1202
static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
1203
                                           struct target_msghdr *target_msgh)
1204
{
1205
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1206
    abi_long msg_controllen;
1207
    abi_ulong target_cmsg_addr;
1208
    struct target_cmsghdr *target_cmsg;
1209
    socklen_t space = 0;
1210
    
1211
    msg_controllen = tswapl(target_msgh->msg_controllen);
1212
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1213
        goto the_end;
1214
    target_cmsg_addr = tswapl(target_msgh->msg_control);
1215
    target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
1216
    if (!target_cmsg)
1217
        return -TARGET_EFAULT;
1218

    
1219
    while (cmsg && target_cmsg) {
1220
        void *data = CMSG_DATA(cmsg);
1221
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
1222

    
1223
        int len = tswapl(target_cmsg->cmsg_len)
1224
                  - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
1225

    
1226
        space += CMSG_SPACE(len);
1227
        if (space > msgh->msg_controllen) {
1228
            space -= CMSG_SPACE(len);
1229
            gemu_log("Host cmsg overflow\n");
1230
            break;
1231
        }
1232

    
1233
        cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
1234
        cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
1235
        cmsg->cmsg_len = CMSG_LEN(len);
1236

    
1237
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1238
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1239
            memcpy(data, target_data, len);
1240
        } else {
1241
            int *fd = (int *)data;
1242
            int *target_fd = (int *)target_data;
1243
            int i, numfds = len / sizeof(int);
1244

    
1245
            for (i = 0; i < numfds; i++)
1246
                fd[i] = tswap32(target_fd[i]);
1247
        }
1248

    
1249
        cmsg = CMSG_NXTHDR(msgh, cmsg);
1250
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1251
    }
1252
    unlock_user(target_cmsg, target_cmsg_addr, 0);
1253
 the_end:
1254
    msgh->msg_controllen = space;
1255
    return 0;
1256
}
1257

    
1258
/* ??? Should this also swap msgh->name?  */
1259
static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
1260
                                           struct msghdr *msgh)
1261
{
1262
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1263
    abi_long msg_controllen;
1264
    abi_ulong target_cmsg_addr;
1265
    struct target_cmsghdr *target_cmsg;
1266
    socklen_t space = 0;
1267

    
1268
    msg_controllen = tswapl(target_msgh->msg_controllen);
1269
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1270
        goto the_end;
1271
    target_cmsg_addr = tswapl(target_msgh->msg_control);
1272
    target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
1273
    if (!target_cmsg)
1274
        return -TARGET_EFAULT;
1275

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

    
1280
        int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
1281

    
1282
        space += TARGET_CMSG_SPACE(len);
1283
        if (space > msg_controllen) {
1284
            space -= TARGET_CMSG_SPACE(len);
1285
            gemu_log("Target cmsg overflow\n");
1286
            break;
1287
        }
1288

    
1289
        target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
1290
        target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
1291
        target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
1292

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

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

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

    
1314
/* do_setsockopt() Must return target values and target errnos. */
1315
static abi_long do_setsockopt(int sockfd, int level, int optname,
1316
                              abi_ulong optval_addr, socklen_t optlen)
1317
{
1318
    abi_long ret;
1319
    int val;
1320
    struct ip_mreqn *ip_mreq;
1321
    struct ip_mreq_source *ip_mreq_source;
1322

    
1323
    switch(level) {
1324
    case SOL_TCP:
1325
        /* TCP options all take an 'int' value.  */
1326
        if (optlen < sizeof(uint32_t))
1327
            return -TARGET_EINVAL;
1328

    
1329
        if (get_user_u32(val, optval_addr))
1330
            return -TARGET_EFAULT;
1331
        ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1332
        break;
1333
    case SOL_IP:
1334
        switch(optname) {
1335
        case IP_TOS:
1336
        case IP_TTL:
1337
        case IP_HDRINCL:
1338
        case IP_ROUTER_ALERT:
1339
        case IP_RECVOPTS:
1340
        case IP_RETOPTS:
1341
        case IP_PKTINFO:
1342
        case IP_MTU_DISCOVER:
1343
        case IP_RECVERR:
1344
        case IP_RECVTOS:
1345
#ifdef IP_FREEBIND
1346
        case IP_FREEBIND:
1347
#endif
1348
        case IP_MULTICAST_TTL:
1349
        case IP_MULTICAST_LOOP:
1350
            val = 0;
1351
            if (optlen >= sizeof(uint32_t)) {
1352
                if (get_user_u32(val, optval_addr))
1353
                    return -TARGET_EFAULT;
1354
            } else if (optlen >= 1) {
1355
                if (get_user_u8(val, optval_addr))
1356
                    return -TARGET_EFAULT;
1357
            }
1358
            ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1359
            break;
1360
        case IP_ADD_MEMBERSHIP:
1361
        case IP_DROP_MEMBERSHIP:
1362
            if (optlen < sizeof (struct target_ip_mreq) ||
1363
                optlen > sizeof (struct target_ip_mreqn))
1364
                return -TARGET_EINVAL;
1365

    
1366
            ip_mreq = (struct ip_mreqn *) alloca(optlen);
1367
            target_to_host_ip_mreq(ip_mreq, optval_addr, optlen);
1368
            ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq, optlen));
1369
            break;
1370

    
1371
        case IP_BLOCK_SOURCE:
1372
        case IP_UNBLOCK_SOURCE:
1373
        case IP_ADD_SOURCE_MEMBERSHIP:
1374
        case IP_DROP_SOURCE_MEMBERSHIP:
1375
            if (optlen != sizeof (struct target_ip_mreq_source))
1376
                return -TARGET_EINVAL;
1377

    
1378
            ip_mreq_source = lock_user(VERIFY_READ, optval_addr, optlen, 1);
1379
            ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq_source, optlen));
1380
            unlock_user (ip_mreq_source, optval_addr, 0);
1381
            break;
1382

    
1383
        default:
1384
            goto unimplemented;
1385
        }
1386
        break;
1387
    case TARGET_SOL_SOCKET:
1388
        switch (optname) {
1389
            /* Options with 'int' argument.  */
1390
        case TARGET_SO_DEBUG:
1391
                optname = SO_DEBUG;
1392
                break;
1393
        case TARGET_SO_REUSEADDR:
1394
                optname = SO_REUSEADDR;
1395
                break;
1396
        case TARGET_SO_TYPE:
1397
                optname = SO_TYPE;
1398
                break;
1399
        case TARGET_SO_ERROR:
1400
                optname = SO_ERROR;
1401
                break;
1402
        case TARGET_SO_DONTROUTE:
1403
                optname = SO_DONTROUTE;
1404
                break;
1405
        case TARGET_SO_BROADCAST:
1406
                optname = SO_BROADCAST;
1407
                break;
1408
        case TARGET_SO_SNDBUF:
1409
                optname = SO_SNDBUF;
1410
                break;
1411
        case TARGET_SO_RCVBUF:
1412
                optname = SO_RCVBUF;
1413
                break;
1414
        case TARGET_SO_KEEPALIVE:
1415
                optname = SO_KEEPALIVE;
1416
                break;
1417
        case TARGET_SO_OOBINLINE:
1418
                optname = SO_OOBINLINE;
1419
                break;
1420
        case TARGET_SO_NO_CHECK:
1421
                optname = SO_NO_CHECK;
1422
                break;
1423
        case TARGET_SO_PRIORITY:
1424
                optname = SO_PRIORITY;
1425
                break;
1426
#ifdef SO_BSDCOMPAT
1427
        case TARGET_SO_BSDCOMPAT:
1428
                optname = SO_BSDCOMPAT;
1429
                break;
1430
#endif
1431
        case TARGET_SO_PASSCRED:
1432
                optname = SO_PASSCRED;
1433
                break;
1434
        case TARGET_SO_TIMESTAMP:
1435
                optname = SO_TIMESTAMP;
1436
                break;
1437
        case TARGET_SO_RCVLOWAT:
1438
                optname = SO_RCVLOWAT;
1439
                break;
1440
        case TARGET_SO_RCVTIMEO:
1441
                optname = SO_RCVTIMEO;
1442
                break;
1443
        case TARGET_SO_SNDTIMEO:
1444
                optname = SO_SNDTIMEO;
1445
                break;
1446
            break;
1447
        default:
1448
            goto unimplemented;
1449
        }
1450
        if (optlen < sizeof(uint32_t))
1451
            return -TARGET_EINVAL;
1452

    
1453
        if (get_user_u32(val, optval_addr))
1454
            return -TARGET_EFAULT;
1455
        ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
1456
        break;
1457
    default:
1458
    unimplemented:
1459
        gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
1460
        ret = -TARGET_ENOPROTOOPT;
1461
    }
1462
    return ret;
1463
}
1464

    
1465
/* do_getsockopt() Must return target values and target errnos. */
1466
static abi_long do_getsockopt(int sockfd, int level, int optname,
1467
                              abi_ulong optval_addr, abi_ulong optlen)
1468
{
1469
    abi_long ret;
1470
    int len, val;
1471
    socklen_t lv;
1472

    
1473
    switch(level) {
1474
    case TARGET_SOL_SOCKET:
1475
        level = SOL_SOCKET;
1476
        switch (optname) {
1477
        /* These don't just return a single integer */
1478
        case TARGET_SO_LINGER:
1479
        case TARGET_SO_RCVTIMEO:
1480
        case TARGET_SO_SNDTIMEO:
1481
        case TARGET_SO_PEERCRED:
1482
        case TARGET_SO_PEERNAME:
1483
            goto unimplemented;
1484
        /* Options with 'int' argument.  */
1485
        case TARGET_SO_DEBUG:
1486
            optname = SO_DEBUG;
1487
            goto int_case;
1488
        case TARGET_SO_REUSEADDR:
1489
            optname = SO_REUSEADDR;
1490
            goto int_case;
1491
        case TARGET_SO_TYPE:
1492
            optname = SO_TYPE;
1493
            goto int_case;
1494
        case TARGET_SO_ERROR:
1495
            optname = SO_ERROR;
1496
            goto int_case;
1497
        case TARGET_SO_DONTROUTE:
1498
            optname = SO_DONTROUTE;
1499
            goto int_case;
1500
        case TARGET_SO_BROADCAST:
1501
            optname = SO_BROADCAST;
1502
            goto int_case;
1503
        case TARGET_SO_SNDBUF:
1504
            optname = SO_SNDBUF;
1505
            goto int_case;
1506
        case TARGET_SO_RCVBUF:
1507
            optname = SO_RCVBUF;
1508
            goto int_case;
1509
        case TARGET_SO_KEEPALIVE:
1510
            optname = SO_KEEPALIVE;
1511
            goto int_case;
1512
        case TARGET_SO_OOBINLINE:
1513
            optname = SO_OOBINLINE;
1514
            goto int_case;
1515
        case TARGET_SO_NO_CHECK:
1516
            optname = SO_NO_CHECK;
1517
            goto int_case;
1518
        case TARGET_SO_PRIORITY:
1519
            optname = SO_PRIORITY;
1520
            goto int_case;
1521
#ifdef SO_BSDCOMPAT
1522
        case TARGET_SO_BSDCOMPAT:
1523
            optname = SO_BSDCOMPAT;
1524
            goto int_case;
1525
#endif
1526
        case TARGET_SO_PASSCRED:
1527
            optname = SO_PASSCRED;
1528
            goto int_case;
1529
        case TARGET_SO_TIMESTAMP:
1530
            optname = SO_TIMESTAMP;
1531
            goto int_case;
1532
        case TARGET_SO_RCVLOWAT:
1533
            optname = SO_RCVLOWAT;
1534
            goto int_case;
1535
        default:
1536
            goto int_case;
1537
        }
1538
        break;
1539
    case SOL_TCP:
1540
        /* TCP options all take an 'int' value.  */
1541
    int_case:
1542
        if (get_user_u32(len, optlen))
1543
            return -TARGET_EFAULT;
1544
        if (len < 0)
1545
            return -TARGET_EINVAL;
1546
        lv = sizeof(lv);
1547
        ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1548
        if (ret < 0)
1549
            return ret;
1550
        if (len > lv)
1551
            len = lv;
1552
        if (len == 4) {
1553
            if (put_user_u32(val, optval_addr))
1554
                return -TARGET_EFAULT;
1555
        } else {
1556
            if (put_user_u8(val, optval_addr))
1557
                return -TARGET_EFAULT;
1558
        }
1559
        if (put_user_u32(len, optlen))
1560
            return -TARGET_EFAULT;
1561
        break;
1562
    case SOL_IP:
1563
        switch(optname) {
1564
        case IP_TOS:
1565
        case IP_TTL:
1566
        case IP_HDRINCL:
1567
        case IP_ROUTER_ALERT:
1568
        case IP_RECVOPTS:
1569
        case IP_RETOPTS:
1570
        case IP_PKTINFO:
1571
        case IP_MTU_DISCOVER:
1572
        case IP_RECVERR:
1573
        case IP_RECVTOS:
1574
#ifdef IP_FREEBIND
1575
        case IP_FREEBIND:
1576
#endif
1577
        case IP_MULTICAST_TTL:
1578
        case IP_MULTICAST_LOOP:
1579
            if (get_user_u32(len, optlen))
1580
                return -TARGET_EFAULT;
1581
            if (len < 0)
1582
                return -TARGET_EINVAL;
1583
            lv = sizeof(lv);
1584
            ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1585
            if (ret < 0)
1586
                return ret;
1587
            if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
1588
                len = 1;
1589
                if (put_user_u32(len, optlen)
1590
                    || put_user_u8(val, optval_addr))
1591
                    return -TARGET_EFAULT;
1592
            } else {
1593
                if (len > sizeof(int))
1594
                    len = sizeof(int);
1595
                if (put_user_u32(len, optlen)
1596
                    || put_user_u32(val, optval_addr))
1597
                    return -TARGET_EFAULT;
1598
            }
1599
            break;
1600
        default:
1601
            ret = -TARGET_ENOPROTOOPT;
1602
            break;
1603
        }
1604
        break;
1605
    default:
1606
    unimplemented:
1607
        gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1608
                 level, optname);
1609
        ret = -TARGET_EOPNOTSUPP;
1610
        break;
1611
    }
1612
    return ret;
1613
}
1614

    
1615
/* FIXME
1616
 * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1617
 * other lock functions have a return code of 0 for failure.
1618
 */
1619
static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1620
                           int count, int copy)
1621
{
1622
    struct target_iovec *target_vec;
1623
    abi_ulong base;
1624
    int i;
1625

    
1626
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1627
    if (!target_vec)
1628
        return -TARGET_EFAULT;
1629
    for(i = 0;i < count; i++) {
1630
        base = tswapl(target_vec[i].iov_base);
1631
        vec[i].iov_len = tswapl(target_vec[i].iov_len);
1632
        if (vec[i].iov_len != 0) {
1633
            vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
1634
            /* Don't check lock_user return value. We must call writev even
1635
               if a element has invalid base address. */
1636
        } else {
1637
            /* zero length pointer is ignored */
1638
            vec[i].iov_base = NULL;
1639
        }
1640
    }
1641
    unlock_user (target_vec, target_addr, 0);
1642
    return 0;
1643
}
1644

    
1645
static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1646
                             int count, int copy)
1647
{
1648
    struct target_iovec *target_vec;
1649
    abi_ulong base;
1650
    int i;
1651

    
1652
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1653
    if (!target_vec)
1654
        return -TARGET_EFAULT;
1655
    for(i = 0;i < count; i++) {
1656
        if (target_vec[i].iov_base) {
1657
            base = tswapl(target_vec[i].iov_base);
1658
            unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1659
        }
1660
    }
1661
    unlock_user (target_vec, target_addr, 0);
1662

    
1663
    return 0;
1664
}
1665

    
1666
/* do_socket() Must return target values and target errnos. */
1667
static abi_long do_socket(int domain, int type, int protocol)
1668
{
1669
#if defined(TARGET_MIPS)
1670
    switch(type) {
1671
    case TARGET_SOCK_DGRAM:
1672
        type = SOCK_DGRAM;
1673
        break;
1674
    case TARGET_SOCK_STREAM:
1675
        type = SOCK_STREAM;
1676
        break;
1677
    case TARGET_SOCK_RAW:
1678
        type = SOCK_RAW;
1679
        break;
1680
    case TARGET_SOCK_RDM:
1681
        type = SOCK_RDM;
1682
        break;
1683
    case TARGET_SOCK_SEQPACKET:
1684
        type = SOCK_SEQPACKET;
1685
        break;
1686
    case TARGET_SOCK_PACKET:
1687
        type = SOCK_PACKET;
1688
        break;
1689
    }
1690
#endif
1691
    if (domain == PF_NETLINK)
1692
        return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1693
    return get_errno(socket(domain, type, protocol));
1694
}
1695

    
1696
/* do_bind() Must return target values and target errnos. */
1697
static abi_long do_bind(int sockfd, abi_ulong target_addr,
1698
                        socklen_t addrlen)
1699
{
1700
    void *addr;
1701
    abi_long ret;
1702

    
1703
    if ((int)addrlen < 0) {
1704
        return -TARGET_EINVAL;
1705
    }
1706

    
1707
    addr = alloca(addrlen+1);
1708

    
1709
    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1710
    if (ret)
1711
        return ret;
1712

    
1713
    return get_errno(bind(sockfd, addr, addrlen));
1714
}
1715

    
1716
/* do_connect() Must return target values and target errnos. */
1717
static abi_long do_connect(int sockfd, abi_ulong target_addr,
1718
                           socklen_t addrlen)
1719
{
1720
    void *addr;
1721
    abi_long ret;
1722

    
1723
    if ((int)addrlen < 0) {
1724
        return -TARGET_EINVAL;
1725
    }
1726

    
1727
    addr = alloca(addrlen);
1728

    
1729
    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1730
    if (ret)
1731
        return ret;
1732

    
1733
    return get_errno(connect(sockfd, addr, addrlen));
1734
}
1735

    
1736
/* do_sendrecvmsg() Must return target values and target errnos. */
1737
static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1738
                               int flags, int send)
1739
{
1740
    abi_long ret, len;
1741
    struct target_msghdr *msgp;
1742
    struct msghdr msg;
1743
    int count;
1744
    struct iovec *vec;
1745
    abi_ulong target_vec;
1746

    
1747
    /* FIXME */
1748
    if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1749
                          msgp,
1750
                          target_msg,
1751
                          send ? 1 : 0))
1752
        return -TARGET_EFAULT;
1753
    if (msgp->msg_name) {
1754
        msg.msg_namelen = tswap32(msgp->msg_namelen);
1755
        msg.msg_name = alloca(msg.msg_namelen);
1756
        ret = target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
1757
                                msg.msg_namelen);
1758
        if (ret) {
1759
            unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1760
            return ret;
1761
        }
1762
    } else {
1763
        msg.msg_name = NULL;
1764
        msg.msg_namelen = 0;
1765
    }
1766
    msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
1767
    msg.msg_control = alloca(msg.msg_controllen);
1768
    msg.msg_flags = tswap32(msgp->msg_flags);
1769

    
1770
    count = tswapl(msgp->msg_iovlen);
1771
    vec = alloca(count * sizeof(struct iovec));
1772
    target_vec = tswapl(msgp->msg_iov);
1773
    lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1774
    msg.msg_iovlen = count;
1775
    msg.msg_iov = vec;
1776

    
1777
    if (send) {
1778
        ret = target_to_host_cmsg(&msg, msgp);
1779
        if (ret == 0)
1780
            ret = get_errno(sendmsg(fd, &msg, flags));
1781
    } else {
1782
        ret = get_errno(recvmsg(fd, &msg, flags));
1783
        if (!is_error(ret)) {
1784
            len = ret;
1785
            ret = host_to_target_cmsg(msgp, &msg);
1786
            if (!is_error(ret))
1787
                ret = len;
1788
        }
1789
    }
1790
    unlock_iovec(vec, target_vec, count, !send);
1791
    unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1792
    return ret;
1793
}
1794

    
1795
/* do_accept() Must return target values and target errnos. */
1796
static abi_long do_accept(int fd, abi_ulong target_addr,
1797
                          abi_ulong target_addrlen_addr)
1798
{
1799
    socklen_t addrlen;
1800
    void *addr;
1801
    abi_long ret;
1802

    
1803
    if (target_addr == 0)
1804
       return get_errno(accept(fd, NULL, NULL));
1805

    
1806
    /* linux returns EINVAL if addrlen pointer is invalid */
1807
    if (get_user_u32(addrlen, target_addrlen_addr))
1808
        return -TARGET_EINVAL;
1809

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

    
1814
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1815
        return -TARGET_EINVAL;
1816

    
1817
    addr = alloca(addrlen);
1818

    
1819
    ret = get_errno(accept(fd, addr, &addrlen));
1820
    if (!is_error(ret)) {
1821
        host_to_target_sockaddr(target_addr, addr, addrlen);
1822
        if (put_user_u32(addrlen, target_addrlen_addr))
1823
            ret = -TARGET_EFAULT;
1824
    }
1825
    return ret;
1826
}
1827

    
1828
/* do_getpeername() Must return target values and target errnos. */
1829
static abi_long do_getpeername(int fd, abi_ulong target_addr,
1830
                               abi_ulong target_addrlen_addr)
1831
{
1832
    socklen_t addrlen;
1833
    void *addr;
1834
    abi_long ret;
1835

    
1836
    if (get_user_u32(addrlen, target_addrlen_addr))
1837
        return -TARGET_EFAULT;
1838

    
1839
    if ((int)addrlen < 0) {
1840
        return -TARGET_EINVAL;
1841
    }
1842

    
1843
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1844
        return -TARGET_EFAULT;
1845

    
1846
    addr = alloca(addrlen);
1847

    
1848
    ret = get_errno(getpeername(fd, addr, &addrlen));
1849
    if (!is_error(ret)) {
1850
        host_to_target_sockaddr(target_addr, addr, addrlen);
1851
        if (put_user_u32(addrlen, target_addrlen_addr))
1852
            ret = -TARGET_EFAULT;
1853
    }
1854
    return ret;
1855
}
1856

    
1857
/* do_getsockname() Must return target values and target errnos. */
1858
static abi_long do_getsockname(int fd, abi_ulong target_addr,
1859
                               abi_ulong target_addrlen_addr)
1860
{
1861
    socklen_t addrlen;
1862
    void *addr;
1863
    abi_long ret;
1864

    
1865
    if (get_user_u32(addrlen, target_addrlen_addr))
1866
        return -TARGET_EFAULT;
1867

    
1868
    if ((int)addrlen < 0) {
1869
        return -TARGET_EINVAL;
1870
    }
1871

    
1872
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1873
        return -TARGET_EFAULT;
1874

    
1875
    addr = alloca(addrlen);
1876

    
1877
    ret = get_errno(getsockname(fd, addr, &addrlen));
1878
    if (!is_error(ret)) {
1879
        host_to_target_sockaddr(target_addr, addr, addrlen);
1880
        if (put_user_u32(addrlen, target_addrlen_addr))
1881
            ret = -TARGET_EFAULT;
1882
    }
1883
    return ret;
1884
}
1885

    
1886
/* do_socketpair() Must return target values and target errnos. */
1887
static abi_long do_socketpair(int domain, int type, int protocol,
1888
                              abi_ulong target_tab_addr)
1889
{
1890
    int tab[2];
1891
    abi_long ret;
1892

    
1893
    ret = get_errno(socketpair(domain, type, protocol, tab));
1894
    if (!is_error(ret)) {
1895
        if (put_user_s32(tab[0], target_tab_addr)
1896
            || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1897
            ret = -TARGET_EFAULT;
1898
    }
1899
    return ret;
1900
}
1901

    
1902
/* do_sendto() Must return target values and target errnos. */
1903
static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
1904
                          abi_ulong target_addr, socklen_t addrlen)
1905
{
1906
    void *addr;
1907
    void *host_msg;
1908
    abi_long ret;
1909

    
1910
    if ((int)addrlen < 0) {
1911
        return -TARGET_EINVAL;
1912
    }
1913

    
1914
    host_msg = lock_user(VERIFY_READ, msg, len, 1);
1915
    if (!host_msg)
1916
        return -TARGET_EFAULT;
1917
    if (target_addr) {
1918
        addr = alloca(addrlen);
1919
        ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1920
        if (ret) {
1921
            unlock_user(host_msg, msg, 0);
1922
            return ret;
1923
        }
1924
        ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
1925
    } else {
1926
        ret = get_errno(send(fd, host_msg, len, flags));
1927
    }
1928
    unlock_user(host_msg, msg, 0);
1929
    return ret;
1930
}
1931

    
1932
/* do_recvfrom() Must return target values and target errnos. */
1933
static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
1934
                            abi_ulong target_addr,
1935
                            abi_ulong target_addrlen)
1936
{
1937
    socklen_t addrlen;
1938
    void *addr;
1939
    void *host_msg;
1940
    abi_long ret;
1941

    
1942
    host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
1943
    if (!host_msg)
1944
        return -TARGET_EFAULT;
1945
    if (target_addr) {
1946
        if (get_user_u32(addrlen, target_addrlen)) {
1947
            ret = -TARGET_EFAULT;
1948
            goto fail;
1949
        }
1950
        if ((int)addrlen < 0) {
1951
            ret = -TARGET_EINVAL;
1952
            goto fail;
1953
        }
1954
        addr = alloca(addrlen);
1955
        ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
1956
    } else {
1957
        addr = NULL; /* To keep compiler quiet.  */
1958
        ret = get_errno(recv(fd, host_msg, len, flags));
1959
    }
1960
    if (!is_error(ret)) {
1961
        if (target_addr) {
1962
            host_to_target_sockaddr(target_addr, addr, addrlen);
1963
            if (put_user_u32(addrlen, target_addrlen)) {
1964
                ret = -TARGET_EFAULT;
1965
                goto fail;
1966
            }
1967
        }
1968
        unlock_user(host_msg, msg, len);
1969
    } else {
1970
fail:
1971
        unlock_user(host_msg, msg, 0);
1972
    }
1973
    return ret;
1974
}
1975

    
1976
#ifdef TARGET_NR_socketcall
1977
/* do_socketcall() Must return target values and target errnos. */
1978
static abi_long do_socketcall(int num, abi_ulong vptr)
1979
{
1980
    abi_long ret;
1981
    const int n = sizeof(abi_ulong);
1982

    
1983
    switch(num) {
1984
    case SOCKOP_socket:
1985
        {
1986
            abi_ulong domain, type, protocol;
1987

    
1988
            if (get_user_ual(domain, vptr)
1989
                || get_user_ual(type, vptr + n)
1990
                || get_user_ual(protocol, vptr + 2 * n))
1991
                return -TARGET_EFAULT;
1992

    
1993
            ret = do_socket(domain, type, protocol);
1994
        }
1995
        break;
1996
    case SOCKOP_bind:
1997
        {
1998
            abi_ulong sockfd;
1999
            abi_ulong target_addr;
2000
            socklen_t addrlen;
2001

    
2002
            if (get_user_ual(sockfd, vptr)
2003
                || get_user_ual(target_addr, vptr + n)
2004
                || get_user_ual(addrlen, vptr + 2 * n))
2005
                return -TARGET_EFAULT;
2006

    
2007
            ret = do_bind(sockfd, target_addr, addrlen);
2008
        }
2009
        break;
2010
    case SOCKOP_connect:
2011
        {
2012
            abi_ulong sockfd;
2013
            abi_ulong target_addr;
2014
            socklen_t addrlen;
2015

    
2016
            if (get_user_ual(sockfd, vptr)
2017
                || get_user_ual(target_addr, vptr + n)
2018
                || get_user_ual(addrlen, vptr + 2 * n))
2019
                return -TARGET_EFAULT;
2020

    
2021
            ret = do_connect(sockfd, target_addr, addrlen);
2022
        }
2023
        break;
2024
    case SOCKOP_listen:
2025
        {
2026
            abi_ulong sockfd, backlog;
2027

    
2028
            if (get_user_ual(sockfd, vptr)
2029
                || get_user_ual(backlog, vptr + n))
2030
                return -TARGET_EFAULT;
2031

    
2032
            ret = get_errno(listen(sockfd, backlog));
2033
        }
2034
        break;
2035
    case SOCKOP_accept:
2036
        {
2037
            abi_ulong sockfd;
2038
            abi_ulong target_addr, target_addrlen;
2039

    
2040
            if (get_user_ual(sockfd, vptr)
2041
                || get_user_ual(target_addr, vptr + n)
2042
                || get_user_ual(target_addrlen, vptr + 2 * n))
2043
                return -TARGET_EFAULT;
2044

    
2045
            ret = do_accept(sockfd, target_addr, target_addrlen);
2046
        }
2047
        break;
2048
    case SOCKOP_getsockname:
2049
        {
2050
            abi_ulong sockfd;
2051
            abi_ulong target_addr, target_addrlen;
2052

    
2053
            if (get_user_ual(sockfd, vptr)
2054
                || get_user_ual(target_addr, vptr + n)
2055
                || get_user_ual(target_addrlen, vptr + 2 * n))
2056
                return -TARGET_EFAULT;
2057

    
2058
            ret = do_getsockname(sockfd, target_addr, target_addrlen);
2059
        }
2060
        break;
2061
    case SOCKOP_getpeername:
2062
        {
2063
            abi_ulong sockfd;
2064
            abi_ulong target_addr, target_addrlen;
2065

    
2066
            if (get_user_ual(sockfd, vptr)
2067
                || get_user_ual(target_addr, vptr + n)
2068
                || get_user_ual(target_addrlen, vptr + 2 * n))
2069
                return -TARGET_EFAULT;
2070

    
2071
            ret = do_getpeername(sockfd, target_addr, target_addrlen);
2072
        }
2073
        break;
2074
    case SOCKOP_socketpair:
2075
        {
2076
            abi_ulong domain, type, protocol;
2077
            abi_ulong tab;
2078

    
2079
            if (get_user_ual(domain, vptr)
2080
                || get_user_ual(type, vptr + n)
2081
                || get_user_ual(protocol, vptr + 2 * n)
2082
                || get_user_ual(tab, vptr + 3 * n))
2083
                return -TARGET_EFAULT;
2084

    
2085
            ret = do_socketpair(domain, type, protocol, tab);
2086
        }
2087
        break;
2088
    case SOCKOP_send:
2089
        {
2090
            abi_ulong sockfd;
2091
            abi_ulong msg;
2092
            size_t len;
2093
            abi_ulong flags;
2094

    
2095
            if (get_user_ual(sockfd, vptr)
2096
                || get_user_ual(msg, vptr + n)
2097
                || get_user_ual(len, vptr + 2 * n)
2098
                || get_user_ual(flags, vptr + 3 * n))
2099
                return -TARGET_EFAULT;
2100

    
2101
            ret = do_sendto(sockfd, msg, len, flags, 0, 0);
2102
        }
2103
        break;
2104
    case SOCKOP_recv:
2105
        {
2106
            abi_ulong sockfd;
2107
            abi_ulong msg;
2108
            size_t len;
2109
            abi_ulong flags;
2110

    
2111
            if (get_user_ual(sockfd, vptr)
2112
                || get_user_ual(msg, vptr + n)
2113
                || get_user_ual(len, vptr + 2 * n)
2114
                || get_user_ual(flags, vptr + 3 * n))
2115
                return -TARGET_EFAULT;
2116

    
2117
            ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
2118
        }
2119
        break;
2120
    case SOCKOP_sendto:
2121
        {
2122
            abi_ulong sockfd;
2123
            abi_ulong msg;
2124
            size_t len;
2125
            abi_ulong flags;
2126
            abi_ulong addr;
2127
            socklen_t addrlen;
2128

    
2129
            if (get_user_ual(sockfd, vptr)
2130
                || get_user_ual(msg, vptr + n)
2131
                || get_user_ual(len, vptr + 2 * n)
2132
                || get_user_ual(flags, vptr + 3 * n)
2133
                || get_user_ual(addr, vptr + 4 * n)
2134
                || get_user_ual(addrlen, vptr + 5 * n))
2135
                return -TARGET_EFAULT;
2136

    
2137
            ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
2138
        }
2139
        break;
2140
    case SOCKOP_recvfrom:
2141
        {
2142
            abi_ulong sockfd;
2143
            abi_ulong msg;
2144
            size_t len;
2145
            abi_ulong flags;
2146
            abi_ulong addr;
2147
            socklen_t addrlen;
2148

    
2149
            if (get_user_ual(sockfd, vptr)
2150
                || get_user_ual(msg, vptr + n)
2151
                || get_user_ual(len, vptr + 2 * n)
2152
                || get_user_ual(flags, vptr + 3 * n)
2153
                || get_user_ual(addr, vptr + 4 * n)
2154
                || get_user_ual(addrlen, vptr + 5 * n))
2155
                return -TARGET_EFAULT;
2156

    
2157
            ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
2158
        }
2159
        break;
2160
    case SOCKOP_shutdown:
2161
        {
2162
            abi_ulong sockfd, how;
2163

    
2164
            if (get_user_ual(sockfd, vptr)
2165
                || get_user_ual(how, vptr + n))
2166
                return -TARGET_EFAULT;
2167

    
2168
            ret = get_errno(shutdown(sockfd, how));
2169
        }
2170
        break;
2171
    case SOCKOP_sendmsg:
2172
    case SOCKOP_recvmsg:
2173
        {
2174
            abi_ulong fd;
2175
            abi_ulong target_msg;
2176
            abi_ulong flags;
2177

    
2178
            if (get_user_ual(fd, vptr)
2179
                || get_user_ual(target_msg, vptr + n)
2180
                || get_user_ual(flags, vptr + 2 * n))
2181
                return -TARGET_EFAULT;
2182

    
2183
            ret = do_sendrecvmsg(fd, target_msg, flags,
2184
                                 (num == SOCKOP_sendmsg));
2185
        }
2186
        break;
2187
    case SOCKOP_setsockopt:
2188
        {
2189
            abi_ulong sockfd;
2190
            abi_ulong level;
2191
            abi_ulong optname;
2192
            abi_ulong optval;
2193
            socklen_t optlen;
2194

    
2195
            if (get_user_ual(sockfd, vptr)
2196
                || get_user_ual(level, vptr + n)
2197
                || get_user_ual(optname, vptr + 2 * n)
2198
                || get_user_ual(optval, vptr + 3 * n)
2199
                || get_user_ual(optlen, vptr + 4 * n))
2200
                return -TARGET_EFAULT;
2201

    
2202
            ret = do_setsockopt(sockfd, level, optname, optval, optlen);
2203
        }
2204
        break;
2205
    case SOCKOP_getsockopt:
2206
        {
2207
            abi_ulong sockfd;
2208
            abi_ulong level;
2209
            abi_ulong optname;
2210
            abi_ulong optval;
2211
            socklen_t optlen;
2212

    
2213
            if (get_user_ual(sockfd, vptr)
2214
                || get_user_ual(level, vptr + n)
2215
                || get_user_ual(optname, vptr + 2 * n)
2216
                || get_user_ual(optval, vptr + 3 * n)
2217
                || get_user_ual(optlen, vptr + 4 * n))
2218
                return -TARGET_EFAULT;
2219

    
2220
            ret = do_getsockopt(sockfd, level, optname, optval, optlen);
2221
        }
2222
        break;
2223
    default:
2224
        gemu_log("Unsupported socketcall: %d\n", num);
2225
        ret = -TARGET_ENOSYS;
2226
        break;
2227
    }
2228
    return ret;
2229
}
2230
#endif
2231

    
2232
#define N_SHM_REGIONS        32
2233

    
2234
static struct shm_region {
2235
    abi_ulong        start;
2236
    abi_ulong        size;
2237
} shm_regions[N_SHM_REGIONS];
2238

    
2239
struct target_ipc_perm
2240
{
2241
    abi_long __key;
2242
    abi_ulong uid;
2243
    abi_ulong gid;
2244
    abi_ulong cuid;
2245
    abi_ulong cgid;
2246
    unsigned short int mode;
2247
    unsigned short int __pad1;
2248
    unsigned short int __seq;
2249
    unsigned short int __pad2;
2250
    abi_ulong __unused1;
2251
    abi_ulong __unused2;
2252
};
2253

    
2254
struct target_semid_ds
2255
{
2256
  struct target_ipc_perm sem_perm;
2257
  abi_ulong sem_otime;
2258
  abi_ulong __unused1;
2259
  abi_ulong sem_ctime;
2260
  abi_ulong __unused2;
2261
  abi_ulong sem_nsems;
2262
  abi_ulong __unused3;
2263
  abi_ulong __unused4;
2264
};
2265

    
2266
static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
2267
                                               abi_ulong target_addr)
2268
{
2269
    struct target_ipc_perm *target_ip;
2270
    struct target_semid_ds *target_sd;
2271

    
2272
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2273
        return -TARGET_EFAULT;
2274
    target_ip = &(target_sd->sem_perm);
2275
    host_ip->__key = tswapl(target_ip->__key);
2276
    host_ip->uid = tswapl(target_ip->uid);
2277
    host_ip->gid = tswapl(target_ip->gid);
2278
    host_ip->cuid = tswapl(target_ip->cuid);
2279
    host_ip->cgid = tswapl(target_ip->cgid);
2280
    host_ip->mode = tswapl(target_ip->mode);
2281
    unlock_user_struct(target_sd, target_addr, 0);
2282
    return 0;
2283
}
2284

    
2285
static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
2286
                                               struct ipc_perm *host_ip)
2287
{
2288
    struct target_ipc_perm *target_ip;
2289
    struct target_semid_ds *target_sd;
2290

    
2291
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2292
        return -TARGET_EFAULT;
2293
    target_ip = &(target_sd->sem_perm);
2294
    target_ip->__key = tswapl(host_ip->__key);
2295
    target_ip->uid = tswapl(host_ip->uid);
2296
    target_ip->gid = tswapl(host_ip->gid);
2297
    target_ip->cuid = tswapl(host_ip->cuid);
2298
    target_ip->cgid = tswapl(host_ip->cgid);
2299
    target_ip->mode = tswapl(host_ip->mode);
2300
    unlock_user_struct(target_sd, target_addr, 1);
2301
    return 0;
2302
}
2303

    
2304
static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
2305
                                               abi_ulong target_addr)
2306
{
2307
    struct target_semid_ds *target_sd;
2308

    
2309
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2310
        return -TARGET_EFAULT;
2311
    if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr))
2312
        return -TARGET_EFAULT;
2313
    host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
2314
    host_sd->sem_otime = tswapl(target_sd->sem_otime);
2315
    host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
2316
    unlock_user_struct(target_sd, target_addr, 0);
2317
    return 0;
2318
}
2319

    
2320
static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
2321
                                               struct semid_ds *host_sd)
2322
{
2323
    struct target_semid_ds *target_sd;
2324

    
2325
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2326
        return -TARGET_EFAULT;
2327
    if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
2328
        return -TARGET_EFAULT;;
2329
    target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
2330
    target_sd->sem_otime = tswapl(host_sd->sem_otime);
2331
    target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
2332
    unlock_user_struct(target_sd, target_addr, 1);
2333
    return 0;
2334
}
2335

    
2336
struct target_seminfo {
2337
    int semmap;
2338
    int semmni;
2339
    int semmns;
2340
    int semmnu;
2341
    int semmsl;
2342
    int semopm;
2343
    int semume;
2344
    int semusz;
2345
    int semvmx;
2346
    int semaem;
2347
};
2348

    
2349
static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
2350
                                              struct seminfo *host_seminfo)
2351
{
2352
    struct target_seminfo *target_seminfo;
2353
    if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
2354
        return -TARGET_EFAULT;
2355
    __put_user(host_seminfo->semmap, &target_seminfo->semmap);
2356
    __put_user(host_seminfo->semmni, &target_seminfo->semmni);
2357
    __put_user(host_seminfo->semmns, &target_seminfo->semmns);
2358
    __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
2359
    __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
2360
    __put_user(host_seminfo->semopm, &target_seminfo->semopm);
2361
    __put_user(host_seminfo->semume, &target_seminfo->semume);
2362
    __put_user(host_seminfo->semusz, &target_seminfo->semusz);
2363
    __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
2364
    __put_user(host_seminfo->semaem, &target_seminfo->semaem);
2365
    unlock_user_struct(target_seminfo, target_addr, 1);
2366
    return 0;
2367
}
2368

    
2369
union semun {
2370
        int val;
2371
        struct semid_ds *buf;
2372
        unsigned short *array;
2373
        struct seminfo *__buf;
2374
};
2375

    
2376
union target_semun {
2377
        int val;
2378
        abi_ulong buf;
2379
        abi_ulong array;
2380
        abi_ulong __buf;
2381
};
2382

    
2383
static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
2384
                                               abi_ulong target_addr)
2385
{
2386
    int nsems;
2387
    unsigned short *array;
2388
    union semun semun;
2389
    struct semid_ds semid_ds;
2390
    int i, ret;
2391

    
2392
    semun.buf = &semid_ds;
2393

    
2394
    ret = semctl(semid, 0, IPC_STAT, semun);
2395
    if (ret == -1)
2396
        return get_errno(ret);
2397

    
2398
    nsems = semid_ds.sem_nsems;
2399

    
2400
    *host_array = malloc(nsems*sizeof(unsigned short));
2401
    array = lock_user(VERIFY_READ, target_addr,
2402
                      nsems*sizeof(unsigned short), 1);
2403
    if (!array)
2404
        return -TARGET_EFAULT;
2405

    
2406
    for(i=0; i<nsems; i++) {
2407
        __get_user((*host_array)[i], &array[i]);
2408
    }
2409
    unlock_user(array, target_addr, 0);
2410

    
2411
    return 0;
2412
}
2413

    
2414
static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
2415
                                               unsigned short **host_array)
2416
{
2417
    int nsems;
2418
    unsigned short *array;
2419
    union semun semun;
2420
    struct semid_ds semid_ds;
2421
    int i, ret;
2422

    
2423
    semun.buf = &semid_ds;
2424

    
2425
    ret = semctl(semid, 0, IPC_STAT, semun);
2426
    if (ret == -1)
2427
        return get_errno(ret);
2428

    
2429
    nsems = semid_ds.sem_nsems;
2430

    
2431
    array = lock_user(VERIFY_WRITE, target_addr,
2432
                      nsems*sizeof(unsigned short), 0);
2433
    if (!array)
2434
        return -TARGET_EFAULT;
2435

    
2436
    for(i=0; i<nsems; i++) {
2437
        __put_user((*host_array)[i], &array[i]);
2438
    }
2439
    free(*host_array);
2440
    unlock_user(array, target_addr, 1);
2441

    
2442
    return 0;
2443
}
2444

    
2445
static inline abi_long do_semctl(int semid, int semnum, int cmd,
2446
                                 union target_semun target_su)
2447
{
2448
    union semun arg;
2449
    struct semid_ds dsarg;
2450
    unsigned short *array = NULL;
2451
    struct seminfo seminfo;
2452
    abi_long ret = -TARGET_EINVAL;
2453
    abi_long err;
2454
    cmd &= 0xff;
2455

    
2456
    switch( cmd ) {
2457
        case GETVAL:
2458
        case SETVAL:
2459
            arg.val = tswapl(target_su.val);
2460
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2461
            target_su.val = tswapl(arg.val);
2462
            break;
2463
        case GETALL:
2464
        case SETALL:
2465
            err = target_to_host_semarray(semid, &array, target_su.array);
2466
            if (err)
2467
                return err;
2468
            arg.array = array;
2469
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2470
            err = host_to_target_semarray(semid, target_su.array, &array);
2471
            if (err)
2472
                return err;
2473
            break;
2474
        case IPC_STAT:
2475
        case IPC_SET:
2476
        case SEM_STAT:
2477
            err = target_to_host_semid_ds(&dsarg, target_su.buf);
2478
            if (err)
2479
                return err;
2480
            arg.buf = &dsarg;
2481
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2482
            err = host_to_target_semid_ds(target_su.buf, &dsarg);
2483
            if (err)
2484
                return err;
2485
            break;
2486
        case IPC_INFO:
2487
        case SEM_INFO:
2488
            arg.__buf = &seminfo;
2489
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2490
            err = host_to_target_seminfo(target_su.__buf, &seminfo);
2491
            if (err)
2492
                return err;
2493
            break;
2494
        case IPC_RMID:
2495
        case GETPID:
2496
        case GETNCNT:
2497
        case GETZCNT:
2498
            ret = get_errno(semctl(semid, semnum, cmd, NULL));
2499
            break;
2500
    }
2501

    
2502
    return ret;
2503
}
2504

    
2505
struct target_sembuf {
2506
    unsigned short sem_num;
2507
    short sem_op;
2508
    short sem_flg;
2509
};
2510

    
2511
static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
2512
                                             abi_ulong target_addr,
2513
                                             unsigned nsops)
2514
{
2515
    struct target_sembuf *target_sembuf;
2516
    int i;
2517

    
2518
    target_sembuf = lock_user(VERIFY_READ, target_addr,
2519
                              nsops*sizeof(struct target_sembuf), 1);
2520
    if (!target_sembuf)
2521
        return -TARGET_EFAULT;
2522

    
2523
    for(i=0; i<nsops; i++) {
2524
        __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
2525
        __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
2526
        __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
2527
    }
2528

    
2529
    unlock_user(target_sembuf, target_addr, 0);
2530

    
2531
    return 0;
2532
}
2533

    
2534
static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
2535
{
2536
    struct sembuf sops[nsops];
2537

    
2538
    if (target_to_host_sembuf(sops, ptr, nsops))
2539
        return -TARGET_EFAULT;
2540

    
2541
    return semop(semid, sops, nsops);
2542
}
2543

    
2544
struct target_msqid_ds
2545
{
2546
    struct target_ipc_perm msg_perm;
2547
    abi_ulong msg_stime;
2548
#if TARGET_ABI_BITS == 32
2549
    abi_ulong __unused1;
2550
#endif
2551
    abi_ulong msg_rtime;
2552
#if TARGET_ABI_BITS == 32
2553
    abi_ulong __unused2;
2554
#endif
2555
    abi_ulong msg_ctime;
2556
#if TARGET_ABI_BITS == 32
2557
    abi_ulong __unused3;
2558
#endif
2559
    abi_ulong __msg_cbytes;
2560
    abi_ulong msg_qnum;
2561
    abi_ulong msg_qbytes;
2562
    abi_ulong msg_lspid;
2563
    abi_ulong msg_lrpid;
2564
    abi_ulong __unused4;
2565
    abi_ulong __unused5;
2566
};
2567

    
2568
static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
2569
                                               abi_ulong target_addr)
2570
{
2571
    struct target_msqid_ds *target_md;
2572

    
2573
    if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
2574
        return -TARGET_EFAULT;
2575
    if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
2576
        return -TARGET_EFAULT;
2577
    host_md->msg_stime = tswapl(target_md->msg_stime);
2578
    host_md->msg_rtime = tswapl(target_md->msg_rtime);
2579
    host_md->msg_ctime = tswapl(target_md->msg_ctime);
2580
    host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
2581
    host_md->msg_qnum = tswapl(target_md->msg_qnum);
2582
    host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
2583
    host_md->msg_lspid = tswapl(target_md->msg_lspid);
2584
    host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
2585
    unlock_user_struct(target_md, target_addr, 0);
2586
    return 0;
2587
}
2588

    
2589
static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
2590
                                               struct msqid_ds *host_md)
2591
{
2592
    struct target_msqid_ds *target_md;
2593

    
2594
    if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
2595
        return -TARGET_EFAULT;
2596
    if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
2597
        return -TARGET_EFAULT;
2598
    target_md->msg_stime = tswapl(host_md->msg_stime);
2599
    target_md->msg_rtime = tswapl(host_md->msg_rtime);
2600
    target_md->msg_ctime = tswapl(host_md->msg_ctime);
2601
    target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
2602
    target_md->msg_qnum = tswapl(host_md->msg_qnum);
2603
    target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
2604
    target_md->msg_lspid = tswapl(host_md->msg_lspid);
2605
    target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
2606
    unlock_user_struct(target_md, target_addr, 1);
2607
    return 0;
2608
}
2609

    
2610
struct target_msginfo {
2611
    int msgpool;
2612
    int msgmap;
2613
    int msgmax;
2614
    int msgmnb;
2615
    int msgmni;
2616
    int msgssz;
2617
    int msgtql;
2618
    unsigned short int msgseg;
2619
};
2620

    
2621
static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
2622
                                              struct msginfo *host_msginfo)
2623
{
2624
    struct target_msginfo *target_msginfo;
2625
    if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
2626
        return -TARGET_EFAULT;
2627
    __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
2628
    __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
2629
    __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
2630
    __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
2631
    __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
2632
    __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
2633
    __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
2634
    __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
2635
    unlock_user_struct(target_msginfo, target_addr, 1);
2636
    return 0;
2637
}
2638

    
2639
static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
2640
{
2641
    struct msqid_ds dsarg;
2642
    struct msginfo msginfo;
2643
    abi_long ret = -TARGET_EINVAL;
2644

    
2645
    cmd &= 0xff;
2646

    
2647
    switch (cmd) {
2648
    case IPC_STAT:
2649
    case IPC_SET:
2650
    case MSG_STAT:
2651
        if (target_to_host_msqid_ds(&dsarg,ptr))
2652
            return -TARGET_EFAULT;
2653
        ret = get_errno(msgctl(msgid, cmd, &dsarg));
2654
        if (host_to_target_msqid_ds(ptr,&dsarg))
2655
            return -TARGET_EFAULT;
2656
        break;
2657
    case IPC_RMID:
2658
        ret = get_errno(msgctl(msgid, cmd, NULL));
2659
        break;
2660
    case IPC_INFO:
2661
    case MSG_INFO:
2662
        ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
2663
        if (host_to_target_msginfo(ptr, &msginfo))
2664
            return -TARGET_EFAULT;
2665
        break;
2666
    }
2667

    
2668
    return ret;
2669
}
2670

    
2671
struct target_msgbuf {
2672
    abi_long mtype;
2673
    char        mtext[1];
2674
};
2675

    
2676
static inline abi_long do_msgsnd(int msqid, abi_long msgp,
2677
                                 unsigned int msgsz, int msgflg)
2678
{
2679
    struct target_msgbuf *target_mb;
2680
    struct msgbuf *host_mb;
2681
    abi_long ret = 0;
2682

    
2683
    if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
2684
        return -TARGET_EFAULT;
2685
    host_mb = malloc(msgsz+sizeof(long));
2686
    host_mb->mtype = (abi_long) tswapl(target_mb->mtype);
2687
    memcpy(host_mb->mtext, target_mb->mtext, msgsz);
2688
    ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
2689
    free(host_mb);
2690
    unlock_user_struct(target_mb, msgp, 0);
2691

    
2692
    return ret;
2693
}
2694

    
2695
static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2696
                                 unsigned int msgsz, abi_long msgtyp,
2697
                                 int msgflg)
2698
{
2699
    struct target_msgbuf *target_mb;
2700
    char *target_mtext;
2701
    struct msgbuf *host_mb;
2702
    abi_long ret = 0;
2703

    
2704
    if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2705
        return -TARGET_EFAULT;
2706

    
2707
    host_mb = malloc(msgsz+sizeof(long));
2708
    ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapl(msgtyp), msgflg));
2709

    
2710
    if (ret > 0) {
2711
        abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2712
        target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2713
        if (!target_mtext) {
2714
            ret = -TARGET_EFAULT;
2715
            goto end;
2716
        }
2717
        memcpy(target_mb->mtext, host_mb->mtext, ret);
2718
        unlock_user(target_mtext, target_mtext_addr, ret);
2719
    }
2720

    
2721
    target_mb->mtype = tswapl(host_mb->mtype);
2722
    free(host_mb);
2723

    
2724
end:
2725
    if (target_mb)
2726
        unlock_user_struct(target_mb, msgp, 1);
2727
    return ret;
2728
}
2729

    
2730
struct target_shmid_ds
2731
{
2732
    struct target_ipc_perm shm_perm;
2733
    abi_ulong shm_segsz;
2734
    abi_ulong shm_atime;
2735
#if TARGET_ABI_BITS == 32
2736
    abi_ulong __unused1;
2737
#endif
2738
    abi_ulong shm_dtime;
2739
#if TARGET_ABI_BITS == 32
2740
    abi_ulong __unused2;
2741
#endif
2742
    abi_ulong shm_ctime;
2743
#if TARGET_ABI_BITS == 32
2744
    abi_ulong __unused3;
2745
#endif
2746
    int shm_cpid;
2747
    int shm_lpid;
2748
    abi_ulong shm_nattch;
2749
    unsigned long int __unused4;
2750
    unsigned long int __unused5;
2751
};
2752

    
2753
static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
2754
                                               abi_ulong target_addr)
2755
{
2756
    struct target_shmid_ds *target_sd;
2757

    
2758
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2759
        return -TARGET_EFAULT;
2760
    if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr))
2761
        return -TARGET_EFAULT;
2762
    __get_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2763
    __get_user(host_sd->shm_atime, &target_sd->shm_atime);
2764
    __get_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2765
    __get_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2766
    __get_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2767
    __get_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2768
    __get_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2769
    unlock_user_struct(target_sd, target_addr, 0);
2770
    return 0;
2771
}
2772

    
2773
static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
2774
                                               struct shmid_ds *host_sd)
2775
{
2776
    struct target_shmid_ds *target_sd;
2777

    
2778
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2779
        return -TARGET_EFAULT;
2780
    if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm)))
2781
        return -TARGET_EFAULT;
2782
    __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2783
    __put_user(host_sd->shm_atime, &target_sd->shm_atime);
2784
    __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2785
    __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2786
    __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2787
    __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2788
    __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2789
    unlock_user_struct(target_sd, target_addr, 1);
2790
    return 0;
2791
}
2792

    
2793
struct  target_shminfo {
2794
    abi_ulong shmmax;
2795
    abi_ulong shmmin;
2796
    abi_ulong shmmni;
2797
    abi_ulong shmseg;
2798
    abi_ulong shmall;
2799
};
2800

    
2801
static inline abi_long host_to_target_shminfo(abi_ulong target_addr,
2802
                                              struct shminfo *host_shminfo)
2803
{
2804
    struct target_shminfo *target_shminfo;
2805
    if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0))
2806
        return -TARGET_EFAULT;
2807
    __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
2808
    __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
2809
    __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
2810
    __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
2811
    __put_user(host_shminfo->shmall, &target_shminfo->shmall);
2812
    unlock_user_struct(target_shminfo, target_addr, 1);
2813
    return 0;
2814
}
2815

    
2816
struct target_shm_info {
2817
    int used_ids;
2818
    abi_ulong shm_tot;
2819
    abi_ulong shm_rss;
2820
    abi_ulong shm_swp;
2821
    abi_ulong swap_attempts;
2822
    abi_ulong swap_successes;
2823
};
2824

    
2825
static inline abi_long host_to_target_shm_info(abi_ulong target_addr,
2826
                                               struct shm_info *host_shm_info)
2827
{
2828
    struct target_shm_info *target_shm_info;
2829
    if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0))
2830
        return -TARGET_EFAULT;
2831
    __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
2832
    __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
2833
    __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
2834
    __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
2835
    __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts);
2836
    __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes);
2837
    unlock_user_struct(target_shm_info, target_addr, 1);
2838
    return 0;
2839
}
2840

    
2841
static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
2842
{
2843
    struct shmid_ds dsarg;
2844
    struct shminfo shminfo;
2845
    struct shm_info shm_info;
2846
    abi_long ret = -TARGET_EINVAL;
2847

    
2848
    cmd &= 0xff;
2849

    
2850
    switch(cmd) {
2851
    case IPC_STAT:
2852
    case IPC_SET:
2853
    case SHM_STAT:
2854
        if (target_to_host_shmid_ds(&dsarg, buf))
2855
            return -TARGET_EFAULT;
2856
        ret = get_errno(shmctl(shmid, cmd, &dsarg));
2857
        if (host_to_target_shmid_ds(buf, &dsarg))
2858
            return -TARGET_EFAULT;
2859
        break;
2860
    case IPC_INFO:
2861
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
2862
        if (host_to_target_shminfo(buf, &shminfo))
2863
            return -TARGET_EFAULT;
2864
        break;
2865
    case SHM_INFO:
2866
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
2867
        if (host_to_target_shm_info(buf, &shm_info))
2868
            return -TARGET_EFAULT;
2869
        break;
2870
    case IPC_RMID:
2871
    case SHM_LOCK:
2872
    case SHM_UNLOCK:
2873
        ret = get_errno(shmctl(shmid, cmd, NULL));
2874
        break;
2875
    }
2876

    
2877
    return ret;
2878
}
2879

    
2880
static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
2881
{
2882
    abi_long raddr;
2883
    void *host_raddr;
2884
    struct shmid_ds shm_info;
2885
    int i,ret;
2886

    
2887
    /* find out the length of the shared memory segment */
2888
    ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
2889
    if (is_error(ret)) {
2890
        /* can't get length, bail out */
2891
        return ret;
2892
    }
2893

    
2894
    mmap_lock();
2895

    
2896
    if (shmaddr)
2897
        host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
2898
    else {
2899
        abi_ulong mmap_start;
2900

    
2901
        mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
2902

    
2903
        if (mmap_start == -1) {
2904
            errno = ENOMEM;
2905
            host_raddr = (void *)-1;
2906
        } else
2907
            host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);
2908
    }
2909

    
2910
    if (host_raddr == (void *)-1) {
2911
        mmap_unlock();
2912
        return get_errno((long)host_raddr);
2913
    }
2914
    raddr=h2g((unsigned long)host_raddr);
2915

    
2916
    page_set_flags(raddr, raddr + shm_info.shm_segsz,
2917
                   PAGE_VALID | PAGE_READ |
2918
                   ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
2919

    
2920
    for (i = 0; i < N_SHM_REGIONS; i++) {
2921
        if (shm_regions[i].start == 0) {
2922
            shm_regions[i].start = raddr;
2923
            shm_regions[i].size = shm_info.shm_segsz;
2924
            break;
2925
        }
2926
    }
2927

    
2928
    mmap_unlock();
2929
    return raddr;
2930

    
2931
}
2932

    
2933
static inline abi_long do_shmdt(abi_ulong shmaddr)
2934
{
2935
    int i;
2936

    
2937
    for (i = 0; i < N_SHM_REGIONS; ++i) {
2938
        if (shm_regions[i].start == shmaddr) {
2939
            shm_regions[i].start = 0;
2940
            page_set_flags(shmaddr, shmaddr + shm_regions[i].size, 0);
2941
            break;
2942
        }
2943
    }
2944

    
2945
    return get_errno(shmdt(g2h(shmaddr)));
2946
}
2947

    
2948
#ifdef TARGET_NR_ipc
2949
/* ??? This only works with linear mappings.  */
2950
/* do_ipc() must return target values and target errnos. */
2951
static abi_long do_ipc(unsigned int call, int first,
2952
                       int second, int third,
2953
                       abi_long ptr, abi_long fifth)
2954
{
2955
    int version;
2956
    abi_long ret = 0;
2957

    
2958
    version = call >> 16;
2959
    call &= 0xffff;
2960

    
2961
    switch (call) {
2962
    case IPCOP_semop:
2963
        ret = do_semop(first, ptr, second);
2964
        break;
2965

    
2966
    case IPCOP_semget:
2967
        ret = get_errno(semget(first, second, third));
2968
        break;
2969

    
2970
    case IPCOP_semctl:
2971
        ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr);
2972
        break;
2973

    
2974
    case IPCOP_msgget:
2975
        ret = get_errno(msgget(first, second));
2976
        break;
2977

    
2978
    case IPCOP_msgsnd:
2979
        ret = do_msgsnd(first, ptr, second, third);
2980
        break;
2981

    
2982
    case IPCOP_msgctl:
2983
        ret = do_msgctl(first, second, ptr);
2984
        break;
2985

    
2986
    case IPCOP_msgrcv:
2987
        switch (version) {
2988
        case 0:
2989
            {
2990
                struct target_ipc_kludge {
2991
                    abi_long msgp;
2992
                    abi_long msgtyp;
2993
                } *tmp;
2994

    
2995
                if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
2996
                    ret = -TARGET_EFAULT;
2997
                    break;
2998
                }
2999

    
3000
                ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
3001

    
3002
                unlock_user_struct(tmp, ptr, 0);
3003
                break;
3004
            }
3005
        default:
3006
            ret = do_msgrcv(first, ptr, second, fifth, third);
3007
        }
3008
        break;
3009

    
3010
    case IPCOP_shmat:
3011
        switch (version) {
3012
        default:
3013
        {
3014
            abi_ulong raddr;
3015
            raddr = do_shmat(first, ptr, second);
3016
            if (is_error(raddr))
3017
                return get_errno(raddr);
3018
            if (put_user_ual(raddr, third))
3019
                return -TARGET_EFAULT;
3020
            break;
3021
        }
3022
        case 1:
3023
            ret = -TARGET_EINVAL;
3024
            break;
3025
        }
3026
        break;
3027
    case IPCOP_shmdt:
3028
        ret = do_shmdt(ptr);
3029
        break;
3030

    
3031
    case IPCOP_shmget:
3032
        /* IPC_* flag values are the same on all linux platforms */
3033
        ret = get_errno(shmget(first, second, third));
3034
        break;
3035

    
3036
        /* IPC_* and SHM_* command values are the same on all linux platforms */
3037
    case IPCOP_shmctl:
3038
        ret = do_shmctl(first, second, third);
3039
        break;
3040
    default:
3041
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
3042
        ret = -TARGET_ENOSYS;
3043
        break;
3044
    }
3045
    return ret;
3046
}
3047
#endif
3048

    
3049
/* kernel structure types definitions */
3050

    
3051
#define STRUCT(name, ...) STRUCT_ ## name,
3052
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
3053
enum {
3054
#include "syscall_types.h"
3055
};
3056
#undef STRUCT
3057
#undef STRUCT_SPECIAL
3058

    
3059
#define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = {  __VA_ARGS__, TYPE_NULL };
3060
#define STRUCT_SPECIAL(name)
3061
#include "syscall_types.h"
3062
#undef STRUCT
3063
#undef STRUCT_SPECIAL
3064

    
3065
typedef struct IOCTLEntry IOCTLEntry;
3066

    
3067
typedef abi_long do_ioctl_fn(const IOCTLEntry *ie, uint8_t *buf_temp,
3068
                             int fd, abi_long cmd, abi_long arg);
3069

    
3070
struct IOCTLEntry {
3071
    unsigned int target_cmd;
3072
    unsigned int host_cmd;
3073
    const char *name;
3074
    int access;
3075
    do_ioctl_fn *do_ioctl;
3076
    const argtype arg_type[5];
3077
};
3078

    
3079
#define IOC_R 0x0001
3080
#define IOC_W 0x0002
3081
#define IOC_RW (IOC_R | IOC_W)
3082

    
3083
#define MAX_STRUCT_SIZE 4096
3084

    
3085
#ifdef CONFIG_FIEMAP
3086
/* So fiemap access checks don't overflow on 32 bit systems.
3087
 * This is very slightly smaller than the limit imposed by
3088
 * the underlying kernel.
3089
 */
3090
#define FIEMAP_MAX_EXTENTS ((UINT_MAX - sizeof(struct fiemap))  \
3091
                            / sizeof(struct fiemap_extent))
3092

    
3093
static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp,
3094
                                       int fd, abi_long cmd, abi_long arg)
3095
{
3096
    /* The parameter for this ioctl is a struct fiemap followed
3097
     * by an array of struct fiemap_extent whose size is set
3098
     * in fiemap->fm_extent_count. The array is filled in by the
3099
     * ioctl.
3100
     */
3101
    int target_size_in, target_size_out;
3102
    struct fiemap *fm;
3103
    const argtype *arg_type = ie->arg_type;
3104
    const argtype extent_arg_type[] = { MK_STRUCT(STRUCT_fiemap_extent) };
3105
    void *argptr, *p;
3106
    abi_long ret;
3107
    int i, extent_size = thunk_type_size(extent_arg_type, 0);
3108
    uint32_t outbufsz;
3109
    int free_fm = 0;
3110

    
3111
    assert(arg_type[0] == TYPE_PTR);
3112
    assert(ie->access == IOC_RW);
3113
    arg_type++;
3114
    target_size_in = thunk_type_size(arg_type, 0);
3115
    argptr = lock_user(VERIFY_READ, arg, target_size_in, 1);
3116
    if (!argptr) {
3117
        return -TARGET_EFAULT;
3118
    }
3119
    thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3120
    unlock_user(argptr, arg, 0);
3121
    fm = (struct fiemap *)buf_temp;
3122
    if (fm->fm_extent_count > FIEMAP_MAX_EXTENTS) {
3123
        return -TARGET_EINVAL;
3124
    }
3125

    
3126
    outbufsz = sizeof (*fm) +
3127
        (sizeof(struct fiemap_extent) * fm->fm_extent_count);
3128

    
3129
    if (outbufsz > MAX_STRUCT_SIZE) {
3130
        /* We can't fit all the extents into the fixed size buffer.
3131
         * Allocate one that is large enough and use it instead.
3132
         */
3133
        fm = malloc(outbufsz);
3134
        if (!fm) {
3135
            return -TARGET_ENOMEM;
3136
        }
3137
        memcpy(fm, buf_temp, sizeof(struct fiemap));
3138
        free_fm = 1;
3139
    }
3140
    ret = get_errno(ioctl(fd, ie->host_cmd, fm));
3141
    if (!is_error(ret)) {
3142
        target_size_out = target_size_in;
3143
        /* An extent_count of 0 means we were only counting the extents
3144
         * so there are no structs to copy
3145
         */
3146
        if (fm->fm_extent_count != 0) {
3147
            target_size_out += fm->fm_mapped_extents * extent_size;
3148
        }
3149
        argptr = lock_user(VERIFY_WRITE, arg, target_size_out, 0);
3150
        if (!argptr) {
3151
            ret = -TARGET_EFAULT;
3152
        } else {
3153
            /* Convert the struct fiemap */
3154
            thunk_convert(argptr, fm, arg_type, THUNK_TARGET);
3155
            if (fm->fm_extent_count != 0) {
3156
                p = argptr + target_size_in;
3157
                /* ...and then all the struct fiemap_extents */
3158
                for (i = 0; i < fm->fm_mapped_extents; i++) {
3159
                    thunk_convert(p, &fm->fm_extents[i], extent_arg_type,
3160
                                  THUNK_TARGET);
3161
                    p += extent_size;
3162
                }
3163
            }
3164
            unlock_user(argptr, arg, target_size_out);
3165
        }
3166
    }
3167
    if (free_fm) {
3168
        free(fm);
3169
    }
3170
    return ret;
3171
}
3172
#endif
3173

    
3174
static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp,
3175
                                int fd, abi_long cmd, abi_long arg)
3176
{
3177
    const argtype *arg_type = ie->arg_type;
3178
    int target_size;
3179
    void *argptr;
3180
    int ret;
3181
    struct ifconf *host_ifconf;
3182
    uint32_t outbufsz;
3183
    const argtype ifreq_arg_type[] = { MK_STRUCT(STRUCT_sockaddr_ifreq) };
3184
    int target_ifreq_size;
3185
    int nb_ifreq;
3186
    int free_buf = 0;
3187
    int i;
3188
    int target_ifc_len;
3189
    abi_long target_ifc_buf;
3190
    int host_ifc_len;
3191
    char *host_ifc_buf;
3192

    
3193
    assert(arg_type[0] == TYPE_PTR);
3194
    assert(ie->access == IOC_RW);
3195

    
3196
    arg_type++;
3197
    target_size = thunk_type_size(arg_type, 0);
3198

    
3199
    argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3200
    if (!argptr)
3201
        return -TARGET_EFAULT;
3202
    thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3203
    unlock_user(argptr, arg, 0);
3204

    
3205
    host_ifconf = (struct ifconf *)(unsigned long)buf_temp;
3206
    target_ifc_len = host_ifconf->ifc_len;
3207
    target_ifc_buf = (abi_long)(unsigned long)host_ifconf->ifc_buf;
3208

    
3209
    target_ifreq_size = thunk_type_size(ifreq_arg_type, 0);
3210
    nb_ifreq = target_ifc_len / target_ifreq_size;
3211
    host_ifc_len = nb_ifreq * sizeof(struct ifreq);
3212

    
3213
    outbufsz = sizeof(*host_ifconf) + host_ifc_len;
3214
    if (outbufsz > MAX_STRUCT_SIZE) {
3215
        /* We can't fit all the extents into the fixed size buffer.
3216
         * Allocate one that is large enough and use it instead.
3217
         */
3218
        host_ifconf = malloc(outbufsz);
3219
        if (!host_ifconf) {
3220
            return -TARGET_ENOMEM;
3221
        }
3222
        memcpy(host_ifconf, buf_temp, sizeof(*host_ifconf));
3223
        free_buf = 1;
3224
    }
3225
    host_ifc_buf = (char*)host_ifconf + sizeof(*host_ifconf);
3226

    
3227
    host_ifconf->ifc_len = host_ifc_len;
3228
    host_ifconf->ifc_buf = host_ifc_buf;
3229

    
3230
    ret = get_errno(ioctl(fd, ie->host_cmd, host_ifconf));
3231
    if (!is_error(ret)) {
3232
        /* convert host ifc_len to target ifc_len */
3233

    
3234
        nb_ifreq = host_ifconf->ifc_len / sizeof(struct ifreq);
3235
        target_ifc_len = nb_ifreq * target_ifreq_size;
3236
        host_ifconf->ifc_len = target_ifc_len;
3237

    
3238
        /* restore target ifc_buf */
3239

    
3240
        host_ifconf->ifc_buf = (char *)(unsigned long)target_ifc_buf;
3241

    
3242
        /* copy struct ifconf to target user */
3243

    
3244
        argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3245
        if (!argptr)
3246
            return -TARGET_EFAULT;
3247
        thunk_convert(argptr, host_ifconf, arg_type, THUNK_TARGET);
3248
        unlock_user(argptr, arg, target_size);
3249

    
3250
        /* copy ifreq[] to target user */
3251

    
3252
        argptr = lock_user(VERIFY_WRITE, target_ifc_buf, target_ifc_len, 0);
3253
        for (i = 0; i < nb_ifreq ; i++) {
3254
            thunk_convert(argptr + i * target_ifreq_size,
3255
                          host_ifc_buf + i * sizeof(struct ifreq),
3256
                          ifreq_arg_type, THUNK_TARGET);
3257
        }
3258
        unlock_user(argptr, target_ifc_buf, target_ifc_len);
3259
    }
3260

    
3261
    if (free_buf) {
3262
        free(host_ifconf);
3263
    }
3264

    
3265
    return ret;
3266
}
3267

    
3268
static IOCTLEntry ioctl_entries[] = {
3269
#define IOCTL(cmd, access, ...) \
3270
    { TARGET_ ## cmd, cmd, #cmd, access, 0, {  __VA_ARGS__ } },
3271
#define IOCTL_SPECIAL(cmd, access, dofn, ...)                      \
3272
    { TARGET_ ## cmd, cmd, #cmd, access, dofn, {  __VA_ARGS__ } },
3273
#include "ioctls.h"
3274
    { 0, 0, },
3275
};
3276

    
3277
/* ??? Implement proper locking for ioctls.  */
3278
/* do_ioctl() Must return target values and target errnos. */
3279
static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
3280
{
3281
    const IOCTLEntry *ie;
3282
    const argtype *arg_type;
3283
    abi_long ret;
3284
    uint8_t buf_temp[MAX_STRUCT_SIZE];
3285
    int target_size;
3286
    void *argptr;
3287

    
3288
    ie = ioctl_entries;
3289
    for(;;) {
3290
        if (ie->target_cmd == 0) {
3291
            gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
3292
            return -TARGET_ENOSYS;
3293
        }
3294
        if (ie->target_cmd == cmd)
3295
            break;
3296
        ie++;
3297
    }
3298
    arg_type = ie->arg_type;
3299
#if defined(DEBUG)
3300
    gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
3301
#endif
3302
    if (ie->do_ioctl) {
3303
        return ie->do_ioctl(ie, buf_temp, fd, cmd, arg);
3304
    }
3305

    
3306
    switch(arg_type[0]) {
3307
    case TYPE_NULL:
3308
        /* no argument */
3309
        ret = get_errno(ioctl(fd, ie->host_cmd));
3310
        break;
3311
    case TYPE_PTRVOID:
3312
    case TYPE_INT:
3313
        /* int argment */
3314
        ret = get_errno(ioctl(fd, ie->host_cmd, arg));
3315
        break;
3316
    case TYPE_PTR:
3317
        arg_type++;
3318
        target_size = thunk_type_size(arg_type, 0);
3319
        switch(ie->access) {
3320
        case IOC_R:
3321
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3322
            if (!is_error(ret)) {
3323
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3324
                if (!argptr)
3325
                    return -TARGET_EFAULT;
3326
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
3327
                unlock_user(argptr, arg, target_size);
3328
            }
3329
            break;
3330
        case IOC_W:
3331
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3332
            if (!argptr)
3333
                return -TARGET_EFAULT;
3334
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3335
            unlock_user(argptr, arg, 0);
3336
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3337
            break;
3338
        default:
3339
        case IOC_RW:
3340
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3341
            if (!argptr)
3342
                return -TARGET_EFAULT;
3343
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3344
            unlock_user(argptr, arg, 0);
3345
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3346
            if (!is_error(ret)) {
3347
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3348
                if (!argptr)
3349
                    return -TARGET_EFAULT;
3350
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
3351
                unlock_user(argptr, arg, target_size);
3352
            }
3353
            break;
3354
        }
3355
        break;
3356
    default:
3357
        gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
3358
                 (long)cmd, arg_type[0]);
3359
        ret = -TARGET_ENOSYS;
3360
        break;
3361
    }
3362
    return ret;
3363
}
3364

    
3365
static const bitmask_transtbl iflag_tbl[] = {
3366
        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
3367
        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
3368
        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
3369
        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
3370
        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
3371
        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
3372
        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
3373
        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
3374
        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
3375
        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
3376
        { TARGET_IXON, TARGET_IXON, IXON, IXON },
3377
        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
3378
        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
3379
        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
3380
        { 0, 0, 0, 0 }
3381
};
3382

    
3383
static const bitmask_transtbl oflag_tbl[] = {
3384
        { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
3385
        { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
3386
        { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
3387
        { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
3388
        { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
3389
        { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
3390
        { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
3391
        { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
3392
        { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
3393
        { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
3394
        { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
3395
        { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
3396
        { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
3397
        { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
3398
        { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
3399
        { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
3400
        { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
3401
        { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
3402
        { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
3403
        { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
3404
        { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
3405
        { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
3406
        { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
3407
        { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
3408
        { 0, 0, 0, 0 }
3409
};
3410

    
3411
static const bitmask_transtbl cflag_tbl[] = {
3412
        { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
3413
        { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
3414
        { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
3415
        { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
3416
        { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
3417
        { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
3418
        { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
3419
        { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
3420
        { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
3421
        { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
3422
        { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
3423
        { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
3424
        { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
3425
        { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
3426
        { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
3427
        { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
3428
        { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
3429
        { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
3430
        { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
3431
        { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
3432
        { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
3433
        { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
3434
        { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
3435
        { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
3436
        { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
3437
        { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
3438
        { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
3439
        { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
3440
        { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
3441
        { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
3442
        { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
3443
        { 0, 0, 0, 0 }
3444
};
3445

    
3446
static const bitmask_transtbl lflag_tbl[] = {
3447
        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
3448
        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
3449
        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
3450
        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
3451
        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
3452
        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
3453
        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
3454
        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
3455
        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
3456
        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
3457
        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
3458
        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
3459
        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
3460
        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
3461
        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
3462
        { 0, 0, 0, 0 }
3463
};
3464

    
3465
static void target_to_host_termios (void *dst, const void *src)
3466
{
3467
    struct host_termios *host = dst;
3468
    const struct target_termios *target = src;
3469

    
3470
    host->c_iflag =
3471
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
3472
    host->c_oflag =
3473
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
3474
    host->c_cflag =
3475
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
3476
    host->c_lflag =
3477
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
3478
    host->c_line = target->c_line;
3479

    
3480
    memset(host->c_cc, 0, sizeof(host->c_cc));
3481
    host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
3482
    host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
3483
    host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
3484
    host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
3485
    host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
3486
    host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
3487
    host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
3488
    host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
3489
    host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
3490
    host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
3491
    host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
3492
    host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
3493
    host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
3494
    host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
3495
    host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
3496
    host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
3497
    host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
3498
}
3499

    
3500
static void host_to_target_termios (void *dst, const void *src)
3501
{
3502
    struct target_termios *target = dst;
3503
    const struct host_termios *host = src;
3504

    
3505
    target->c_iflag =
3506
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
3507
    target->c_oflag =
3508
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
3509
    target->c_cflag =
3510
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
3511
    target->c_lflag =
3512
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
3513
    target->c_line = host->c_line;
3514

    
3515
    memset(target->c_cc, 0, sizeof(target->c_cc));
3516
    target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
3517
    target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
3518
    target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
3519
    target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
3520
    target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
3521
    target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
3522
    target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
3523
    target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
3524
    target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
3525
    target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
3526
    target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
3527
    target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
3528
    target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
3529
    target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
3530
    target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
3531
    target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
3532
    target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
3533
}
3534

    
3535
static const StructEntry struct_termios_def = {
3536
    .convert = { host_to_target_termios, target_to_host_termios },
3537
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
3538
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
3539
};
3540

    
3541
static bitmask_transtbl mmap_flags_tbl[] = {
3542
        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
3543
        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
3544
        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
3545
        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
3546
        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
3547
        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
3548
        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
3549
        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
3550
        { 0, 0, 0, 0 }
3551
};
3552

    
3553
#if defined(TARGET_I386)
3554

    
3555
/* NOTE: there is really one LDT for all the threads */
3556
static uint8_t *ldt_table;
3557

    
3558
static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
3559
{
3560
    int size;
3561
    void *p;
3562

    
3563
    if (!ldt_table)
3564
        return 0;
3565
    size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
3566
    if (size > bytecount)
3567
        size = bytecount;
3568
    p = lock_user(VERIFY_WRITE, ptr, size, 0);
3569
    if (!p)
3570
        return -TARGET_EFAULT;
3571
    /* ??? Should this by byteswapped?  */
3572
    memcpy(p, ldt_table, size);
3573
    unlock_user(p, ptr, size);
3574
    return size;
3575
}
3576

    
3577
/* XXX: add locking support */
3578
static abi_long write_ldt(CPUX86State *env,
3579
                          abi_ulong ptr, unsigned long bytecount, int oldmode)
3580
{
3581
    struct target_modify_ldt_ldt_s ldt_info;
3582
    struct target_modify_ldt_ldt_s *target_ldt_info;
3583
    int seg_32bit, contents, read_exec_only, limit_in_pages;
3584
    int seg_not_present, useable, lm;
3585
    uint32_t *lp, entry_1, entry_2;
3586

    
3587
    if (bytecount != sizeof(ldt_info))
3588
        return -TARGET_EINVAL;
3589
    if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
3590
        return -TARGET_EFAULT;
3591
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3592
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
3593
    ldt_info.limit = tswap32(target_ldt_info->limit);
3594
    ldt_info.flags = tswap32(target_ldt_info->flags);
3595
    unlock_user_struct(target_ldt_info, ptr, 0);
3596

    
3597
    if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
3598
        return -TARGET_EINVAL;
3599
    seg_32bit = ldt_info.flags & 1;
3600
    contents = (ldt_info.flags >> 1) & 3;
3601
    read_exec_only = (ldt_info.flags >> 3) & 1;
3602
    limit_in_pages = (ldt_info.flags >> 4) & 1;
3603
    seg_not_present = (ldt_info.flags >> 5) & 1;
3604
    useable = (ldt_info.flags >> 6) & 1;
3605
#ifdef TARGET_ABI32
3606
    lm = 0;
3607
#else
3608
    lm = (ldt_info.flags >> 7) & 1;
3609
#endif
3610
    if (contents == 3) {
3611
        if (oldmode)
3612
            return -TARGET_EINVAL;
3613
        if (seg_not_present == 0)
3614
            return -TARGET_EINVAL;
3615
    }
3616
    /* allocate the LDT */
3617
    if (!ldt_table) {
3618
        env->ldt.base = target_mmap(0,
3619
                                    TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
3620
                                    PROT_READ|PROT_WRITE,
3621
                                    MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
3622
        if (env->ldt.base == -1)
3623
            return -TARGET_ENOMEM;
3624
        memset(g2h(env->ldt.base), 0,
3625
               TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
3626
        env->ldt.limit = 0xffff;
3627
        ldt_table = g2h(env->ldt.base);
3628
    }
3629

    
3630
    /* NOTE: same code as Linux kernel */
3631
    /* Allow LDTs to be cleared by the user. */
3632
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3633
        if (oldmode ||
3634
            (contents == 0                &&
3635
             read_exec_only == 1        &&
3636
             seg_32bit == 0                &&
3637
             limit_in_pages == 0        &&
3638
             seg_not_present == 1        &&
3639
             useable == 0 )) {
3640
            entry_1 = 0;
3641
            entry_2 = 0;
3642
            goto install;
3643
        }
3644
    }
3645

    
3646
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
3647
        (ldt_info.limit & 0x0ffff);
3648
    entry_2 = (ldt_info.base_addr & 0xff000000) |
3649
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3650
        (ldt_info.limit & 0xf0000) |
3651
        ((read_exec_only ^ 1) << 9) |
3652
        (contents << 10) |
3653
        ((seg_not_present ^ 1) << 15) |
3654
        (seg_32bit << 22) |
3655
        (limit_in_pages << 23) |
3656
        (lm << 21) |
3657
        0x7000;
3658
    if (!oldmode)
3659
        entry_2 |= (useable << 20);
3660

    
3661
    /* Install the new entry ...  */
3662
install:
3663
    lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
3664
    lp[0] = tswap32(entry_1);
3665
    lp[1] = tswap32(entry_2);
3666
    return 0;
3667
}
3668

    
3669
/* specific and weird i386 syscalls */
3670
static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
3671
                              unsigned long bytecount)
3672
{
3673
    abi_long ret;
3674

    
3675
    switch (func) {
3676
    case 0:
3677
        ret = read_ldt(ptr, bytecount);
3678
        break;
3679
    case 1:
3680
        ret = write_ldt(env, ptr, bytecount, 1);
3681
        break;
3682
    case 0x11:
3683
        ret = write_ldt(env, ptr, bytecount, 0);
3684
        break;
3685
    default:
3686
        ret = -TARGET_ENOSYS;
3687
        break;
3688
    }
3689
    return ret;
3690
}
3691

    
3692
#if defined(TARGET_I386) && defined(TARGET_ABI32)
3693
static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
3694
{
3695
    uint64_t *gdt_table = g2h(env->gdt.base);
3696
    struct target_modify_ldt_ldt_s ldt_info;
3697
    struct target_modify_ldt_ldt_s *target_ldt_info;
3698
    int seg_32bit, contents, read_exec_only, limit_in_pages;
3699
    int seg_not_present, useable, lm;
3700
    uint32_t *lp, entry_1, entry_2;
3701
    int i;
3702

    
3703
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3704
    if (!target_ldt_info)
3705
        return -TARGET_EFAULT;
3706
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3707
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
3708
    ldt_info.limit = tswap32(target_ldt_info->limit);
3709
    ldt_info.flags = tswap32(target_ldt_info->flags);
3710
    if (ldt_info.entry_number == -1) {
3711
        for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
3712
            if (gdt_table[i] == 0) {
3713
                ldt_info.entry_number = i;
3714
                target_ldt_info->entry_number = tswap32(i);
3715
                break;
3716
            }
3717
        }
3718
    }
3719
    unlock_user_struct(target_ldt_info, ptr, 1);
3720

    
3721
    if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || 
3722
        ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
3723
           return -TARGET_EINVAL;
3724
    seg_32bit = ldt_info.flags & 1;
3725
    contents = (ldt_info.flags >> 1) & 3;
3726
    read_exec_only = (ldt_info.flags >> 3) & 1;
3727
    limit_in_pages = (ldt_info.flags >> 4) & 1;
3728
    seg_not_present = (ldt_info.flags >> 5) & 1;
3729
    useable = (ldt_info.flags >> 6) & 1;
3730
#ifdef TARGET_ABI32
3731
    lm = 0;
3732
#else
3733
    lm = (ldt_info.flags >> 7) & 1;
3734
#endif
3735

    
3736
    if (contents == 3) {
3737
        if (seg_not_present == 0)
3738
            return -TARGET_EINVAL;
3739
    }
3740

    
3741
    /* NOTE: same code as Linux kernel */
3742
    /* Allow LDTs to be cleared by the user. */
3743
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3744
        if ((contents == 0             &&
3745
             read_exec_only == 1       &&
3746
             seg_32bit == 0            &&
3747
             limit_in_pages == 0       &&
3748
             seg_not_present == 1      &&
3749
             useable == 0 )) {
3750
            entry_1 = 0;
3751
            entry_2 = 0;
3752
            goto install;
3753
        }
3754
    }
3755

    
3756
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
3757
        (ldt_info.limit & 0x0ffff);
3758
    entry_2 = (ldt_info.base_addr & 0xff000000) |
3759
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3760
        (ldt_info.limit & 0xf0000) |
3761
        ((read_exec_only ^ 1) << 9) |
3762
        (contents << 10) |
3763
        ((seg_not_present ^ 1) << 15) |
3764
        (seg_32bit << 22) |
3765
        (limit_in_pages << 23) |
3766
        (useable << 20) |
3767
        (lm << 21) |
3768
        0x7000;
3769

    
3770
    /* Install the new entry ...  */
3771
install:
3772
    lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
3773
    lp[0] = tswap32(entry_1);
3774
    lp[1] = tswap32(entry_2);
3775
    return 0;
3776
}
3777

    
3778
static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
3779
{
3780
    struct target_modify_ldt_ldt_s *target_ldt_info;
3781
    uint64_t *gdt_table = g2h(env->gdt.base);
3782
    uint32_t base_addr, limit, flags;
3783
    int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
3784
    int seg_not_present, useable, lm;
3785
    uint32_t *lp, entry_1, entry_2;
3786

    
3787
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3788
    if (!target_ldt_info)
3789
        return -TARGET_EFAULT;
3790
    idx = tswap32(target_ldt_info->entry_number);
3791
    if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
3792
        idx > TARGET_GDT_ENTRY_TLS_MAX) {
3793
        unlock_user_struct(target_ldt_info, ptr, 1);
3794
        return -TARGET_EINVAL;
3795
    }
3796
    lp = (uint32_t *)(gdt_table + idx);
3797
    entry_1 = tswap32(lp[0]);
3798
    entry_2 = tswap32(lp[1]);
3799
    
3800
    read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
3801
    contents = (entry_2 >> 10) & 3;
3802
    seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
3803
    seg_32bit = (entry_2 >> 22) & 1;
3804
    limit_in_pages = (entry_2 >> 23) & 1;
3805
    useable = (entry_2 >> 20) & 1;
3806
#ifdef TARGET_ABI32
3807
    lm = 0;
3808
#else
3809
    lm = (entry_2 >> 21) & 1;
3810
#endif
3811
    flags = (seg_32bit << 0) | (contents << 1) |
3812
        (read_exec_only << 3) | (limit_in_pages << 4) |
3813
        (seg_not_present << 5) | (useable << 6) | (lm << 7);
3814
    limit = (entry_1 & 0xffff) | (entry_2  & 0xf0000);
3815
    base_addr = (entry_1 >> 16) | 
3816
        (entry_2 & 0xff000000) | 
3817
        ((entry_2 & 0xff) << 16);
3818
    target_ldt_info->base_addr = tswapl(base_addr);
3819
    target_ldt_info->limit = tswap32(limit);
3820
    target_ldt_info->flags = tswap32(flags);
3821
    unlock_user_struct(target_ldt_info, ptr, 1);
3822
    return 0;
3823
}
3824
#endif /* TARGET_I386 && TARGET_ABI32 */
3825

    
3826
#ifndef TARGET_ABI32
3827
static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
3828
{
3829
    abi_long ret = 0;
3830
    abi_ulong val;
3831
    int idx;
3832

    
3833
    switch(code) {
3834
    case TARGET_ARCH_SET_GS:
3835
    case TARGET_ARCH_SET_FS:
3836
        if (code == TARGET_ARCH_SET_GS)
3837
            idx = R_GS;
3838
        else
3839
            idx = R_FS;
3840
        cpu_x86_load_seg(env, idx, 0);
3841
        env->segs[idx].base = addr;
3842
        break;
3843
    case TARGET_ARCH_GET_GS:
3844
    case TARGET_ARCH_GET_FS:
3845
        if (code == TARGET_ARCH_GET_GS)
3846
            idx = R_GS;
3847
        else
3848
            idx = R_FS;
3849
        val = env->segs[idx].base;
3850
        if (put_user(val, addr, abi_ulong))
3851
            ret = -TARGET_EFAULT;
3852
        break;
3853
    default:
3854
        ret = -TARGET_EINVAL;
3855
        break;
3856
    }
3857
    return ret;
3858
}
3859
#endif
3860

    
3861
#endif /* defined(TARGET_I386) */
3862

    
3863
#define NEW_STACK_SIZE 0x40000
3864

    
3865
#if defined(CONFIG_USE_NPTL)
3866

    
3867
static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
3868
typedef struct {
3869
    CPUState *env;
3870
    pthread_mutex_t mutex;
3871
    pthread_cond_t cond;
3872
    pthread_t thread;
3873
    uint32_t tid;
3874
    abi_ulong child_tidptr;
3875
    abi_ulong parent_tidptr;
3876
    sigset_t sigmask;
3877
} new_thread_info;
3878

    
3879
static void *clone_func(void *arg)
3880
{
3881
    new_thread_info *info = arg;
3882
    CPUState *env;
3883
    TaskState *ts;
3884

    
3885
    env = info->env;
3886
    thread_env = env;
3887
    ts = (TaskState *)thread_env->opaque;
3888
    info->tid = gettid();
3889
    env->host_tid = info->tid;
3890
    task_settid(ts);
3891
    if (info->child_tidptr)
3892
        put_user_u32(info->tid, info->child_tidptr);
3893
    if (info->parent_tidptr)
3894
        put_user_u32(info->tid, info->parent_tidptr);
3895
    /* Enable signals.  */
3896
    sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
3897
    /* Signal to the parent that we're ready.  */
3898
    pthread_mutex_lock(&info->mutex);
3899
    pthread_cond_broadcast(&info->cond);
3900
    pthread_mutex_unlock(&info->mutex);
3901
    /* Wait until the parent has finshed initializing the tls state.  */
3902
    pthread_mutex_lock(&clone_lock);
3903
    pthread_mutex_unlock(&clone_lock);
3904
    cpu_loop(env);
3905
    /* never exits */
3906
    return NULL;
3907
}
3908
#else
3909

    
3910
static int clone_func(void *arg)
3911
{
3912
    CPUState *env = arg;
3913
    cpu_loop(env);
3914
    /* never exits */
3915
    return 0;
3916
}
3917
#endif
3918

    
3919
/* do_fork() Must return host values and target errnos (unlike most
3920
   do_*() functions). */
3921
static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
3922
                   abi_ulong parent_tidptr, target_ulong newtls,
3923
                   abi_ulong child_tidptr)
3924
{
3925
    int ret;
3926
    TaskState *ts;
3927
    CPUState *new_env;
3928
#if defined(CONFIG_USE_NPTL)
3929
    unsigned int nptl_flags;
3930
    sigset_t sigmask;
3931
#else
3932
    uint8_t *new_stack;
3933
#endif
3934

    
3935
    /* Emulate vfork() with fork() */
3936
    if (flags & CLONE_VFORK)
3937
        flags &= ~(CLONE_VFORK | CLONE_VM);
3938

    
3939
    if (flags & CLONE_VM) {
3940
        TaskState *parent_ts = (TaskState *)env->opaque;
3941
#if defined(CONFIG_USE_NPTL)
3942
        new_thread_info info;
3943
        pthread_attr_t attr;
3944
#endif
3945
        ts = qemu_mallocz(sizeof(TaskState));
3946
        init_task_state(ts);
3947
        /* we create a new CPU instance. */
3948
        new_env = cpu_copy(env);
3949
#if defined(TARGET_I386) || defined(TARGET_SPARC) || defined(TARGET_PPC)
3950
        cpu_reset(new_env);
3951
#endif
3952
        /* Init regs that differ from the parent.  */
3953
        cpu_clone_regs(new_env, newsp);
3954
        new_env->opaque = ts;
3955
        ts->bprm = parent_ts->bprm;
3956
        ts->info = parent_ts->info;
3957
#if defined(CONFIG_USE_NPTL)
3958
        nptl_flags = flags;
3959
        flags &= ~CLONE_NPTL_FLAGS2;
3960

    
3961
        if (nptl_flags & CLONE_CHILD_CLEARTID) {
3962
            ts->child_tidptr = child_tidptr;
3963
        }
3964

    
3965
        if (nptl_flags & CLONE_SETTLS)
3966
            cpu_set_tls (new_env, newtls);
3967

    
3968
        /* Grab a mutex so that thread setup appears atomic.  */
3969
        pthread_mutex_lock(&clone_lock);
3970

    
3971
        memset(&info, 0, sizeof(info));
3972
        pthread_mutex_init(&info.mutex, NULL);
3973
        pthread_mutex_lock(&info.mutex);
3974
        pthread_cond_init(&info.cond, NULL);
3975
        info.env = new_env;
3976
        if (nptl_flags & CLONE_CHILD_SETTID)
3977
            info.child_tidptr = child_tidptr;
3978
        if (nptl_flags & CLONE_PARENT_SETTID)
3979
            info.parent_tidptr = parent_tidptr;
3980

    
3981
        ret = pthread_attr_init(&attr);
3982
        ret = pthread_attr_setstacksize(&attr, NEW_STACK_SIZE);
3983
        ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
3984
        /* It is not safe to deliver signals until the child has finished
3985
           initializing, so temporarily block all signals.  */
3986
        sigfillset(&sigmask);
3987
        sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
3988

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

    
3992
        sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
3993
        pthread_attr_destroy(&attr);
3994
        if (ret == 0) {
3995
            /* Wait for the child to initialize.  */
3996
            pthread_cond_wait(&info.cond, &info.mutex);
3997
            ret = info.tid;
3998
            if (flags & CLONE_PARENT_SETTID)
3999
                put_user_u32(ret, parent_tidptr);
4000
        } else {
4001
            ret = -1;
4002
        }
4003
        pthread_mutex_unlock(&info.mutex);
4004
        pthread_cond_destroy(&info.cond);
4005
        pthread_mutex_destroy(&info.mutex);
4006
        pthread_mutex_unlock(&clone_lock);
4007
#else
4008
        if (flags & CLONE_NPTL_FLAGS2)
4009
            return -EINVAL;
4010
        /* This is probably going to die very quickly, but do it anyway.  */
4011
        new_stack = qemu_mallocz (NEW_STACK_SIZE);
4012
#ifdef __ia64__
4013
        ret = __clone2(clone_func, new_stack, NEW_STACK_SIZE, flags, new_env);
4014
#else
4015
        ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
4016
#endif
4017
#endif
4018
    } else {
4019
        /* if no CLONE_VM, we consider it is a fork */
4020
        if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
4021
            return -EINVAL;
4022
        fork_start();
4023
        ret = fork();
4024
        if (ret == 0) {
4025
            /* Child Process.  */
4026
            cpu_clone_regs(env, newsp);
4027
            fork_end(1);
4028
#if defined(CONFIG_USE_NPTL)
4029
            /* There is a race condition here.  The parent process could
4030
               theoretically read the TID in the child process before the child
4031
               tid is set.  This would require using either ptrace
4032
               (not implemented) or having *_tidptr to point at a shared memory
4033
               mapping.  We can't repeat the spinlock hack used above because
4034
               the child process gets its own copy of the lock.  */
4035
            if (flags & CLONE_CHILD_SETTID)
4036
                put_user_u32(gettid(), child_tidptr);
4037
            if (flags & CLONE_PARENT_SETTID)
4038
                put_user_u32(gettid(), parent_tidptr);
4039
            ts = (TaskState *)env->opaque;
4040
            if (flags & CLONE_SETTLS)
4041
                cpu_set_tls (env, newtls);
4042
            if (flags & CLONE_CHILD_CLEARTID)
4043
                ts->child_tidptr = child_tidptr;
4044
#endif
4045
        } else {
4046
            fork_end(0);
4047
        }
4048
    }
4049
    return ret;
4050
}
4051

    
4052
/* warning : doesn't handle linux specific flags... */
4053
static int target_to_host_fcntl_cmd(int cmd)
4054
{
4055
    switch(cmd) {
4056
        case TARGET_F_DUPFD:
4057
        case TARGET_F_GETFD:
4058
        case TARGET_F_SETFD:
4059
        case TARGET_F_GETFL:
4060
        case TARGET_F_SETFL:
4061
            return cmd;
4062
        case TARGET_F_GETLK:
4063
            return F_GETLK;
4064
        case TARGET_F_SETLK:
4065
            return F_SETLK;
4066
        case TARGET_F_SETLKW:
4067
            return F_SETLKW;
4068
        case TARGET_F_GETOWN:
4069
            return F_GETOWN;
4070
        case TARGET_F_SETOWN:
4071
            return F_SETOWN;
4072
        case TARGET_F_GETSIG:
4073
            return F_GETSIG;
4074
        case TARGET_F_SETSIG:
4075
            return F_SETSIG;
4076
#if TARGET_ABI_BITS == 32
4077
        case TARGET_F_GETLK64:
4078
            return F_GETLK64;
4079
        case TARGET_F_SETLK64:
4080
            return F_SETLK64;
4081
        case TARGET_F_SETLKW64:
4082
            return F_SETLKW64;
4083
#endif
4084
        case TARGET_F_SETLEASE:
4085
            return F_SETLEASE;
4086
        case TARGET_F_GETLEASE:
4087
            return F_GETLEASE;
4088
#ifdef F_DUPFD_CLOEXEC
4089
        case TARGET_F_DUPFD_CLOEXEC:
4090
            return F_DUPFD_CLOEXEC;
4091
#endif
4092
        case TARGET_F_NOTIFY:
4093
            return F_NOTIFY;
4094
        default:
4095
            return -TARGET_EINVAL;
4096
    }
4097
    return -TARGET_EINVAL;
4098
}
4099

    
4100
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
4101
{
4102
    struct flock fl;
4103
    struct target_flock *target_fl;
4104
    struct flock64 fl64;
4105
    struct target_flock64 *target_fl64;
4106
    abi_long ret;
4107
    int host_cmd = target_to_host_fcntl_cmd(cmd);
4108

    
4109
    if (host_cmd == -TARGET_EINVAL)
4110
            return host_cmd;
4111

    
4112
    switch(cmd) {
4113
    case TARGET_F_GETLK:
4114
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
4115
            return -TARGET_EFAULT;
4116
        fl.l_type = tswap16(target_fl->l_type);
4117
        fl.l_whence = tswap16(target_fl->l_whence);
4118
        fl.l_start = tswapl(target_fl->l_start);
4119
        fl.l_len = tswapl(target_fl->l_len);
4120
        fl.l_pid = tswap32(target_fl->l_pid);
4121
        unlock_user_struct(target_fl, arg, 0);
4122
        ret = get_errno(fcntl(fd, host_cmd, &fl));
4123
        if (ret == 0) {
4124
            if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
4125
                return -TARGET_EFAULT;
4126
            target_fl->l_type = tswap16(fl.l_type);
4127
            target_fl->l_whence = tswap16(fl.l_whence);
4128
            target_fl->l_start = tswapl(fl.l_start);
4129
            target_fl->l_len = tswapl(fl.l_len);
4130
            target_fl->l_pid = tswap32(fl.l_pid);
4131
            unlock_user_struct(target_fl, arg, 1);
4132
        }
4133
        break;
4134

    
4135
    case TARGET_F_SETLK:
4136
    case TARGET_F_SETLKW:
4137
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
4138
            return -TARGET_EFAULT;
4139
        fl.l_type = tswap16(target_fl->l_type);
4140
        fl.l_whence = tswap16(target_fl->l_whence);
4141
        fl.l_start = tswapl(target_fl->l_start);
4142
        fl.l_len = tswapl(target_fl->l_len);
4143
        fl.l_pid = tswap32(target_fl->l_pid);
4144
        unlock_user_struct(target_fl, arg, 0);
4145
        ret = get_errno(fcntl(fd, host_cmd, &fl));
4146
        break;
4147

    
4148
    case TARGET_F_GETLK64:
4149
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
4150
            return -TARGET_EFAULT;
4151
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
4152
        fl64.l_whence = tswap16(target_fl64->l_whence);
4153
        fl64.l_start = tswapl(target_fl64->l_start);
4154
        fl64.l_len = tswapl(target_fl64->l_len);
4155
        fl64.l_pid = tswap32(target_fl64->l_pid);
4156
        unlock_user_struct(target_fl64, arg, 0);
4157
        ret = get_errno(fcntl(fd, host_cmd, &fl64));
4158
        if (ret == 0) {
4159
            if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
4160
                return -TARGET_EFAULT;
4161
            target_fl64->l_type = tswap16(fl64.l_type) >> 1;
4162
            target_fl64->l_whence = tswap16(fl64.l_whence);
4163
            target_fl64->l_start = tswapl(fl64.l_start);
4164
            target_fl64->l_len = tswapl(fl64.l_len);
4165
            target_fl64->l_pid = tswap32(fl64.l_pid);
4166
            unlock_user_struct(target_fl64, arg, 1);
4167
        }
4168
        break;
4169
    case TARGET_F_SETLK64:
4170
    case TARGET_F_SETLKW64:
4171
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
4172
            return -TARGET_EFAULT;
4173
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
4174
        fl64.l_whence = tswap16(target_fl64->l_whence);
4175
        fl64.l_start = tswapl(target_fl64->l_start);
4176
        fl64.l_len = tswapl(target_fl64->l_len);
4177
        fl64.l_pid = tswap32(target_fl64->l_pid);
4178
        unlock_user_struct(target_fl64, arg, 0);
4179
        ret = get_errno(fcntl(fd, host_cmd, &fl64));
4180
        break;
4181

    
4182
    case TARGET_F_GETFL:
4183
        ret = get_errno(fcntl(fd, host_cmd, arg));
4184
        if (ret >= 0) {
4185
            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
4186
        }
4187
        break;
4188

    
4189
    case TARGET_F_SETFL:
4190
        ret = get_errno(fcntl(fd, host_cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
4191
        break;
4192

    
4193
    case TARGET_F_SETOWN:
4194
    case TARGET_F_GETOWN:
4195
    case TARGET_F_SETSIG:
4196
    case TARGET_F_GETSIG:
4197
    case TARGET_F_SETLEASE:
4198
    case TARGET_F_GETLEASE:
4199
        ret = get_errno(fcntl(fd, host_cmd, arg));
4200
        break;
4201

    
4202
    default:
4203
        ret = get_errno(fcntl(fd, cmd, arg));
4204
        break;
4205
    }
4206
    return ret;
4207
}
4208

    
4209
#ifdef USE_UID16
4210

    
4211
static inline int high2lowuid(int uid)
4212
{
4213
    if (uid > 65535)
4214
        return 65534;
4215
    else
4216
        return uid;
4217
}
4218

    
4219
static inline int high2lowgid(int gid)
4220
{
4221
    if (gid > 65535)
4222
        return 65534;
4223
    else
4224
        return gid;
4225
}
4226

    
4227
static inline int low2highuid(int uid)
4228
{
4229
    if ((int16_t)uid == -1)
4230
        return -1;
4231
    else
4232
        return uid;
4233
}
4234

    
4235
static inline int low2highgid(int gid)
4236
{
4237
    if ((int16_t)gid == -1)
4238
        return -1;
4239
    else
4240
        return gid;
4241
}
4242
static inline int tswapid(int id)
4243
{
4244
    return tswap16(id);
4245
}
4246
#else /* !USE_UID16 */
4247
static inline int high2lowuid(int uid)
4248
{
4249
    return uid;
4250
}
4251
static inline int high2lowgid(int gid)
4252
{
4253
    return gid;
4254
}
4255
static inline int low2highuid(int uid)
4256
{
4257
    return uid;
4258
}
4259
static inline int low2highgid(int gid)
4260
{
4261
    return gid;
4262
}
4263
static inline int tswapid(int id)
4264
{
4265
    return tswap32(id);
4266
}
4267
#endif /* USE_UID16 */
4268

    
4269
void syscall_init(void)
4270
{
4271
    IOCTLEntry *ie;
4272
    const argtype *arg_type;
4273
    int size;
4274
    int i;
4275

    
4276
#define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
4277
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
4278
#include "syscall_types.h"
4279
#undef STRUCT
4280
#undef STRUCT_SPECIAL
4281

    
4282
    /* we patch the ioctl size if necessary. We rely on the fact that
4283
       no ioctl has all the bits at '1' in the size field */
4284
    ie = ioctl_entries;
4285
    while (ie->target_cmd != 0) {
4286
        if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
4287
            TARGET_IOC_SIZEMASK) {
4288
            arg_type = ie->arg_type;
4289
            if (arg_type[0] != TYPE_PTR) {
4290
                fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
4291
                        ie->target_cmd);
4292
                exit(1);
4293
            }
4294
            arg_type++;
4295
            size = thunk_type_size(arg_type, 0);
4296
            ie->target_cmd = (ie->target_cmd &
4297
                              ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
4298
                (size << TARGET_IOC_SIZESHIFT);
4299
        }
4300

    
4301
        /* Build target_to_host_errno_table[] table from
4302
         * host_to_target_errno_table[]. */
4303
        for (i=0; i < ERRNO_TABLE_SIZE; i++)
4304
                target_to_host_errno_table[host_to_target_errno_table[i]] = i;
4305

    
4306
        /* automatic consistency check if same arch */
4307
#if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
4308
    (defined(__x86_64__) && defined(TARGET_X86_64))
4309
        if (unlikely(ie->target_cmd != ie->host_cmd)) {
4310
            fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
4311
                    ie->name, ie->target_cmd, ie->host_cmd);
4312
        }
4313
#endif
4314
        ie++;
4315
    }
4316
}
4317

    
4318
#if TARGET_ABI_BITS == 32
4319
static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
4320
{
4321
#ifdef TARGET_WORDS_BIGENDIAN
4322
    return ((uint64_t)word0 << 32) | word1;
4323
#else
4324
    return ((uint64_t)word1 << 32) | word0;
4325
#endif
4326
}
4327
#else /* TARGET_ABI_BITS == 32 */
4328
static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
4329
{
4330
    return word0;
4331
}
4332
#endif /* TARGET_ABI_BITS != 32 */
4333

    
4334
#ifdef TARGET_NR_truncate64
4335
static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
4336
                                         abi_long arg2,
4337
                                         abi_long arg3,
4338
                                         abi_long arg4)
4339
{
4340
#ifdef TARGET_ARM
4341
    if (((CPUARMState *)cpu_env)->eabi)
4342
      {
4343
        arg2 = arg3;
4344
        arg3 = arg4;
4345
      }
4346
#endif
4347
    return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
4348
}
4349
#endif
4350

    
4351
#ifdef TARGET_NR_ftruncate64
4352
static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
4353
                                          abi_long arg2,
4354
                                          abi_long arg3,
4355
                                          abi_long arg4)
4356
{
4357
#ifdef TARGET_ARM
4358
    if (((CPUARMState *)cpu_env)->eabi)
4359
      {
4360
        arg2 = arg3;
4361
        arg3 = arg4;
4362
      }
4363
#endif
4364
    return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
4365
}
4366
#endif
4367

    
4368
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
4369
                                               abi_ulong target_addr)
4370
{
4371
    struct target_timespec *target_ts;
4372

    
4373
    if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
4374
        return -TARGET_EFAULT;
4375
    host_ts->tv_sec = tswapl(target_ts->tv_sec);
4376
    host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
4377
    unlock_user_struct(target_ts, target_addr, 0);
4378
    return 0;
4379
}
4380

    
4381
static inline abi_long host_to_target_timespec(abi_ulong target_addr,
4382
                                               struct timespec *host_ts)
4383
{
4384
    struct target_timespec *target_ts;
4385

    
4386
    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
4387
        return -TARGET_EFAULT;
4388
    target_ts->tv_sec = tswapl(host_ts->tv_sec);
4389
    target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
4390
    unlock_user_struct(target_ts, target_addr, 1);
4391
    return 0;
4392
}
4393

    
4394
#if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
4395
static inline abi_long host_to_target_stat64(void *cpu_env,
4396
                                             abi_ulong target_addr,
4397
                                             struct stat *host_st)
4398
{
4399
#ifdef TARGET_ARM
4400
    if (((CPUARMState *)cpu_env)->eabi) {
4401
        struct target_eabi_stat64 *target_st;
4402

    
4403
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
4404
            return -TARGET_EFAULT;
4405
        memset(target_st, 0, sizeof(struct target_eabi_stat64));
4406
        __put_user(host_st->st_dev, &target_st->st_dev);
4407
        __put_user(host_st->st_ino, &target_st->st_ino);
4408
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4409
        __put_user(host_st->st_ino, &target_st->__st_ino);
4410
#endif
4411
        __put_user(host_st->st_mode, &target_st->st_mode);
4412
        __put_user(host_st->st_nlink, &target_st->st_nlink);
4413
        __put_user(host_st->st_uid, &target_st->st_uid);
4414
        __put_user(host_st->st_gid, &target_st->st_gid);
4415
        __put_user(host_st->st_rdev, &target_st->st_rdev);
4416
        __put_user(host_st->st_size, &target_st->st_size);
4417
        __put_user(host_st->st_blksize, &target_st->st_blksize);
4418
        __put_user(host_st->st_blocks, &target_st->st_blocks);
4419
        __put_user(host_st->st_atime, &target_st->target_st_atime);
4420
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
4421
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
4422
        unlock_user_struct(target_st, target_addr, 1);
4423
    } else
4424
#endif
4425
    {
4426
#if TARGET_ABI_BITS == 64 && !defined(TARGET_ALPHA)
4427
        struct target_stat *target_st;
4428
#else
4429
        struct target_stat64 *target_st;
4430
#endif
4431

    
4432
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
4433
            return -TARGET_EFAULT;
4434
        memset(target_st, 0, sizeof(*target_st));
4435
        __put_user(host_st->st_dev, &target_st->st_dev);
4436
        __put_user(host_st->st_ino, &target_st->st_ino);
4437
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4438
        __put_user(host_st->st_ino, &target_st->__st_ino);
4439
#endif
4440
        __put_user(host_st->st_mode, &target_st->st_mode);
4441
        __put_user(host_st->st_nlink, &target_st->st_nlink);
4442
        __put_user(host_st->st_uid, &target_st->st_uid);
4443
        __put_user(host_st->st_gid, &target_st->st_gid);
4444
        __put_user(host_st->st_rdev, &target_st->st_rdev);
4445
        /* XXX: better use of kernel struct */
4446
        __put_user(host_st->st_size, &target_st->st_size);
4447
        __put_user(host_st->st_blksize, &target_st->st_blksize);
4448
        __put_user(host_st->st_blocks, &target_st->st_blocks);
4449
        __put_user(host_st->st_atime, &target_st->target_st_atime);
4450
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
4451
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
4452
        unlock_user_struct(target_st, target_addr, 1);
4453
    }
4454

    
4455
    return 0;
4456
}
4457
#endif
4458

    
4459
#if defined(CONFIG_USE_NPTL)
4460
/* ??? Using host futex calls even when target atomic operations
4461
   are not really atomic probably breaks things.  However implementing
4462
   futexes locally would make futexes shared between multiple processes
4463
   tricky.  However they're probably useless because guest atomic
4464
   operations won't work either.  */
4465
static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
4466
                    target_ulong uaddr2, int val3)
4467
{
4468
    struct timespec ts, *pts;
4469
    int base_op;
4470

    
4471
    /* ??? We assume FUTEX_* constants are the same on both host
4472
       and target.  */
4473
#ifdef FUTEX_CMD_MASK
4474
    base_op = op & FUTEX_CMD_MASK;
4475
#else
4476
    base_op = op;
4477
#endif
4478
    switch (base_op) {
4479
    case FUTEX_WAIT:
4480
        if (timeout) {
4481
            pts = &ts;
4482
            target_to_host_timespec(pts, timeout);
4483
        } else {
4484
            pts = NULL;
4485
        }
4486
        return get_errno(sys_futex(g2h(uaddr), op, tswap32(val),
4487
                         pts, NULL, 0));
4488
    case FUTEX_WAKE:
4489
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4490
    case FUTEX_FD:
4491
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4492
    case FUTEX_REQUEUE:
4493
    case FUTEX_CMP_REQUEUE:
4494
    case FUTEX_WAKE_OP:
4495
        /* For FUTEX_REQUEUE, FUTEX_CMP_REQUEUE, and FUTEX_WAKE_OP, the
4496
           TIMEOUT parameter is interpreted as a uint32_t by the kernel.
4497
           But the prototype takes a `struct timespec *'; insert casts
4498
           to satisfy the compiler.  We do not need to tswap TIMEOUT
4499
           since it's not compared to guest memory.  */
4500
        pts = (struct timespec *)(uintptr_t) timeout;
4501
        return get_errno(sys_futex(g2h(uaddr), op, val, pts,
4502
                                   g2h(uaddr2),
4503
                                   (base_op == FUTEX_CMP_REQUEUE
4504
                                    ? tswap32(val3)
4505
                                    : val3)));
4506
    default:
4507
        return -TARGET_ENOSYS;
4508
    }
4509
}
4510
#endif
4511

    
4512
/* Map host to target signal numbers for the wait family of syscalls.
4513
   Assume all other status bits are the same.  */
4514
static int host_to_target_waitstatus(int status)
4515
{
4516
    if (WIFSIGNALED(status)) {
4517
        return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f);
4518
    }
4519
    if (WIFSTOPPED(status)) {
4520
        return (host_to_target_signal(WSTOPSIG(status)) << 8)
4521
               | (status & 0xff);
4522
    }
4523
    return status;
4524
}
4525

    
4526
int get_osversion(void)
4527
{
4528
    static int osversion;
4529
    struct new_utsname buf;
4530
    const char *s;
4531
    int i, n, tmp;
4532
    if (osversion)
4533
        return osversion;
4534
    if (qemu_uname_release && *qemu_uname_release) {
4535
        s = qemu_uname_release;
4536
    } else {
4537
        if (sys_uname(&buf))
4538
            return 0;
4539
        s = buf.release;
4540
    }
4541
    tmp = 0;
4542
    for (i = 0; i < 3; i++) {
4543
        n = 0;
4544
        while (*s >= '0' && *s <= '9') {
4545
            n *= 10;
4546
            n += *s - '0';
4547
            s++;
4548
        }
4549
        tmp = (tmp << 8) + n;
4550
        if (*s == '.')
4551
            s++;
4552
    }
4553
    osversion = tmp;
4554
    return osversion;
4555
}
4556

    
4557
/* do_syscall() should always have a single exit point at the end so
4558
   that actions, such as logging of syscall results, can be performed.
4559
   All errnos that do_syscall() returns must be -TARGET_<errcode>. */
4560
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4561
                    abi_long arg2, abi_long arg3, abi_long arg4,
4562
                    abi_long arg5, abi_long arg6, abi_long arg7,
4563
                    abi_long arg8)
4564
{
4565
    abi_long ret;
4566
    struct stat st;
4567
    struct statfs stfs;
4568
    void *p;
4569

    
4570
#ifdef DEBUG
4571
    gemu_log("syscall %d", num);
4572
#endif
4573
    if(do_strace)
4574
        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
4575

    
4576
    switch(num) {
4577
    case TARGET_NR_exit:
4578
#ifdef CONFIG_USE_NPTL
4579
      /* In old applications this may be used to implement _exit(2).
4580
         However in threaded applictions it is used for thread termination,
4581
         and _exit_group is used for application termination.
4582
         Do thread termination if we have more then one thread.  */
4583
      /* FIXME: This probably breaks if a signal arrives.  We should probably
4584
         be disabling signals.  */
4585
      if (first_cpu->next_cpu) {
4586
          TaskState *ts;
4587
          CPUState **lastp;
4588
          CPUState *p;
4589

    
4590
          cpu_list_lock();
4591
          lastp = &first_cpu;
4592
          p = first_cpu;
4593
          while (p && p != (CPUState *)cpu_env) {
4594
              lastp = &p->next_cpu;
4595
              p = p->next_cpu;
4596
          }
4597
          /* If we didn't find the CPU for this thread then something is
4598
             horribly wrong.  */
4599
          if (!p)
4600
              abort();
4601
          /* Remove the CPU from the list.  */
4602
          *lastp = p->next_cpu;
4603
          cpu_list_unlock();
4604
          ts = ((CPUState *)cpu_env)->opaque;
4605
          if (ts->child_tidptr) {
4606
              put_user_u32(0, ts->child_tidptr);
4607
              sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
4608
                        NULL, NULL, 0);
4609
          }
4610
          thread_env = NULL;
4611
          qemu_free(cpu_env);
4612
          qemu_free(ts);
4613
          pthread_exit(NULL);
4614
      }
4615
#endif
4616
#ifdef TARGET_GPROF
4617
        _mcleanup();
4618
#endif
4619
        gdb_exit(cpu_env, arg1);
4620
        _exit(arg1);
4621
        ret = 0; /* avoid warning */
4622
        break;
4623
    case TARGET_NR_read:
4624
        if (arg3 == 0)
4625
            ret = 0;
4626
        else {
4627
            if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
4628
                goto efault;
4629
            ret = get_errno(read(arg1, p, arg3));
4630
            unlock_user(p, arg2, ret);
4631
        }
4632
        break;
4633
    case TARGET_NR_write:
4634
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
4635
            goto efault;
4636
        ret = get_errno(write(arg1, p, arg3));
4637
        unlock_user(p, arg2, 0);
4638
        break;
4639
    case TARGET_NR_open:
4640
        if (!(p = lock_user_string(arg1)))
4641
            goto efault;
4642
        ret = get_errno(open(path(p),
4643
                             target_to_host_bitmask(arg2, fcntl_flags_tbl),
4644
                             arg3));
4645
        unlock_user(p, arg1, 0);
4646
        break;
4647
#if defined(TARGET_NR_openat) && defined(__NR_openat)
4648
    case TARGET_NR_openat:
4649
        if (!(p = lock_user_string(arg2)))
4650
            goto efault;
4651
        ret = get_errno(sys_openat(arg1,
4652
                                   path(p),
4653
                                   target_to_host_bitmask(arg3, fcntl_flags_tbl),
4654
                                   arg4));
4655
        unlock_user(p, arg2, 0);
4656
        break;
4657
#endif
4658
    case TARGET_NR_close:
4659
        ret = get_errno(close(arg1));
4660
        break;
4661
    case TARGET_NR_brk:
4662
        ret = do_brk(arg1);
4663
        break;
4664
    case TARGET_NR_fork:
4665
        ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
4666
        break;
4667
#ifdef TARGET_NR_waitpid
4668
    case TARGET_NR_waitpid:
4669
        {
4670
            int status;
4671
            ret = get_errno(waitpid(arg1, &status, arg3));
4672
            if (!is_error(ret) && arg2
4673
                && put_user_s32(host_to_target_waitstatus(status), arg2))
4674
                goto efault;
4675
        }
4676
        break;
4677
#endif
4678
#ifdef TARGET_NR_waitid
4679
    case TARGET_NR_waitid:
4680
        {
4681
            siginfo_t info;
4682
            info.si_pid = 0;
4683
            ret = get_errno(waitid(arg1, arg2, &info, arg4));
4684
            if (!is_error(ret) && arg3 && info.si_pid != 0) {
4685
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
4686
                    goto efault;
4687
                host_to_target_siginfo(p, &info);
4688
                unlock_user(p, arg3, sizeof(target_siginfo_t));
4689
            }
4690
        }
4691
        break;
4692
#endif
4693
#ifdef TARGET_NR_creat /* not on alpha */
4694
    case TARGET_NR_creat:
4695
        if (!(p = lock_user_string(arg1)))
4696
            goto efault;
4697
        ret = get_errno(creat(p, arg2));
4698
        unlock_user(p, arg1, 0);
4699
        break;
4700
#endif
4701
    case TARGET_NR_link:
4702
        {
4703
            void * p2;
4704
            p = lock_user_string(arg1);
4705
            p2 = lock_user_string(arg2);
4706
            if (!p || !p2)
4707
                ret = -TARGET_EFAULT;
4708
            else
4709
                ret = get_errno(link(p, p2));
4710
            unlock_user(p2, arg2, 0);
4711
            unlock_user(p, arg1, 0);
4712
        }
4713
        break;
4714
#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
4715
    case TARGET_NR_linkat:
4716
        {
4717
            void * p2 = NULL;
4718
            if (!arg2 || !arg4)
4719
                goto efault;
4720
            p  = lock_user_string(arg2);
4721
            p2 = lock_user_string(arg4);
4722
            if (!p || !p2)
4723
                ret = -TARGET_EFAULT;
4724
            else
4725
                ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
4726
            unlock_user(p, arg2, 0);
4727
            unlock_user(p2, arg4, 0);
4728
        }
4729
        break;
4730
#endif
4731
    case TARGET_NR_unlink:
4732
        if (!(p = lock_user_string(arg1)))
4733
            goto efault;
4734
        ret = get_errno(unlink(p));
4735
        unlock_user(p, arg1, 0);
4736
        break;
4737
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
4738
    case TARGET_NR_unlinkat:
4739
        if (!(p = lock_user_string(arg2)))
4740
            goto efault;
4741
        ret = get_errno(sys_unlinkat(arg1, p, arg3));
4742
        unlock_user(p, arg2, 0);
4743
        break;
4744
#endif
4745
    case TARGET_NR_execve:
4746
        {
4747
            char **argp, **envp;
4748
            int argc, envc;
4749
            abi_ulong gp;
4750
            abi_ulong guest_argp;
4751
            abi_ulong guest_envp;
4752
            abi_ulong addr;
4753
            char **q;
4754

    
4755
            argc = 0;
4756
            guest_argp = arg2;
4757
            for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
4758
                if (get_user_ual(addr, gp))
4759
                    goto efault;
4760
                if (!addr)
4761
                    break;
4762
                argc++;
4763
            }
4764
            envc = 0;
4765
            guest_envp = arg3;
4766
            for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
4767
                if (get_user_ual(addr, gp))
4768
                    goto efault;
4769
                if (!addr)
4770
                    break;
4771
                envc++;
4772
            }
4773

    
4774
            argp = alloca((argc + 1) * sizeof(void *));
4775
            envp = alloca((envc + 1) * sizeof(void *));
4776

    
4777
            for (gp = guest_argp, q = argp; gp;
4778
                  gp += sizeof(abi_ulong), q++) {
4779
                if (get_user_ual(addr, gp))
4780
                    goto execve_efault;
4781
                if (!addr)
4782
                    break;
4783
                if (!(*q = lock_user_string(addr)))
4784
                    goto execve_efault;
4785
            }
4786
            *q = NULL;
4787

    
4788
            for (gp = guest_envp, q = envp; gp;
4789
                  gp += sizeof(abi_ulong), q++) {
4790
                if (get_user_ual(addr, gp))
4791
                    goto execve_efault;
4792
                if (!addr)
4793
                    break;
4794
                if (!(*q = lock_user_string(addr)))
4795
                    goto execve_efault;
4796
            }
4797
            *q = NULL;
4798

    
4799
            if (!(p = lock_user_string(arg1)))
4800
                goto execve_efault;
4801
            ret = get_errno(execve(p, argp, envp));
4802
            unlock_user(p, arg1, 0);
4803

    
4804
            goto execve_end;
4805

    
4806
        execve_efault:
4807
            ret = -TARGET_EFAULT;
4808

    
4809
        execve_end:
4810
            for (gp = guest_argp, q = argp; *q;
4811
                  gp += sizeof(abi_ulong), q++) {
4812
                if (get_user_ual(addr, gp)
4813
                    || !addr)
4814
                    break;
4815
                unlock_user(*q, addr, 0);
4816
            }
4817
            for (gp = guest_envp, q = envp; *q;
4818
                  gp += sizeof(abi_ulong), q++) {
4819
                if (get_user_ual(addr, gp)
4820
                    || !addr)
4821
                    break;
4822
                unlock_user(*q, addr, 0);
4823
            }
4824
        }
4825
        break;
4826
    case TARGET_NR_chdir:
4827
        if (!(p = lock_user_string(arg1)))
4828
            goto efault;
4829
        ret = get_errno(chdir(p));
4830
        unlock_user(p, arg1, 0);
4831
        break;
4832
#ifdef TARGET_NR_time
4833
    case TARGET_NR_time:
4834
        {
4835
            time_t host_time;
4836
            ret = get_errno(time(&host_time));
4837
            if (!is_error(ret)
4838
                && arg1
4839
                && put_user_sal(host_time, arg1))
4840
                goto efault;
4841
        }
4842
        break;
4843
#endif
4844
    case TARGET_NR_mknod:
4845
        if (!(p = lock_user_string(arg1)))
4846
            goto efault;
4847
        ret = get_errno(mknod(p, arg2, arg3));
4848
        unlock_user(p, arg1, 0);
4849
        break;
4850
#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
4851
    case TARGET_NR_mknodat:
4852
        if (!(p = lock_user_string(arg2)))
4853
            goto efault;
4854
        ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
4855
        unlock_user(p, arg2, 0);
4856
        break;
4857
#endif
4858
    case TARGET_NR_chmod:
4859
        if (!(p = lock_user_string(arg1)))
4860
            goto efault;
4861
        ret = get_errno(chmod(p, arg2));
4862
        unlock_user(p, arg1, 0);
4863
        break;
4864
#ifdef TARGET_NR_break
4865
    case TARGET_NR_break:
4866
        goto unimplemented;
4867
#endif
4868
#ifdef TARGET_NR_oldstat
4869
    case TARGET_NR_oldstat:
4870
        goto unimplemented;
4871
#endif
4872
    case TARGET_NR_lseek:
4873
        ret = get_errno(lseek(arg1, arg2, arg3));
4874
        break;
4875
#if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA)
4876
    /* Alpha specific */
4877
    case TARGET_NR_getxpid:
4878
        ((CPUAlphaState *)cpu_env)->ir[IR_A4] = getppid();
4879
        ret = get_errno(getpid());
4880
        break;
4881
#endif
4882
#ifdef TARGET_NR_getpid
4883
    case TARGET_NR_getpid:
4884
        ret = get_errno(getpid());
4885
        break;
4886
#endif
4887
    case TARGET_NR_mount:
4888
                {
4889
                        /* need to look at the data field */
4890
                        void *p2, *p3;
4891
                        p = lock_user_string(arg1);
4892
                        p2 = lock_user_string(arg2);
4893
                        p3 = lock_user_string(arg3);
4894
                        if (!p || !p2 || !p3)
4895
                            ret = -TARGET_EFAULT;
4896
                        else {
4897
                            /* FIXME - arg5 should be locked, but it isn't clear how to
4898
                             * do that since it's not guaranteed to be a NULL-terminated
4899
                             * string.
4900
                             */
4901
                            if ( ! arg5 )
4902
                                ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, NULL));
4903
                            else
4904
                                ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
4905
                        }
4906
                        unlock_user(p, arg1, 0);
4907
                        unlock_user(p2, arg2, 0);
4908
                        unlock_user(p3, arg3, 0);
4909
                        break;
4910
                }
4911
#ifdef TARGET_NR_umount
4912
    case TARGET_NR_umount:
4913
        if (!(p = lock_user_string(arg1)))
4914
            goto efault;
4915
        ret = get_errno(umount(p));
4916
        unlock_user(p, arg1, 0);
4917
        break;
4918
#endif
4919
#ifdef TARGET_NR_stime /* not on alpha */
4920
    case TARGET_NR_stime:
4921
        {
4922
            time_t host_time;
4923
            if (get_user_sal(host_time, arg1))
4924
                goto efault;
4925
            ret = get_errno(stime(&host_time));
4926
        }
4927
        break;
4928
#endif
4929
    case TARGET_NR_ptrace:
4930
        goto unimplemented;
4931
#ifdef TARGET_NR_alarm /* not on alpha */
4932
    case TARGET_NR_alarm:
4933
        ret = alarm(arg1);
4934
        break;
4935
#endif
4936
#ifdef TARGET_NR_oldfstat
4937
    case TARGET_NR_oldfstat:
4938
        goto unimplemented;
4939
#endif
4940
#ifdef TARGET_NR_pause /* not on alpha */
4941
    case TARGET_NR_pause:
4942
        ret = get_errno(pause());
4943
        break;
4944
#endif
4945
#ifdef TARGET_NR_utime
4946
    case TARGET_NR_utime:
4947
        {
4948
            struct utimbuf tbuf, *host_tbuf;
4949
            struct target_utimbuf *target_tbuf;
4950
            if (arg2) {
4951
                if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
4952
                    goto efault;
4953
                tbuf.actime = tswapl(target_tbuf->actime);
4954
                tbuf.modtime = tswapl(target_tbuf->modtime);
4955
                unlock_user_struct(target_tbuf, arg2, 0);
4956
                host_tbuf = &tbuf;
4957
            } else {
4958
                host_tbuf = NULL;
4959
            }
4960
            if (!(p = lock_user_string(arg1)))
4961
                goto efault;
4962
            ret = get_errno(utime(p, host_tbuf));
4963
            unlock_user(p, arg1, 0);
4964
        }
4965
        break;
4966
#endif
4967
    case TARGET_NR_utimes:
4968
        {
4969
            struct timeval *tvp, tv[2];
4970
            if (arg2) {
4971
                if (copy_from_user_timeval(&tv[0], arg2)
4972
                    || copy_from_user_timeval(&tv[1],
4973
                                              arg2 + sizeof(struct target_timeval)))
4974
                    goto efault;
4975
                tvp = tv;
4976
            } else {
4977
                tvp = NULL;
4978
            }
4979
            if (!(p = lock_user_string(arg1)))
4980
                goto efault;
4981
            ret = get_errno(utimes(p, tvp));
4982
            unlock_user(p, arg1, 0);
4983
        }
4984
        break;
4985
#if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
4986
    case TARGET_NR_futimesat:
4987
        {
4988
            struct timeval *tvp, tv[2];
4989
            if (arg3) {
4990
                if (copy_from_user_ti