Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ 30cb4cde

History | View | Annotate | Download (238.2 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 <qemu-common.h>
63
#ifdef TARGET_GPROF
64
#include <sys/gmon.h>
65
#endif
66
#ifdef CONFIG_EVENTFD
67
#include <sys/eventfd.h>
68
#endif
69
#ifdef CONFIG_EPOLL
70
#include <sys/epoll.h>
71
#endif
72

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

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

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

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

    
108
//#define DEBUG
109

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

    
114

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

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

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

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

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

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

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

    
160

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

    
169

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

    
199
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
200
#define __NR__llseek __NR_lseek
201
#endif
202

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

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

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

    
275
static int sys_uname(struct new_utsname *buf)
276
{
277
  struct utsname uts_buf;
278

    
279
  if (uname(&uts_buf) < 0)
280
      return (-1);
281

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

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

    
299
#undef COPY_UTSNAME_FIELD
300
}
301

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

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

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

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

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

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

    
486
#endif /* CONFIG_ATFILE */
487

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

    
504
#ifdef CONFIG_INOTIFY
505
#include <sys/inotify.h>
506

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

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

    
551
extern int personality(int);
552
extern int flock(int, int);
553
extern int setfsuid(int);
554
extern int setfsgid(int);
555
extern int setgroups(int, gid_t *);
556

    
557
#define ERRNO_TABLE_SIZE 1200
558

    
559
/* target_to_host_errno_table[] is initialized from
560
 * host_to_target_errno_table[] in syscall_init(). */
561
static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
562
};
563

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

    
676
static inline int host_to_target_errno(int err)
677
{
678
    if(host_to_target_errno_table[err])
679
        return host_to_target_errno_table[err];
680
    return err;
681
}
682

    
683
static inline int target_to_host_errno(int err)
684
{
685
    if (target_to_host_errno_table[err])
686
        return target_to_host_errno_table[err];
687
    return err;
688
}
689

    
690
static inline abi_long get_errno(abi_long ret)
691
{
692
    if (ret == -1)
693
        return -host_to_target_errno(errno);
694
    else
695
        return ret;
696
}
697

    
698
static inline int is_error(abi_long ret)
699
{
700
    return (abi_ulong)ret >= (abi_ulong)(-4096);
701
}
702

    
703
char *target_strerror(int err)
704
{
705
    return strerror(target_to_host_errno(err));
706
}
707

    
708
static abi_ulong target_brk;
709
static abi_ulong target_original_brk;
710

    
711
void target_set_brk(abi_ulong new_brk)
712
{
713
    target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
714
}
715

    
716
/* do_brk() must return target values and target errnos. */
717
abi_long do_brk(abi_ulong new_brk)
718
{
719
    abi_ulong brk_page;
720
    abi_long mapped_addr;
721
    int        new_alloc_size;
722

    
723
    if (!new_brk)
724
        return target_brk;
725
    if (new_brk < target_original_brk)
726
        return target_brk;
727

    
728
    brk_page = HOST_PAGE_ALIGN(target_brk);
729

    
730
    /* If the new brk is less than this, set it and we're done... */
731
    if (new_brk < brk_page) {
732
        target_brk = new_brk;
733
            return target_brk;
734
    }
735

    
736
    /* We need to allocate more memory after the brk... */
737
    new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
738
    mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
739
                                        PROT_READ|PROT_WRITE,
740
                                        MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
741

    
742
#if defined(TARGET_ALPHA)
743
    /* We (partially) emulate OSF/1 on Alpha, which requires we
744
       return a proper errno, not an unchanged brk value.  */
745
    if (is_error(mapped_addr)) {
746
        return -TARGET_ENOMEM;
747
    }
748
#endif
749

    
750
    if (!is_error(mapped_addr)) {
751
        target_brk = new_brk;
752
    }
753
    return target_brk;
754
}
755

    
756
static inline abi_long copy_from_user_fdset(fd_set *fds,
757
                                            abi_ulong target_fds_addr,
758
                                            int n)
759
{
760
    int i, nw, j, k;
761
    abi_ulong b, *target_fds;
762

    
763
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
764
    if (!(target_fds = lock_user(VERIFY_READ,
765
                                 target_fds_addr,
766
                                 sizeof(abi_ulong) * nw,
767
                                 1)))
768
        return -TARGET_EFAULT;
769

    
770
    FD_ZERO(fds);
771
    k = 0;
772
    for (i = 0; i < nw; i++) {
773
        /* grab the abi_ulong */
774
        __get_user(b, &target_fds[i]);
775
        for (j = 0; j < TARGET_ABI_BITS; j++) {
776
            /* check the bit inside the abi_ulong */
777
            if ((b >> j) & 1)
778
                FD_SET(k, fds);
779
            k++;
780
        }
781
    }
782

    
783
    unlock_user(target_fds, target_fds_addr, 0);
784

    
785
    return 0;
786
}
787

    
788
static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
789
                                          const fd_set *fds,
790
                                          int n)
791
{
792
    int i, nw, j, k;
793
    abi_long v;
794
    abi_ulong *target_fds;
795

    
796
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
797
    if (!(target_fds = lock_user(VERIFY_WRITE,
798
                                 target_fds_addr,
799
                                 sizeof(abi_ulong) * nw,
800
                                 0)))
801
        return -TARGET_EFAULT;
802

    
803
    k = 0;
804
    for (i = 0; i < nw; i++) {
805
        v = 0;
806
        for (j = 0; j < TARGET_ABI_BITS; j++) {
807
            v |= ((FD_ISSET(k, fds) != 0) << j);
808
            k++;
809
        }
810
        __put_user(v, &target_fds[i]);
811
    }
812

    
813
    unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
814

    
815
    return 0;
816
}
817

    
818
#if defined(__alpha__)
819
#define HOST_HZ 1024
820
#else
821
#define HOST_HZ 100
822
#endif
823

    
824
static inline abi_long host_to_target_clock_t(long ticks)
825
{
826
#if HOST_HZ == TARGET_HZ
827
    return ticks;
828
#else
829
    return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
830
#endif
831
}
832

    
833
static inline abi_long host_to_target_rusage(abi_ulong target_addr,
834
                                             const struct rusage *rusage)
835
{
836
    struct target_rusage *target_rusage;
837

    
838
    if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
839
        return -TARGET_EFAULT;
840
    target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
841
    target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
842
    target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
843
    target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec);
844
    target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss);
845
    target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss);
846
    target_rusage->ru_idrss = tswapl(rusage->ru_idrss);
847
    target_rusage->ru_isrss = tswapl(rusage->ru_isrss);
848
    target_rusage->ru_minflt = tswapl(rusage->ru_minflt);
849
    target_rusage->ru_majflt = tswapl(rusage->ru_majflt);
850
    target_rusage->ru_nswap = tswapl(rusage->ru_nswap);
851
    target_rusage->ru_inblock = tswapl(rusage->ru_inblock);
852
    target_rusage->ru_oublock = tswapl(rusage->ru_oublock);
853
    target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd);
854
    target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv);
855
    target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);
856
    target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
857
    target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
858
    unlock_user_struct(target_rusage, target_addr, 1);
859

    
860
    return 0;
861
}
862

    
863
static inline rlim_t target_to_host_rlim(target_ulong target_rlim)
864
{
865
    if (target_rlim == TARGET_RLIM_INFINITY)
866
        return RLIM_INFINITY;
867
    else
868
        return tswapl(target_rlim);
869
}
870

    
871
static inline target_ulong host_to_target_rlim(rlim_t rlim)
872
{
873
    if (rlim == RLIM_INFINITY || rlim != (target_long)rlim)
874
        return TARGET_RLIM_INFINITY;
875
    else
876
        return tswapl(rlim);
877
}
878

    
879
static inline abi_long copy_from_user_timeval(struct timeval *tv,
880
                                              abi_ulong target_tv_addr)
881
{
882
    struct target_timeval *target_tv;
883

    
884
    if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
885
        return -TARGET_EFAULT;
886

    
887
    __get_user(tv->tv_sec, &target_tv->tv_sec);
888
    __get_user(tv->tv_usec, &target_tv->tv_usec);
889

    
890
    unlock_user_struct(target_tv, target_tv_addr, 0);
891

    
892
    return 0;
893
}
894

    
895
static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
896
                                            const struct timeval *tv)
897
{
898
    struct target_timeval *target_tv;
899

    
900
    if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
901
        return -TARGET_EFAULT;
902

    
903
    __put_user(tv->tv_sec, &target_tv->tv_sec);
904
    __put_user(tv->tv_usec, &target_tv->tv_usec);
905

    
906
    unlock_user_struct(target_tv, target_tv_addr, 1);
907

    
908
    return 0;
909
}
910

    
911
#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
912
#include <mqueue.h>
913

    
914
static inline abi_long copy_from_user_mq_attr(struct mq_attr *attr,
915
                                              abi_ulong target_mq_attr_addr)
916
{
917
    struct target_mq_attr *target_mq_attr;
918

    
919
    if (!lock_user_struct(VERIFY_READ, target_mq_attr,
920
                          target_mq_attr_addr, 1))
921
        return -TARGET_EFAULT;
922

    
923
    __get_user(attr->mq_flags, &target_mq_attr->mq_flags);
924
    __get_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
925
    __get_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
926
    __get_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
927

    
928
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0);
929

    
930
    return 0;
931
}
932

    
933
static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr,
934
                                            const struct mq_attr *attr)
935
{
936
    struct target_mq_attr *target_mq_attr;
937

    
938
    if (!lock_user_struct(VERIFY_WRITE, target_mq_attr,
939
                          target_mq_attr_addr, 0))
940
        return -TARGET_EFAULT;
941

    
942
    __put_user(attr->mq_flags, &target_mq_attr->mq_flags);
943
    __put_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
944
    __put_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
945
    __put_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
946

    
947
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1);
948

    
949
    return 0;
950
}
951
#endif
952

    
953
/* do_select() must return target values and target errnos. */
954
static abi_long do_select(int n,
955
                          abi_ulong rfd_addr, abi_ulong wfd_addr,
956
                          abi_ulong efd_addr, abi_ulong target_tv_addr)
957
{
958
    fd_set rfds, wfds, efds;
959
    fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
960
    struct timeval tv, *tv_ptr;
961
    abi_long ret;
962

    
963
    if (rfd_addr) {
964
        if (copy_from_user_fdset(&rfds, rfd_addr, n))
965
            return -TARGET_EFAULT;
966
        rfds_ptr = &rfds;
967
    } else {
968
        rfds_ptr = NULL;
969
    }
970
    if (wfd_addr) {
971
        if (copy_from_user_fdset(&wfds, wfd_addr, n))
972
            return -TARGET_EFAULT;
973
        wfds_ptr = &wfds;
974
    } else {
975
        wfds_ptr = NULL;
976
    }
977
    if (efd_addr) {
978
        if (copy_from_user_fdset(&efds, efd_addr, n))
979
            return -TARGET_EFAULT;
980
        efds_ptr = &efds;
981
    } else {
982
        efds_ptr = NULL;
983
    }
984

    
985
    if (target_tv_addr) {
986
        if (copy_from_user_timeval(&tv, target_tv_addr))
987
            return -TARGET_EFAULT;
988
        tv_ptr = &tv;
989
    } else {
990
        tv_ptr = NULL;
991
    }
992

    
993
    ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
994

    
995
    if (!is_error(ret)) {
996
        if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
997
            return -TARGET_EFAULT;
998
        if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
999
            return -TARGET_EFAULT;
1000
        if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
1001
            return -TARGET_EFAULT;
1002

    
1003
        if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
1004
            return -TARGET_EFAULT;
1005
    }
1006

    
1007
    return ret;
1008
}
1009

    
1010
static abi_long do_pipe2(int host_pipe[], int flags)
1011
{
1012
#ifdef CONFIG_PIPE2
1013
    return pipe2(host_pipe, flags);
1014
#else
1015
    return -ENOSYS;
1016
#endif
1017
}
1018

    
1019
static abi_long do_pipe(void *cpu_env, abi_ulong pipedes,
1020
                        int flags, int is_pipe2)
1021
{
1022
    int host_pipe[2];
1023
    abi_long ret;
1024
    ret = flags ? do_pipe2(host_pipe, flags) : pipe(host_pipe);
1025

    
1026
    if (is_error(ret))
1027
        return get_errno(ret);
1028

    
1029
    /* Several targets have special calling conventions for the original
1030
       pipe syscall, but didn't replicate this into the pipe2 syscall.  */
1031
    if (!is_pipe2) {
1032
#if defined(TARGET_ALPHA)
1033
        ((CPUAlphaState *)cpu_env)->ir[IR_A4] = host_pipe[1];
1034
        return host_pipe[0];
1035
#elif defined(TARGET_MIPS)
1036
        ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1];
1037
        return host_pipe[0];
1038
#elif defined(TARGET_SH4)
1039
        ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
1040
        return host_pipe[0];
1041
#endif
1042
    }
1043

    
1044
    if (put_user_s32(host_pipe[0], pipedes)
1045
        || put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0])))
1046
        return -TARGET_EFAULT;
1047
    return get_errno(ret);
1048
}
1049

    
1050
static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn,
1051
                                              abi_ulong target_addr,
1052
                                              socklen_t len)
1053
{
1054
    struct target_ip_mreqn *target_smreqn;
1055

    
1056
    target_smreqn = lock_user(VERIFY_READ, target_addr, len, 1);
1057
    if (!target_smreqn)
1058
        return -TARGET_EFAULT;
1059
    mreqn->imr_multiaddr.s_addr = target_smreqn->imr_multiaddr.s_addr;
1060
    mreqn->imr_address.s_addr = target_smreqn->imr_address.s_addr;
1061
    if (len == sizeof(struct target_ip_mreqn))
1062
        mreqn->imr_ifindex = tswapl(target_smreqn->imr_ifindex);
1063
    unlock_user(target_smreqn, target_addr, 0);
1064

    
1065
    return 0;
1066
}
1067

    
1068
static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
1069
                                               abi_ulong target_addr,
1070
                                               socklen_t len)
1071
{
1072
    const socklen_t unix_maxlen = sizeof (struct sockaddr_un);
1073
    sa_family_t sa_family;
1074
    struct target_sockaddr *target_saddr;
1075

    
1076
    target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
1077
    if (!target_saddr)
1078
        return -TARGET_EFAULT;
1079

    
1080
    sa_family = tswap16(target_saddr->sa_family);
1081

    
1082
    /* Oops. The caller might send a incomplete sun_path; sun_path
1083
     * must be terminated by \0 (see the manual page), but
1084
     * unfortunately it is quite common to specify sockaddr_un
1085
     * length as "strlen(x->sun_path)" while it should be
1086
     * "strlen(...) + 1". We'll fix that here if needed.
1087
     * Linux kernel has a similar feature.
1088
     */
1089

    
1090
    if (sa_family == AF_UNIX) {
1091
        if (len < unix_maxlen && len > 0) {
1092
            char *cp = (char*)target_saddr;
1093

    
1094
            if ( cp[len-1] && !cp[len] )
1095
                len++;
1096
        }
1097
        if (len > unix_maxlen)
1098
            len = unix_maxlen;
1099
    }
1100

    
1101
    memcpy(addr, target_saddr, len);
1102
    addr->sa_family = sa_family;
1103
    unlock_user(target_saddr, target_addr, 0);
1104

    
1105
    return 0;
1106
}
1107

    
1108
static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
1109
                                               struct sockaddr *addr,
1110
                                               socklen_t len)
1111
{
1112
    struct target_sockaddr *target_saddr;
1113

    
1114
    target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
1115
    if (!target_saddr)
1116
        return -TARGET_EFAULT;
1117
    memcpy(target_saddr, addr, len);
1118
    target_saddr->sa_family = tswap16(addr->sa_family);
1119
    unlock_user(target_saddr, target_addr, len);
1120

    
1121
    return 0;
1122
}
1123

    
1124
/* ??? Should this also swap msgh->name?  */
1125
static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
1126
                                           struct target_msghdr *target_msgh)
1127
{
1128
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1129
    abi_long msg_controllen;
1130
    abi_ulong target_cmsg_addr;
1131
    struct target_cmsghdr *target_cmsg;
1132
    socklen_t space = 0;
1133
    
1134
    msg_controllen = tswapl(target_msgh->msg_controllen);
1135
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1136
        goto the_end;
1137
    target_cmsg_addr = tswapl(target_msgh->msg_control);
1138
    target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
1139
    if (!target_cmsg)
1140
        return -TARGET_EFAULT;
1141

    
1142
    while (cmsg && target_cmsg) {
1143
        void *data = CMSG_DATA(cmsg);
1144
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
1145

    
1146
        int len = tswapl(target_cmsg->cmsg_len)
1147
                  - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
1148

    
1149
        space += CMSG_SPACE(len);
1150
        if (space > msgh->msg_controllen) {
1151
            space -= CMSG_SPACE(len);
1152
            gemu_log("Host cmsg overflow\n");
1153
            break;
1154
        }
1155

    
1156
        cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
1157
        cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
1158
        cmsg->cmsg_len = CMSG_LEN(len);
1159

    
1160
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1161
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1162
            memcpy(data, target_data, len);
1163
        } else {
1164
            int *fd = (int *)data;
1165
            int *target_fd = (int *)target_data;
1166
            int i, numfds = len / sizeof(int);
1167

    
1168
            for (i = 0; i < numfds; i++)
1169
                fd[i] = tswap32(target_fd[i]);
1170
        }
1171

    
1172
        cmsg = CMSG_NXTHDR(msgh, cmsg);
1173
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1174
    }
1175
    unlock_user(target_cmsg, target_cmsg_addr, 0);
1176
 the_end:
1177
    msgh->msg_controllen = space;
1178
    return 0;
1179
}
1180

    
1181
/* ??? Should this also swap msgh->name?  */
1182
static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
1183
                                           struct msghdr *msgh)
1184
{
1185
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1186
    abi_long msg_controllen;
1187
    abi_ulong target_cmsg_addr;
1188
    struct target_cmsghdr *target_cmsg;
1189
    socklen_t space = 0;
1190

    
1191
    msg_controllen = tswapl(target_msgh->msg_controllen);
1192
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1193
        goto the_end;
1194
    target_cmsg_addr = tswapl(target_msgh->msg_control);
1195
    target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
1196
    if (!target_cmsg)
1197
        return -TARGET_EFAULT;
1198

    
1199
    while (cmsg && target_cmsg) {
1200
        void *data = CMSG_DATA(cmsg);
1201
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
1202

    
1203
        int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
1204

    
1205
        space += TARGET_CMSG_SPACE(len);
1206
        if (space > msg_controllen) {
1207
            space -= TARGET_CMSG_SPACE(len);
1208
            gemu_log("Target cmsg overflow\n");
1209
            break;
1210
        }
1211

    
1212
        target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
1213
        target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
1214
        target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
1215

    
1216
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1217
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1218
            memcpy(target_data, data, len);
1219
        } else {
1220
            int *fd = (int *)data;
1221
            int *target_fd = (int *)target_data;
1222
            int i, numfds = len / sizeof(int);
1223

    
1224
            for (i = 0; i < numfds; i++)
1225
                target_fd[i] = tswap32(fd[i]);
1226
        }
1227

    
1228
        cmsg = CMSG_NXTHDR(msgh, cmsg);
1229
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1230
    }
1231
    unlock_user(target_cmsg, target_cmsg_addr, space);
1232
 the_end:
1233
    target_msgh->msg_controllen = tswapl(space);
1234
    return 0;
1235
}
1236

    
1237
/* do_setsockopt() Must return target values and target errnos. */
1238
static abi_long do_setsockopt(int sockfd, int level, int optname,
1239
                              abi_ulong optval_addr, socklen_t optlen)
1240
{
1241
    abi_long ret;
1242
    int val;
1243
    struct ip_mreqn *ip_mreq;
1244
    struct ip_mreq_source *ip_mreq_source;
1245

    
1246
    switch(level) {
1247
    case SOL_TCP:
1248
        /* TCP options all take an 'int' value.  */
1249
        if (optlen < sizeof(uint32_t))
1250
            return -TARGET_EINVAL;
1251

    
1252
        if (get_user_u32(val, optval_addr))
1253
            return -TARGET_EFAULT;
1254
        ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1255
        break;
1256
    case SOL_IP:
1257
        switch(optname) {
1258
        case IP_TOS:
1259
        case IP_TTL:
1260
        case IP_HDRINCL:
1261
        case IP_ROUTER_ALERT:
1262
        case IP_RECVOPTS:
1263
        case IP_RETOPTS:
1264
        case IP_PKTINFO:
1265
        case IP_MTU_DISCOVER:
1266
        case IP_RECVERR:
1267
        case IP_RECVTOS:
1268
#ifdef IP_FREEBIND
1269
        case IP_FREEBIND:
1270
#endif
1271
        case IP_MULTICAST_TTL:
1272
        case IP_MULTICAST_LOOP:
1273
            val = 0;
1274
            if (optlen >= sizeof(uint32_t)) {
1275
                if (get_user_u32(val, optval_addr))
1276
                    return -TARGET_EFAULT;
1277
            } else if (optlen >= 1) {
1278
                if (get_user_u8(val, optval_addr))
1279
                    return -TARGET_EFAULT;
1280
            }
1281
            ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1282
            break;
1283
        case IP_ADD_MEMBERSHIP:
1284
        case IP_DROP_MEMBERSHIP:
1285
            if (optlen < sizeof (struct target_ip_mreq) ||
1286
                optlen > sizeof (struct target_ip_mreqn))
1287
                return -TARGET_EINVAL;
1288

    
1289
            ip_mreq = (struct ip_mreqn *) alloca(optlen);
1290
            target_to_host_ip_mreq(ip_mreq, optval_addr, optlen);
1291
            ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq, optlen));
1292
            break;
1293

    
1294
        case IP_BLOCK_SOURCE:
1295
        case IP_UNBLOCK_SOURCE:
1296
        case IP_ADD_SOURCE_MEMBERSHIP:
1297
        case IP_DROP_SOURCE_MEMBERSHIP:
1298
            if (optlen != sizeof (struct target_ip_mreq_source))
1299
                return -TARGET_EINVAL;
1300

    
1301
            ip_mreq_source = lock_user(VERIFY_READ, optval_addr, optlen, 1);
1302
            ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq_source, optlen));
1303
            unlock_user (ip_mreq_source, optval_addr, 0);
1304
            break;
1305

    
1306
        default:
1307
            goto unimplemented;
1308
        }
1309
        break;
1310
    case TARGET_SOL_SOCKET:
1311
        switch (optname) {
1312
            /* Options with 'int' argument.  */
1313
        case TARGET_SO_DEBUG:
1314
                optname = SO_DEBUG;
1315
                break;
1316
        case TARGET_SO_REUSEADDR:
1317
                optname = SO_REUSEADDR;
1318
                break;
1319
        case TARGET_SO_TYPE:
1320
                optname = SO_TYPE;
1321
                break;
1322
        case TARGET_SO_ERROR:
1323
                optname = SO_ERROR;
1324
                break;
1325
        case TARGET_SO_DONTROUTE:
1326
                optname = SO_DONTROUTE;
1327
                break;
1328
        case TARGET_SO_BROADCAST:
1329
                optname = SO_BROADCAST;
1330
                break;
1331
        case TARGET_SO_SNDBUF:
1332
                optname = SO_SNDBUF;
1333
                break;
1334
        case TARGET_SO_RCVBUF:
1335
                optname = SO_RCVBUF;
1336
                break;
1337
        case TARGET_SO_KEEPALIVE:
1338
                optname = SO_KEEPALIVE;
1339
                break;
1340
        case TARGET_SO_OOBINLINE:
1341
                optname = SO_OOBINLINE;
1342
                break;
1343
        case TARGET_SO_NO_CHECK:
1344
                optname = SO_NO_CHECK;
1345
                break;
1346
        case TARGET_SO_PRIORITY:
1347
                optname = SO_PRIORITY;
1348
                break;
1349
#ifdef SO_BSDCOMPAT
1350
        case TARGET_SO_BSDCOMPAT:
1351
                optname = SO_BSDCOMPAT;
1352
                break;
1353
#endif
1354
        case TARGET_SO_PASSCRED:
1355
                optname = SO_PASSCRED;
1356
                break;
1357
        case TARGET_SO_TIMESTAMP:
1358
                optname = SO_TIMESTAMP;
1359
                break;
1360
        case TARGET_SO_RCVLOWAT:
1361
                optname = SO_RCVLOWAT;
1362
                break;
1363
        case TARGET_SO_RCVTIMEO:
1364
                optname = SO_RCVTIMEO;
1365
                break;
1366
        case TARGET_SO_SNDTIMEO:
1367
                optname = SO_SNDTIMEO;
1368
                break;
1369
            break;
1370
        default:
1371
            goto unimplemented;
1372
        }
1373
        if (optlen < sizeof(uint32_t))
1374
            return -TARGET_EINVAL;
1375

    
1376
        if (get_user_u32(val, optval_addr))
1377
            return -TARGET_EFAULT;
1378
        ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
1379
        break;
1380
    default:
1381
    unimplemented:
1382
        gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
1383
        ret = -TARGET_ENOPROTOOPT;
1384
    }
1385
    return ret;
1386
}
1387

    
1388
/* do_getsockopt() Must return target values and target errnos. */
1389
static abi_long do_getsockopt(int sockfd, int level, int optname,
1390
                              abi_ulong optval_addr, abi_ulong optlen)
1391
{
1392
    abi_long ret;
1393
    int len, val;
1394
    socklen_t lv;
1395

    
1396
    switch(level) {
1397
    case TARGET_SOL_SOCKET:
1398
        level = SOL_SOCKET;
1399
        switch (optname) {
1400
        /* These don't just return a single integer */
1401
        case TARGET_SO_LINGER:
1402
        case TARGET_SO_RCVTIMEO:
1403
        case TARGET_SO_SNDTIMEO:
1404
        case TARGET_SO_PEERCRED:
1405
        case TARGET_SO_PEERNAME:
1406
            goto unimplemented;
1407
        /* Options with 'int' argument.  */
1408
        case TARGET_SO_DEBUG:
1409
            optname = SO_DEBUG;
1410
            goto int_case;
1411
        case TARGET_SO_REUSEADDR:
1412
            optname = SO_REUSEADDR;
1413
            goto int_case;
1414
        case TARGET_SO_TYPE:
1415
            optname = SO_TYPE;
1416
            goto int_case;
1417
        case TARGET_SO_ERROR:
1418
            optname = SO_ERROR;
1419
            goto int_case;
1420
        case TARGET_SO_DONTROUTE:
1421
            optname = SO_DONTROUTE;
1422
            goto int_case;
1423
        case TARGET_SO_BROADCAST:
1424
            optname = SO_BROADCAST;
1425
            goto int_case;
1426
        case TARGET_SO_SNDBUF:
1427
            optname = SO_SNDBUF;
1428
            goto int_case;
1429
        case TARGET_SO_RCVBUF:
1430
            optname = SO_RCVBUF;
1431
            goto int_case;
1432
        case TARGET_SO_KEEPALIVE:
1433
            optname = SO_KEEPALIVE;
1434
            goto int_case;
1435
        case TARGET_SO_OOBINLINE:
1436
            optname = SO_OOBINLINE;
1437
            goto int_case;
1438
        case TARGET_SO_NO_CHECK:
1439
            optname = SO_NO_CHECK;
1440
            goto int_case;
1441
        case TARGET_SO_PRIORITY:
1442
            optname = SO_PRIORITY;
1443
            goto int_case;
1444
#ifdef SO_BSDCOMPAT
1445
        case TARGET_SO_BSDCOMPAT:
1446
            optname = SO_BSDCOMPAT;
1447
            goto int_case;
1448
#endif
1449
        case TARGET_SO_PASSCRED:
1450
            optname = SO_PASSCRED;
1451
            goto int_case;
1452
        case TARGET_SO_TIMESTAMP:
1453
            optname = SO_TIMESTAMP;
1454
            goto int_case;
1455
        case TARGET_SO_RCVLOWAT:
1456
            optname = SO_RCVLOWAT;
1457
            goto int_case;
1458
        default:
1459
            goto int_case;
1460
        }
1461
        break;
1462
    case SOL_TCP:
1463
        /* TCP options all take an 'int' value.  */
1464
    int_case:
1465
        if (get_user_u32(len, optlen))
1466
            return -TARGET_EFAULT;
1467
        if (len < 0)
1468
            return -TARGET_EINVAL;
1469
        lv = sizeof(lv);
1470
        ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1471
        if (ret < 0)
1472
            return ret;
1473
        if (len > lv)
1474
            len = lv;
1475
        if (len == 4) {
1476
            if (put_user_u32(val, optval_addr))
1477
                return -TARGET_EFAULT;
1478
        } else {
1479
            if (put_user_u8(val, optval_addr))
1480
                return -TARGET_EFAULT;
1481
        }
1482
        if (put_user_u32(len, optlen))
1483
            return -TARGET_EFAULT;
1484
        break;
1485
    case SOL_IP:
1486
        switch(optname) {
1487
        case IP_TOS:
1488
        case IP_TTL:
1489
        case IP_HDRINCL:
1490
        case IP_ROUTER_ALERT:
1491
        case IP_RECVOPTS:
1492
        case IP_RETOPTS:
1493
        case IP_PKTINFO:
1494
        case IP_MTU_DISCOVER:
1495
        case IP_RECVERR:
1496
        case IP_RECVTOS:
1497
#ifdef IP_FREEBIND
1498
        case IP_FREEBIND:
1499
#endif
1500
        case IP_MULTICAST_TTL:
1501
        case IP_MULTICAST_LOOP:
1502
            if (get_user_u32(len, optlen))
1503
                return -TARGET_EFAULT;
1504
            if (len < 0)
1505
                return -TARGET_EINVAL;
1506
            lv = sizeof(lv);
1507
            ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1508
            if (ret < 0)
1509
                return ret;
1510
            if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
1511
                len = 1;
1512
                if (put_user_u32(len, optlen)
1513
                    || put_user_u8(val, optval_addr))
1514
                    return -TARGET_EFAULT;
1515
            } else {
1516
                if (len > sizeof(int))
1517
                    len = sizeof(int);
1518
                if (put_user_u32(len, optlen)
1519
                    || put_user_u32(val, optval_addr))
1520
                    return -TARGET_EFAULT;
1521
            }
1522
            break;
1523
        default:
1524
            ret = -TARGET_ENOPROTOOPT;
1525
            break;
1526
        }
1527
        break;
1528
    default:
1529
    unimplemented:
1530
        gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1531
                 level, optname);
1532
        ret = -TARGET_EOPNOTSUPP;
1533
        break;
1534
    }
1535
    return ret;
1536
}
1537

    
1538
/* FIXME
1539
 * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1540
 * other lock functions have a return code of 0 for failure.
1541
 */
1542
static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1543
                           int count, int copy)
1544
{
1545
    struct target_iovec *target_vec;
1546
    abi_ulong base;
1547
    int i;
1548

    
1549
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1550
    if (!target_vec)
1551
        return -TARGET_EFAULT;
1552
    for(i = 0;i < count; i++) {
1553
        base = tswapl(target_vec[i].iov_base);
1554
        vec[i].iov_len = tswapl(target_vec[i].iov_len);
1555
        if (vec[i].iov_len != 0) {
1556
            vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
1557
            /* Don't check lock_user return value. We must call writev even
1558
               if a element has invalid base address. */
1559
        } else {
1560
            /* zero length pointer is ignored */
1561
            vec[i].iov_base = NULL;
1562
        }
1563
    }
1564
    unlock_user (target_vec, target_addr, 0);
1565
    return 0;
1566
}
1567

    
1568
static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1569
                             int count, int copy)
1570
{
1571
    struct target_iovec *target_vec;
1572
    abi_ulong base;
1573
    int i;
1574

    
1575
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1576
    if (!target_vec)
1577
        return -TARGET_EFAULT;
1578
    for(i = 0;i < count; i++) {
1579
        if (target_vec[i].iov_base) {
1580
            base = tswapl(target_vec[i].iov_base);
1581
            unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1582
        }
1583
    }
1584
    unlock_user (target_vec, target_addr, 0);
1585

    
1586
    return 0;
1587
}
1588

    
1589
/* do_socket() Must return target values and target errnos. */
1590
static abi_long do_socket(int domain, int type, int protocol)
1591
{
1592
#if defined(TARGET_MIPS)
1593
    switch(type) {
1594
    case TARGET_SOCK_DGRAM:
1595
        type = SOCK_DGRAM;
1596
        break;
1597
    case TARGET_SOCK_STREAM:
1598
        type = SOCK_STREAM;
1599
        break;
1600
    case TARGET_SOCK_RAW:
1601
        type = SOCK_RAW;
1602
        break;
1603
    case TARGET_SOCK_RDM:
1604
        type = SOCK_RDM;
1605
        break;
1606
    case TARGET_SOCK_SEQPACKET:
1607
        type = SOCK_SEQPACKET;
1608
        break;
1609
    case TARGET_SOCK_PACKET:
1610
        type = SOCK_PACKET;
1611
        break;
1612
    }
1613
#endif
1614
    if (domain == PF_NETLINK)
1615
        return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1616
    return get_errno(socket(domain, type, protocol));
1617
}
1618

    
1619
/* do_bind() Must return target values and target errnos. */
1620
static abi_long do_bind(int sockfd, abi_ulong target_addr,
1621
                        socklen_t addrlen)
1622
{
1623
    void *addr;
1624
    abi_long ret;
1625

    
1626
    if ((int)addrlen < 0) {
1627
        return -TARGET_EINVAL;
1628
    }
1629

    
1630
    addr = alloca(addrlen+1);
1631

    
1632
    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1633
    if (ret)
1634
        return ret;
1635

    
1636
    return get_errno(bind(sockfd, addr, addrlen));
1637
}
1638

    
1639
/* do_connect() Must return target values and target errnos. */
1640
static abi_long do_connect(int sockfd, abi_ulong target_addr,
1641
                           socklen_t addrlen)
1642
{
1643
    void *addr;
1644
    abi_long ret;
1645

    
1646
    if ((int)addrlen < 0) {
1647
        return -TARGET_EINVAL;
1648
    }
1649

    
1650
    addr = alloca(addrlen);
1651

    
1652
    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1653
    if (ret)
1654
        return ret;
1655

    
1656
    return get_errno(connect(sockfd, addr, addrlen));
1657
}
1658

    
1659
/* do_sendrecvmsg() Must return target values and target errnos. */
1660
static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1661
                               int flags, int send)
1662
{
1663
    abi_long ret, len;
1664
    struct target_msghdr *msgp;
1665
    struct msghdr msg;
1666
    int count;
1667
    struct iovec *vec;
1668
    abi_ulong target_vec;
1669

    
1670
    /* FIXME */
1671
    if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1672
                          msgp,
1673
                          target_msg,
1674
                          send ? 1 : 0))
1675
        return -TARGET_EFAULT;
1676
    if (msgp->msg_name) {
1677
        msg.msg_namelen = tswap32(msgp->msg_namelen);
1678
        msg.msg_name = alloca(msg.msg_namelen);
1679
        ret = target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
1680
                                msg.msg_namelen);
1681
        if (ret) {
1682
            unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1683
            return ret;
1684
        }
1685
    } else {
1686
        msg.msg_name = NULL;
1687
        msg.msg_namelen = 0;
1688
    }
1689
    msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
1690
    msg.msg_control = alloca(msg.msg_controllen);
1691
    msg.msg_flags = tswap32(msgp->msg_flags);
1692

    
1693
    count = tswapl(msgp->msg_iovlen);
1694
    vec = alloca(count * sizeof(struct iovec));
1695
    target_vec = tswapl(msgp->msg_iov);
1696
    lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1697
    msg.msg_iovlen = count;
1698
    msg.msg_iov = vec;
1699

    
1700
    if (send) {
1701
        ret = target_to_host_cmsg(&msg, msgp);
1702
        if (ret == 0)
1703
            ret = get_errno(sendmsg(fd, &msg, flags));
1704
    } else {
1705
        ret = get_errno(recvmsg(fd, &msg, flags));
1706
        if (!is_error(ret)) {
1707
            len = ret;
1708
            ret = host_to_target_cmsg(msgp, &msg);
1709
            if (!is_error(ret))
1710
                ret = len;
1711
        }
1712
    }
1713
    unlock_iovec(vec, target_vec, count, !send);
1714
    unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1715
    return ret;
1716
}
1717

    
1718
/* do_accept() Must return target values and target errnos. */
1719
static abi_long do_accept(int fd, abi_ulong target_addr,
1720
                          abi_ulong target_addrlen_addr)
1721
{
1722
    socklen_t addrlen;
1723
    void *addr;
1724
    abi_long ret;
1725

    
1726
    if (target_addr == 0)
1727
       return get_errno(accept(fd, NULL, NULL));
1728

    
1729
    /* linux returns EINVAL if addrlen pointer is invalid */
1730
    if (get_user_u32(addrlen, target_addrlen_addr))
1731
        return -TARGET_EINVAL;
1732

    
1733
    if ((int)addrlen < 0) {
1734
        return -TARGET_EINVAL;
1735
    }
1736

    
1737
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1738
        return -TARGET_EINVAL;
1739

    
1740
    addr = alloca(addrlen);
1741

    
1742
    ret = get_errno(accept(fd, addr, &addrlen));
1743
    if (!is_error(ret)) {
1744
        host_to_target_sockaddr(target_addr, addr, addrlen);
1745
        if (put_user_u32(addrlen, target_addrlen_addr))
1746
            ret = -TARGET_EFAULT;
1747
    }
1748
    return ret;
1749
}
1750

    
1751
/* do_getpeername() Must return target values and target errnos. */
1752
static abi_long do_getpeername(int fd, abi_ulong target_addr,
1753
                               abi_ulong target_addrlen_addr)
1754
{
1755
    socklen_t addrlen;
1756
    void *addr;
1757
    abi_long ret;
1758

    
1759
    if (get_user_u32(addrlen, target_addrlen_addr))
1760
        return -TARGET_EFAULT;
1761

    
1762
    if ((int)addrlen < 0) {
1763
        return -TARGET_EINVAL;
1764
    }
1765

    
1766
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1767
        return -TARGET_EFAULT;
1768

    
1769
    addr = alloca(addrlen);
1770

    
1771
    ret = get_errno(getpeername(fd, addr, &addrlen));
1772
    if (!is_error(ret)) {
1773
        host_to_target_sockaddr(target_addr, addr, addrlen);
1774
        if (put_user_u32(addrlen, target_addrlen_addr))
1775
            ret = -TARGET_EFAULT;
1776
    }
1777
    return ret;
1778
}
1779

    
1780
/* do_getsockname() Must return target values and target errnos. */
1781
static abi_long do_getsockname(int fd, abi_ulong target_addr,
1782
                               abi_ulong target_addrlen_addr)
1783
{
1784
    socklen_t addrlen;
1785
    void *addr;
1786
    abi_long ret;
1787

    
1788
    if (get_user_u32(addrlen, target_addrlen_addr))
1789
        return -TARGET_EFAULT;
1790

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

    
1795
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1796
        return -TARGET_EFAULT;
1797

    
1798
    addr = alloca(addrlen);
1799

    
1800
    ret = get_errno(getsockname(fd, addr, &addrlen));
1801
    if (!is_error(ret)) {
1802
        host_to_target_sockaddr(target_addr, addr, addrlen);
1803
        if (put_user_u32(addrlen, target_addrlen_addr))
1804
            ret = -TARGET_EFAULT;
1805
    }
1806
    return ret;
1807
}
1808

    
1809
/* do_socketpair() Must return target values and target errnos. */
1810
static abi_long do_socketpair(int domain, int type, int protocol,
1811
                              abi_ulong target_tab_addr)
1812
{
1813
    int tab[2];
1814
    abi_long ret;
1815

    
1816
    ret = get_errno(socketpair(domain, type, protocol, tab));
1817
    if (!is_error(ret)) {
1818
        if (put_user_s32(tab[0], target_tab_addr)
1819
            || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1820
            ret = -TARGET_EFAULT;
1821
    }
1822
    return ret;
1823
}
1824

    
1825
/* do_sendto() Must return target values and target errnos. */
1826
static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
1827
                          abi_ulong target_addr, socklen_t addrlen)
1828
{
1829
    void *addr;
1830
    void *host_msg;
1831
    abi_long ret;
1832

    
1833
    if ((int)addrlen < 0) {
1834
        return -TARGET_EINVAL;
1835
    }
1836

    
1837
    host_msg = lock_user(VERIFY_READ, msg, len, 1);
1838
    if (!host_msg)
1839
        return -TARGET_EFAULT;
1840
    if (target_addr) {
1841
        addr = alloca(addrlen);
1842
        ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1843
        if (ret) {
1844
            unlock_user(host_msg, msg, 0);
1845
            return ret;
1846
        }
1847
        ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
1848
    } else {
1849
        ret = get_errno(send(fd, host_msg, len, flags));
1850
    }
1851
    unlock_user(host_msg, msg, 0);
1852
    return ret;
1853
}
1854

    
1855
/* do_recvfrom() Must return target values and target errnos. */
1856
static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
1857
                            abi_ulong target_addr,
1858
                            abi_ulong target_addrlen)
1859
{
1860
    socklen_t addrlen;
1861
    void *addr;
1862
    void *host_msg;
1863
    abi_long ret;
1864

    
1865
    host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
1866
    if (!host_msg)
1867
        return -TARGET_EFAULT;
1868
    if (target_addr) {
1869
        if (get_user_u32(addrlen, target_addrlen)) {
1870
            ret = -TARGET_EFAULT;
1871
            goto fail;
1872
        }
1873
        if ((int)addrlen < 0) {
1874
            ret = -TARGET_EINVAL;
1875
            goto fail;
1876
        }
1877
        addr = alloca(addrlen);
1878
        ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
1879
    } else {
1880
        addr = NULL; /* To keep compiler quiet.  */
1881
        ret = get_errno(recv(fd, host_msg, len, flags));
1882
    }
1883
    if (!is_error(ret)) {
1884
        if (target_addr) {
1885
            host_to_target_sockaddr(target_addr, addr, addrlen);
1886
            if (put_user_u32(addrlen, target_addrlen)) {
1887
                ret = -TARGET_EFAULT;
1888
                goto fail;
1889
            }
1890
        }
1891
        unlock_user(host_msg, msg, len);
1892
    } else {
1893
fail:
1894
        unlock_user(host_msg, msg, 0);
1895
    }
1896
    return ret;
1897
}
1898

    
1899
#ifdef TARGET_NR_socketcall
1900
/* do_socketcall() Must return target values and target errnos. */
1901
static abi_long do_socketcall(int num, abi_ulong vptr)
1902
{
1903
    abi_long ret;
1904
    const int n = sizeof(abi_ulong);
1905

    
1906
    switch(num) {
1907
    case SOCKOP_socket:
1908
        {
1909
            abi_ulong domain, type, protocol;
1910

    
1911
            if (get_user_ual(domain, vptr)
1912
                || get_user_ual(type, vptr + n)
1913
                || get_user_ual(protocol, vptr + 2 * n))
1914
                return -TARGET_EFAULT;
1915

    
1916
            ret = do_socket(domain, type, protocol);
1917
        }
1918
        break;
1919
    case SOCKOP_bind:
1920
        {
1921
            abi_ulong sockfd;
1922
            abi_ulong target_addr;
1923
            socklen_t addrlen;
1924

    
1925
            if (get_user_ual(sockfd, vptr)
1926
                || get_user_ual(target_addr, vptr + n)
1927
                || get_user_ual(addrlen, vptr + 2 * n))
1928
                return -TARGET_EFAULT;
1929

    
1930
            ret = do_bind(sockfd, target_addr, addrlen);
1931
        }
1932
        break;
1933
    case SOCKOP_connect:
1934
        {
1935
            abi_ulong sockfd;
1936
            abi_ulong target_addr;
1937
            socklen_t addrlen;
1938

    
1939
            if (get_user_ual(sockfd, vptr)
1940
                || get_user_ual(target_addr, vptr + n)
1941
                || get_user_ual(addrlen, vptr + 2 * n))
1942
                return -TARGET_EFAULT;
1943

    
1944
            ret = do_connect(sockfd, target_addr, addrlen);
1945
        }
1946
        break;
1947
    case SOCKOP_listen:
1948
        {
1949
            abi_ulong sockfd, backlog;
1950

    
1951
            if (get_user_ual(sockfd, vptr)
1952
                || get_user_ual(backlog, vptr + n))
1953
                return -TARGET_EFAULT;
1954

    
1955
            ret = get_errno(listen(sockfd, backlog));
1956
        }
1957
        break;
1958
    case SOCKOP_accept:
1959
        {
1960
            abi_ulong sockfd;
1961
            abi_ulong target_addr, target_addrlen;
1962

    
1963
            if (get_user_ual(sockfd, vptr)
1964
                || get_user_ual(target_addr, vptr + n)
1965
                || get_user_ual(target_addrlen, vptr + 2 * n))
1966
                return -TARGET_EFAULT;
1967

    
1968
            ret = do_accept(sockfd, target_addr, target_addrlen);
1969
        }
1970
        break;
1971
    case SOCKOP_getsockname:
1972
        {
1973
            abi_ulong sockfd;
1974
            abi_ulong target_addr, target_addrlen;
1975

    
1976
            if (get_user_ual(sockfd, vptr)
1977
                || get_user_ual(target_addr, vptr + n)
1978
                || get_user_ual(target_addrlen, vptr + 2 * n))
1979
                return -TARGET_EFAULT;
1980

    
1981
            ret = do_getsockname(sockfd, target_addr, target_addrlen);
1982
        }
1983
        break;
1984
    case SOCKOP_getpeername:
1985
        {
1986
            abi_ulong sockfd;
1987
            abi_ulong target_addr, target_addrlen;
1988

    
1989
            if (get_user_ual(sockfd, vptr)
1990
                || get_user_ual(target_addr, vptr + n)
1991
                || get_user_ual(target_addrlen, vptr + 2 * n))
1992
                return -TARGET_EFAULT;
1993

    
1994
            ret = do_getpeername(sockfd, target_addr, target_addrlen);
1995
        }
1996
        break;
1997
    case SOCKOP_socketpair:
1998
        {
1999
            abi_ulong domain, type, protocol;
2000
            abi_ulong tab;
2001

    
2002
            if (get_user_ual(domain, vptr)
2003
                || get_user_ual(type, vptr + n)
2004
                || get_user_ual(protocol, vptr + 2 * n)
2005
                || get_user_ual(tab, vptr + 3 * n))
2006
                return -TARGET_EFAULT;
2007

    
2008
            ret = do_socketpair(domain, type, protocol, tab);
2009
        }
2010
        break;
2011
    case SOCKOP_send:
2012
        {
2013
            abi_ulong sockfd;
2014
            abi_ulong msg;
2015
            size_t len;
2016
            abi_ulong flags;
2017

    
2018
            if (get_user_ual(sockfd, vptr)
2019
                || get_user_ual(msg, vptr + n)
2020
                || get_user_ual(len, vptr + 2 * n)
2021
                || get_user_ual(flags, vptr + 3 * n))
2022
                return -TARGET_EFAULT;
2023

    
2024
            ret = do_sendto(sockfd, msg, len, flags, 0, 0);
2025
        }
2026
        break;
2027
    case SOCKOP_recv:
2028
        {
2029
            abi_ulong sockfd;
2030
            abi_ulong msg;
2031
            size_t len;
2032
            abi_ulong flags;
2033

    
2034
            if (get_user_ual(sockfd, vptr)
2035
                || get_user_ual(msg, vptr + n)
2036
                || get_user_ual(len, vptr + 2 * n)
2037
                || get_user_ual(flags, vptr + 3 * n))
2038
                return -TARGET_EFAULT;
2039

    
2040
            ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
2041
        }
2042
        break;
2043
    case SOCKOP_sendto:
2044
        {
2045
            abi_ulong sockfd;
2046
            abi_ulong msg;
2047
            size_t len;
2048
            abi_ulong flags;
2049
            abi_ulong addr;
2050
            socklen_t addrlen;
2051

    
2052
            if (get_user_ual(sockfd, vptr)
2053
                || get_user_ual(msg, vptr + n)
2054
                || get_user_ual(len, vptr + 2 * n)
2055
                || get_user_ual(flags, vptr + 3 * n)
2056
                || get_user_ual(addr, vptr + 4 * n)
2057
                || get_user_ual(addrlen, vptr + 5 * n))
2058
                return -TARGET_EFAULT;
2059

    
2060
            ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
2061
        }
2062
        break;
2063
    case SOCKOP_recvfrom:
2064
        {
2065
            abi_ulong sockfd;
2066
            abi_ulong msg;
2067
            size_t len;
2068
            abi_ulong flags;
2069
            abi_ulong addr;
2070
            socklen_t addrlen;
2071

    
2072
            if (get_user_ual(sockfd, vptr)
2073
                || get_user_ual(msg, vptr + n)
2074
                || get_user_ual(len, vptr + 2 * n)
2075
                || get_user_ual(flags, vptr + 3 * n)
2076
                || get_user_ual(addr, vptr + 4 * n)
2077
                || get_user_ual(addrlen, vptr + 5 * n))
2078
                return -TARGET_EFAULT;
2079

    
2080
            ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
2081
        }
2082
        break;
2083
    case SOCKOP_shutdown:
2084
        {
2085
            abi_ulong sockfd, how;
2086

    
2087
            if (get_user_ual(sockfd, vptr)
2088
                || get_user_ual(how, vptr + n))
2089
                return -TARGET_EFAULT;
2090

    
2091
            ret = get_errno(shutdown(sockfd, how));
2092
        }
2093
        break;
2094
    case SOCKOP_sendmsg:
2095
    case SOCKOP_recvmsg:
2096
        {
2097
            abi_ulong fd;
2098
            abi_ulong target_msg;
2099
            abi_ulong flags;
2100

    
2101
            if (get_user_ual(fd, vptr)
2102
                || get_user_ual(target_msg, vptr + n)
2103
                || get_user_ual(flags, vptr + 2 * n))
2104
                return -TARGET_EFAULT;
2105

    
2106
            ret = do_sendrecvmsg(fd, target_msg, flags,
2107
                                 (num == SOCKOP_sendmsg));
2108
        }
2109
        break;
2110
    case SOCKOP_setsockopt:
2111
        {
2112
            abi_ulong sockfd;
2113
            abi_ulong level;
2114
            abi_ulong optname;
2115
            abi_ulong optval;
2116
            socklen_t optlen;
2117

    
2118
            if (get_user_ual(sockfd, vptr)
2119
                || get_user_ual(level, vptr + n)
2120
                || get_user_ual(optname, vptr + 2 * n)
2121
                || get_user_ual(optval, vptr + 3 * n)
2122
                || get_user_ual(optlen, vptr + 4 * n))
2123
                return -TARGET_EFAULT;
2124

    
2125
            ret = do_setsockopt(sockfd, level, optname, optval, optlen);
2126
        }
2127
        break;
2128
    case SOCKOP_getsockopt:
2129
        {
2130
            abi_ulong sockfd;
2131
            abi_ulong level;
2132
            abi_ulong optname;
2133
            abi_ulong optval;
2134
            socklen_t optlen;
2135

    
2136
            if (get_user_ual(sockfd, vptr)
2137
                || get_user_ual(level, vptr + n)
2138
                || get_user_ual(optname, vptr + 2 * n)
2139
                || get_user_ual(optval, vptr + 3 * n)
2140
                || get_user_ual(optlen, vptr + 4 * n))
2141
                return -TARGET_EFAULT;
2142

    
2143
            ret = do_getsockopt(sockfd, level, optname, optval, optlen);
2144
        }
2145
        break;
2146
    default:
2147
        gemu_log("Unsupported socketcall: %d\n", num);
2148
        ret = -TARGET_ENOSYS;
2149
        break;
2150
    }
2151
    return ret;
2152
}
2153
#endif
2154

    
2155
#define N_SHM_REGIONS        32
2156

    
2157
static struct shm_region {
2158
    abi_ulong        start;
2159
    abi_ulong        size;
2160
} shm_regions[N_SHM_REGIONS];
2161

    
2162
struct target_ipc_perm
2163
{
2164
    abi_long __key;
2165
    abi_ulong uid;
2166
    abi_ulong gid;
2167
    abi_ulong cuid;
2168
    abi_ulong cgid;
2169
    unsigned short int mode;
2170
    unsigned short int __pad1;
2171
    unsigned short int __seq;
2172
    unsigned short int __pad2;
2173
    abi_ulong __unused1;
2174
    abi_ulong __unused2;
2175
};
2176

    
2177
struct target_semid_ds
2178
{
2179
  struct target_ipc_perm sem_perm;
2180
  abi_ulong sem_otime;
2181
  abi_ulong __unused1;
2182
  abi_ulong sem_ctime;
2183
  abi_ulong __unused2;
2184
  abi_ulong sem_nsems;
2185
  abi_ulong __unused3;
2186
  abi_ulong __unused4;
2187
};
2188

    
2189
static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
2190
                                               abi_ulong target_addr)
2191
{
2192
    struct target_ipc_perm *target_ip;
2193
    struct target_semid_ds *target_sd;
2194

    
2195
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2196
        return -TARGET_EFAULT;
2197
    target_ip = &(target_sd->sem_perm);
2198
    host_ip->__key = tswapl(target_ip->__key);
2199
    host_ip->uid = tswapl(target_ip->uid);
2200
    host_ip->gid = tswapl(target_ip->gid);
2201
    host_ip->cuid = tswapl(target_ip->cuid);
2202
    host_ip->cgid = tswapl(target_ip->cgid);
2203
    host_ip->mode = tswapl(target_ip->mode);
2204
    unlock_user_struct(target_sd, target_addr, 0);
2205
    return 0;
2206
}
2207

    
2208
static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
2209
                                               struct ipc_perm *host_ip)
2210
{
2211
    struct target_ipc_perm *target_ip;
2212
    struct target_semid_ds *target_sd;
2213

    
2214
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2215
        return -TARGET_EFAULT;
2216
    target_ip = &(target_sd->sem_perm);
2217
    target_ip->__key = tswapl(host_ip->__key);
2218
    target_ip->uid = tswapl(host_ip->uid);
2219
    target_ip->gid = tswapl(host_ip->gid);
2220
    target_ip->cuid = tswapl(host_ip->cuid);
2221
    target_ip->cgid = tswapl(host_ip->cgid);
2222
    target_ip->mode = tswapl(host_ip->mode);
2223
    unlock_user_struct(target_sd, target_addr, 1);
2224
    return 0;
2225
}
2226

    
2227
static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
2228
                                               abi_ulong target_addr)
2229
{
2230
    struct target_semid_ds *target_sd;
2231

    
2232
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2233
        return -TARGET_EFAULT;
2234
    if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr))
2235
        return -TARGET_EFAULT;
2236
    host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
2237
    host_sd->sem_otime = tswapl(target_sd->sem_otime);
2238
    host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
2239
    unlock_user_struct(target_sd, target_addr, 0);
2240
    return 0;
2241
}
2242

    
2243
static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
2244
                                               struct semid_ds *host_sd)
2245
{
2246
    struct target_semid_ds *target_sd;
2247

    
2248
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2249
        return -TARGET_EFAULT;
2250
    if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
2251
        return -TARGET_EFAULT;;
2252
    target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
2253
    target_sd->sem_otime = tswapl(host_sd->sem_otime);
2254
    target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
2255
    unlock_user_struct(target_sd, target_addr, 1);
2256
    return 0;
2257
}
2258

    
2259
struct target_seminfo {
2260
    int semmap;
2261
    int semmni;
2262
    int semmns;
2263
    int semmnu;
2264
    int semmsl;
2265
    int semopm;
2266
    int semume;
2267
    int semusz;
2268
    int semvmx;
2269
    int semaem;
2270
};
2271

    
2272
static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
2273
                                              struct seminfo *host_seminfo)
2274
{
2275
    struct target_seminfo *target_seminfo;
2276
    if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
2277
        return -TARGET_EFAULT;
2278
    __put_user(host_seminfo->semmap, &target_seminfo->semmap);
2279
    __put_user(host_seminfo->semmni, &target_seminfo->semmni);
2280
    __put_user(host_seminfo->semmns, &target_seminfo->semmns);
2281
    __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
2282
    __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
2283
    __put_user(host_seminfo->semopm, &target_seminfo->semopm);
2284
    __put_user(host_seminfo->semume, &target_seminfo->semume);
2285
    __put_user(host_seminfo->semusz, &target_seminfo->semusz);
2286
    __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
2287
    __put_user(host_seminfo->semaem, &target_seminfo->semaem);
2288
    unlock_user_struct(target_seminfo, target_addr, 1);
2289
    return 0;
2290
}
2291

    
2292
union semun {
2293
        int val;
2294
        struct semid_ds *buf;
2295
        unsigned short *array;
2296
        struct seminfo *__buf;
2297
};
2298

    
2299
union target_semun {
2300
        int val;
2301
        abi_ulong buf;
2302
        abi_ulong array;
2303
        abi_ulong __buf;
2304
};
2305

    
2306
static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
2307
                                               abi_ulong target_addr)
2308
{
2309
    int nsems;
2310
    unsigned short *array;
2311
    union semun semun;
2312
    struct semid_ds semid_ds;
2313
    int i, ret;
2314

    
2315
    semun.buf = &semid_ds;
2316

    
2317
    ret = semctl(semid, 0, IPC_STAT, semun);
2318
    if (ret == -1)
2319
        return get_errno(ret);
2320

    
2321
    nsems = semid_ds.sem_nsems;
2322

    
2323
    *host_array = malloc(nsems*sizeof(unsigned short));
2324
    array = lock_user(VERIFY_READ, target_addr,
2325
                      nsems*sizeof(unsigned short), 1);
2326
    if (!array)
2327
        return -TARGET_EFAULT;
2328

    
2329
    for(i=0; i<nsems; i++) {
2330
        __get_user((*host_array)[i], &array[i]);
2331
    }
2332
    unlock_user(array, target_addr, 0);
2333

    
2334
    return 0;
2335
}
2336

    
2337
static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
2338
                                               unsigned short **host_array)
2339
{
2340
    int nsems;
2341
    unsigned short *array;
2342
    union semun semun;
2343
    struct semid_ds semid_ds;
2344
    int i, ret;
2345

    
2346
    semun.buf = &semid_ds;
2347

    
2348
    ret = semctl(semid, 0, IPC_STAT, semun);
2349
    if (ret == -1)
2350
        return get_errno(ret);
2351

    
2352
    nsems = semid_ds.sem_nsems;
2353

    
2354
    array = lock_user(VERIFY_WRITE, target_addr,
2355
                      nsems*sizeof(unsigned short), 0);
2356
    if (!array)
2357
        return -TARGET_EFAULT;
2358

    
2359
    for(i=0; i<nsems; i++) {
2360
        __put_user((*host_array)[i], &array[i]);
2361
    }
2362
    free(*host_array);
2363
    unlock_user(array, target_addr, 1);
2364

    
2365
    return 0;
2366
}
2367

    
2368
static inline abi_long do_semctl(int semid, int semnum, int cmd,
2369
                                 union target_semun target_su)
2370
{
2371
    union semun arg;
2372
    struct semid_ds dsarg;
2373
    unsigned short *array = NULL;
2374
    struct seminfo seminfo;
2375
    abi_long ret = -TARGET_EINVAL;
2376
    abi_long err;
2377
    cmd &= 0xff;
2378

    
2379
    switch( cmd ) {
2380
        case GETVAL:
2381
        case SETVAL:
2382
            arg.val = tswapl(target_su.val);
2383
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2384
            target_su.val = tswapl(arg.val);
2385
            break;
2386
        case GETALL:
2387
        case SETALL:
2388
            err = target_to_host_semarray(semid, &array, target_su.array);
2389
            if (err)
2390
                return err;
2391
            arg.array = array;
2392
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2393
            err = host_to_target_semarray(semid, target_su.array, &array);
2394
            if (err)
2395
                return err;
2396
            break;
2397
        case IPC_STAT:
2398
        case IPC_SET:
2399
        case SEM_STAT:
2400
            err = target_to_host_semid_ds(&dsarg, target_su.buf);
2401
            if (err)
2402
                return err;
2403
            arg.buf = &dsarg;
2404
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2405
            err = host_to_target_semid_ds(target_su.buf, &dsarg);
2406
            if (err)
2407
                return err;
2408
            break;
2409
        case IPC_INFO:
2410
        case SEM_INFO:
2411
            arg.__buf = &seminfo;
2412
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2413
            err = host_to_target_seminfo(target_su.__buf, &seminfo);
2414
            if (err)
2415
                return err;
2416
            break;
2417
        case IPC_RMID:
2418
        case GETPID:
2419
        case GETNCNT:
2420
        case GETZCNT:
2421
            ret = get_errno(semctl(semid, semnum, cmd, NULL));
2422
            break;
2423
    }
2424

    
2425
    return ret;
2426
}
2427

    
2428
struct target_sembuf {
2429
    unsigned short sem_num;
2430
    short sem_op;
2431
    short sem_flg;
2432
};
2433

    
2434
static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
2435
                                             abi_ulong target_addr,
2436
                                             unsigned nsops)
2437
{
2438
    struct target_sembuf *target_sembuf;
2439
    int i;
2440

    
2441
    target_sembuf = lock_user(VERIFY_READ, target_addr,
2442
                              nsops*sizeof(struct target_sembuf), 1);
2443
    if (!target_sembuf)
2444
        return -TARGET_EFAULT;
2445

    
2446
    for(i=0; i<nsops; i++) {
2447
        __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
2448
        __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
2449
        __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
2450
    }
2451

    
2452
    unlock_user(target_sembuf, target_addr, 0);
2453

    
2454
    return 0;
2455
}
2456

    
2457
static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
2458
{
2459
    struct sembuf sops[nsops];
2460

    
2461
    if (target_to_host_sembuf(sops, ptr, nsops))
2462
        return -TARGET_EFAULT;
2463

    
2464
    return semop(semid, sops, nsops);
2465
}
2466

    
2467
struct target_msqid_ds
2468
{
2469
    struct target_ipc_perm msg_perm;
2470
    abi_ulong msg_stime;
2471
#if TARGET_ABI_BITS == 32
2472
    abi_ulong __unused1;
2473
#endif
2474
    abi_ulong msg_rtime;
2475
#if TARGET_ABI_BITS == 32
2476
    abi_ulong __unused2;
2477
#endif
2478
    abi_ulong msg_ctime;
2479
#if TARGET_ABI_BITS == 32
2480
    abi_ulong __unused3;
2481
#endif
2482
    abi_ulong __msg_cbytes;
2483
    abi_ulong msg_qnum;
2484
    abi_ulong msg_qbytes;
2485
    abi_ulong msg_lspid;
2486
    abi_ulong msg_lrpid;
2487
    abi_ulong __unused4;
2488
    abi_ulong __unused5;
2489
};
2490

    
2491
static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
2492
                                               abi_ulong target_addr)
2493
{
2494
    struct target_msqid_ds *target_md;
2495

    
2496
    if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
2497
        return -TARGET_EFAULT;
2498
    if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
2499
        return -TARGET_EFAULT;
2500
    host_md->msg_stime = tswapl(target_md->msg_stime);
2501
    host_md->msg_rtime = tswapl(target_md->msg_rtime);
2502
    host_md->msg_ctime = tswapl(target_md->msg_ctime);
2503
    host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
2504
    host_md->msg_qnum = tswapl(target_md->msg_qnum);
2505
    host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
2506
    host_md->msg_lspid = tswapl(target_md->msg_lspid);
2507
    host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
2508
    unlock_user_struct(target_md, target_addr, 0);
2509
    return 0;
2510
}
2511

    
2512
static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
2513
                                               struct msqid_ds *host_md)
2514
{
2515
    struct target_msqid_ds *target_md;
2516

    
2517
    if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
2518
        return -TARGET_EFAULT;
2519
    if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
2520
        return -TARGET_EFAULT;
2521
    target_md->msg_stime = tswapl(host_md->msg_stime);
2522
    target_md->msg_rtime = tswapl(host_md->msg_rtime);
2523
    target_md->msg_ctime = tswapl(host_md->msg_ctime);
2524
    target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
2525
    target_md->msg_qnum = tswapl(host_md->msg_qnum);
2526
    target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
2527
    target_md->msg_lspid = tswapl(host_md->msg_lspid);
2528
    target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
2529
    unlock_user_struct(target_md, target_addr, 1);
2530
    return 0;
2531
}
2532

    
2533
struct target_msginfo {
2534
    int msgpool;
2535
    int msgmap;
2536
    int msgmax;
2537
    int msgmnb;
2538
    int msgmni;
2539
    int msgssz;
2540
    int msgtql;
2541
    unsigned short int msgseg;
2542
};
2543

    
2544
static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
2545
                                              struct msginfo *host_msginfo)
2546
{
2547
    struct target_msginfo *target_msginfo;
2548
    if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
2549
        return -TARGET_EFAULT;
2550
    __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
2551
    __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
2552
    __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
2553
    __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
2554
    __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
2555
    __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
2556
    __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
2557
    __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
2558
    unlock_user_struct(target_msginfo, target_addr, 1);
2559
    return 0;
2560
}
2561

    
2562
static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
2563
{
2564
    struct msqid_ds dsarg;
2565
    struct msginfo msginfo;
2566
    abi_long ret = -TARGET_EINVAL;
2567

    
2568
    cmd &= 0xff;
2569

    
2570
    switch (cmd) {
2571
    case IPC_STAT:
2572
    case IPC_SET:
2573
    case MSG_STAT:
2574
        if (target_to_host_msqid_ds(&dsarg,ptr))
2575
            return -TARGET_EFAULT;
2576
        ret = get_errno(msgctl(msgid, cmd, &dsarg));
2577
        if (host_to_target_msqid_ds(ptr,&dsarg))
2578
            return -TARGET_EFAULT;
2579
        break;
2580
    case IPC_RMID:
2581
        ret = get_errno(msgctl(msgid, cmd, NULL));
2582
        break;
2583
    case IPC_INFO:
2584
    case MSG_INFO:
2585
        ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
2586
        if (host_to_target_msginfo(ptr, &msginfo))
2587
            return -TARGET_EFAULT;
2588
        break;
2589
    }
2590

    
2591
    return ret;
2592
}
2593

    
2594
struct target_msgbuf {
2595
    abi_long mtype;
2596
    char        mtext[1];
2597
};
2598

    
2599
static inline abi_long do_msgsnd(int msqid, abi_long msgp,
2600
                                 unsigned int msgsz, int msgflg)
2601
{
2602
    struct target_msgbuf *target_mb;
2603
    struct msgbuf *host_mb;
2604
    abi_long ret = 0;
2605

    
2606
    if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
2607
        return -TARGET_EFAULT;
2608
    host_mb = malloc(msgsz+sizeof(long));
2609
    host_mb->mtype = (abi_long) tswapl(target_mb->mtype);
2610
    memcpy(host_mb->mtext, target_mb->mtext, msgsz);
2611
    ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
2612
    free(host_mb);
2613
    unlock_user_struct(target_mb, msgp, 0);
2614

    
2615
    return ret;
2616
}
2617

    
2618
static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2619
                                 unsigned int msgsz, abi_long msgtyp,
2620
                                 int msgflg)
2621
{
2622
    struct target_msgbuf *target_mb;
2623
    char *target_mtext;
2624
    struct msgbuf *host_mb;
2625
    abi_long ret = 0;
2626

    
2627
    if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2628
        return -TARGET_EFAULT;
2629

    
2630
    host_mb = malloc(msgsz+sizeof(long));
2631
    ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapl(msgtyp), msgflg));
2632

    
2633
    if (ret > 0) {
2634
        abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2635
        target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2636
        if (!target_mtext) {
2637
            ret = -TARGET_EFAULT;
2638
            goto end;
2639
        }
2640
        memcpy(target_mb->mtext, host_mb->mtext, ret);
2641
        unlock_user(target_mtext, target_mtext_addr, ret);
2642
    }
2643

    
2644
    target_mb->mtype = tswapl(host_mb->mtype);
2645
    free(host_mb);
2646

    
2647
end:
2648
    if (target_mb)
2649
        unlock_user_struct(target_mb, msgp, 1);
2650
    return ret;
2651
}
2652

    
2653
struct target_shmid_ds
2654
{
2655
    struct target_ipc_perm shm_perm;
2656
    abi_ulong shm_segsz;
2657
    abi_ulong shm_atime;
2658
#if TARGET_ABI_BITS == 32
2659
    abi_ulong __unused1;
2660
#endif
2661
    abi_ulong shm_dtime;
2662
#if TARGET_ABI_BITS == 32
2663
    abi_ulong __unused2;
2664
#endif
2665
    abi_ulong shm_ctime;
2666
#if TARGET_ABI_BITS == 32
2667
    abi_ulong __unused3;
2668
#endif
2669
    int shm_cpid;
2670
    int shm_lpid;
2671
    abi_ulong shm_nattch;
2672
    unsigned long int __unused4;
2673
    unsigned long int __unused5;
2674
};
2675

    
2676
static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
2677
                                               abi_ulong target_addr)
2678
{
2679
    struct target_shmid_ds *target_sd;
2680

    
2681
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2682
        return -TARGET_EFAULT;
2683
    if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr))
2684
        return -TARGET_EFAULT;
2685
    __get_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2686
    __get_user(host_sd->shm_atime, &target_sd->shm_atime);
2687
    __get_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2688
    __get_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2689
    __get_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2690
    __get_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2691
    __get_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2692
    unlock_user_struct(target_sd, target_addr, 0);
2693
    return 0;
2694
}
2695

    
2696
static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
2697
                                               struct shmid_ds *host_sd)
2698
{
2699
    struct target_shmid_ds *target_sd;
2700

    
2701
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2702
        return -TARGET_EFAULT;
2703
    if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm)))
2704
        return -TARGET_EFAULT;
2705
    __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2706
    __put_user(host_sd->shm_atime, &target_sd->shm_atime);
2707
    __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2708
    __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2709
    __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2710
    __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2711
    __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2712
    unlock_user_struct(target_sd, target_addr, 1);
2713
    return 0;
2714
}
2715

    
2716
struct  target_shminfo {
2717
    abi_ulong shmmax;
2718
    abi_ulong shmmin;
2719
    abi_ulong shmmni;
2720
    abi_ulong shmseg;
2721
    abi_ulong shmall;
2722
};
2723

    
2724
static inline abi_long host_to_target_shminfo(abi_ulong target_addr,
2725
                                              struct shminfo *host_shminfo)
2726
{
2727
    struct target_shminfo *target_shminfo;
2728
    if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0))
2729
        return -TARGET_EFAULT;
2730
    __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
2731
    __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
2732
    __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
2733
    __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
2734
    __put_user(host_shminfo->shmall, &target_shminfo->shmall);
2735
    unlock_user_struct(target_shminfo, target_addr, 1);
2736
    return 0;
2737
}
2738

    
2739
struct target_shm_info {
2740
    int used_ids;
2741
    abi_ulong shm_tot;
2742
    abi_ulong shm_rss;
2743
    abi_ulong shm_swp;
2744
    abi_ulong swap_attempts;
2745
    abi_ulong swap_successes;
2746
};
2747

    
2748
static inline abi_long host_to_target_shm_info(abi_ulong target_addr,
2749
                                               struct shm_info *host_shm_info)
2750
{
2751
    struct target_shm_info *target_shm_info;
2752
    if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0))
2753
        return -TARGET_EFAULT;
2754
    __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
2755
    __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
2756
    __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
2757
    __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
2758
    __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts);
2759
    __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes);
2760
    unlock_user_struct(target_shm_info, target_addr, 1);
2761
    return 0;
2762
}
2763

    
2764
static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
2765
{
2766
    struct shmid_ds dsarg;
2767
    struct shminfo shminfo;
2768
    struct shm_info shm_info;
2769
    abi_long ret = -TARGET_EINVAL;
2770

    
2771
    cmd &= 0xff;
2772

    
2773
    switch(cmd) {
2774
    case IPC_STAT:
2775
    case IPC_SET:
2776
    case SHM_STAT:
2777
        if (target_to_host_shmid_ds(&dsarg, buf))
2778
            return -TARGET_EFAULT;
2779
        ret = get_errno(shmctl(shmid, cmd, &dsarg));
2780
        if (host_to_target_shmid_ds(buf, &dsarg))
2781
            return -TARGET_EFAULT;
2782
        break;
2783
    case IPC_INFO:
2784
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
2785
        if (host_to_target_shminfo(buf, &shminfo))
2786
            return -TARGET_EFAULT;
2787
        break;
2788
    case SHM_INFO:
2789
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
2790
        if (host_to_target_shm_info(buf, &shm_info))
2791
            return -TARGET_EFAULT;
2792
        break;
2793
    case IPC_RMID:
2794
    case SHM_LOCK:
2795
    case SHM_UNLOCK:
2796
        ret = get_errno(shmctl(shmid, cmd, NULL));
2797
        break;
2798
    }
2799

    
2800
    return ret;
2801
}
2802

    
2803
static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
2804
{
2805
    abi_long raddr;
2806
    void *host_raddr;
2807
    struct shmid_ds shm_info;
2808
    int i,ret;
2809

    
2810
    /* find out the length of the shared memory segment */
2811
    ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
2812
    if (is_error(ret)) {
2813
        /* can't get length, bail out */
2814
        return ret;
2815
    }
2816

    
2817
    mmap_lock();
2818

    
2819
    if (shmaddr)
2820
        host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
2821
    else {
2822
        abi_ulong mmap_start;
2823

    
2824
        mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
2825

    
2826
        if (mmap_start == -1) {
2827
            errno = ENOMEM;
2828
            host_raddr = (void *)-1;
2829
        } else
2830
            host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);
2831
    }
2832

    
2833
    if (host_raddr == (void *)-1) {
2834
        mmap_unlock();
2835
        return get_errno((long)host_raddr);
2836
    }
2837
    raddr=h2g((unsigned long)host_raddr);
2838

    
2839
    page_set_flags(raddr, raddr + shm_info.shm_segsz,
2840
                   PAGE_VALID | PAGE_READ |
2841
                   ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
2842

    
2843
    for (i = 0; i < N_SHM_REGIONS; i++) {
2844
        if (shm_regions[i].start == 0) {
2845
            shm_regions[i].start = raddr;
2846
            shm_regions[i].size = shm_info.shm_segsz;
2847
            break;
2848
        }
2849
    }
2850

    
2851
    mmap_unlock();
2852
    return raddr;
2853

    
2854
}
2855

    
2856
static inline abi_long do_shmdt(abi_ulong shmaddr)
2857
{
2858
    int i;
2859

    
2860
    for (i = 0; i < N_SHM_REGIONS; ++i) {
2861
        if (shm_regions[i].start == shmaddr) {
2862
            shm_regions[i].start = 0;
2863
            page_set_flags(shmaddr, shmaddr + shm_regions[i].size, 0);
2864
            break;
2865
        }
2866
    }
2867

    
2868
    return get_errno(shmdt(g2h(shmaddr)));
2869
}
2870

    
2871
#ifdef TARGET_NR_ipc
2872
/* ??? This only works with linear mappings.  */
2873
/* do_ipc() must return target values and target errnos. */
2874
static abi_long do_ipc(unsigned int call, int first,
2875
                       int second, int third,
2876
                       abi_long ptr, abi_long fifth)
2877
{
2878
    int version;
2879
    abi_long ret = 0;
2880

    
2881
    version = call >> 16;
2882
    call &= 0xffff;
2883

    
2884
    switch (call) {
2885
    case IPCOP_semop:
2886
        ret = do_semop(first, ptr, second);
2887
        break;
2888

    
2889
    case IPCOP_semget:
2890
        ret = get_errno(semget(first, second, third));
2891
        break;
2892

    
2893
    case IPCOP_semctl:
2894
        ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr);
2895
        break;
2896

    
2897
    case IPCOP_msgget:
2898
        ret = get_errno(msgget(first, second));
2899
        break;
2900

    
2901
    case IPCOP_msgsnd:
2902
        ret = do_msgsnd(first, ptr, second, third);
2903
        break;
2904

    
2905
    case IPCOP_msgctl:
2906
        ret = do_msgctl(first, second, ptr);
2907
        break;
2908

    
2909
    case IPCOP_msgrcv:
2910
        switch (version) {
2911
        case 0:
2912
            {
2913
                struct target_ipc_kludge {
2914
                    abi_long msgp;
2915
                    abi_long msgtyp;
2916
                } *tmp;
2917

    
2918
                if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
2919
                    ret = -TARGET_EFAULT;
2920
                    break;
2921
                }
2922

    
2923
                ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
2924

    
2925
                unlock_user_struct(tmp, ptr, 0);
2926
                break;
2927
            }
2928
        default:
2929
            ret = do_msgrcv(first, ptr, second, fifth, third);
2930
        }
2931
        break;
2932

    
2933
    case IPCOP_shmat:
2934
        switch (version) {
2935
        default:
2936
        {
2937
            abi_ulong raddr;
2938
            raddr = do_shmat(first, ptr, second);
2939
            if (is_error(raddr))
2940
                return get_errno(raddr);
2941
            if (put_user_ual(raddr, third))
2942
                return -TARGET_EFAULT;
2943
            break;
2944
        }
2945
        case 1:
2946
            ret = -TARGET_EINVAL;
2947
            break;
2948
        }
2949
        break;
2950
    case IPCOP_shmdt:
2951
        ret = do_shmdt(ptr);
2952
        break;
2953

    
2954
    case IPCOP_shmget:
2955
        /* IPC_* flag values are the same on all linux platforms */
2956
        ret = get_errno(shmget(first, second, third));
2957
        break;
2958

    
2959
        /* IPC_* and SHM_* command values are the same on all linux platforms */
2960
    case IPCOP_shmctl:
2961
        ret = do_shmctl(first, second, third);
2962
        break;
2963
    default:
2964
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2965
        ret = -TARGET_ENOSYS;
2966
        break;
2967
    }
2968
    return ret;
2969
}
2970
#endif
2971

    
2972
/* kernel structure types definitions */
2973
#define IFNAMSIZ        16
2974

    
2975
#define STRUCT(name, ...) STRUCT_ ## name,
2976
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
2977
enum {
2978
#include "syscall_types.h"
2979
};
2980
#undef STRUCT
2981
#undef STRUCT_SPECIAL
2982

    
2983
#define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = {  __VA_ARGS__, TYPE_NULL };
2984
#define STRUCT_SPECIAL(name)
2985
#include "syscall_types.h"
2986
#undef STRUCT
2987
#undef STRUCT_SPECIAL
2988

    
2989
typedef struct IOCTLEntry IOCTLEntry;
2990

    
2991
typedef abi_long do_ioctl_fn(const IOCTLEntry *ie, uint8_t *buf_temp,
2992
                             int fd, abi_long cmd, abi_long arg);
2993

    
2994
struct IOCTLEntry {
2995
    unsigned int target_cmd;
2996
    unsigned int host_cmd;
2997
    const char *name;
2998
    int access;
2999
    do_ioctl_fn *do_ioctl;
3000
    const argtype arg_type[5];
3001
};
3002

    
3003
#define IOC_R 0x0001
3004
#define IOC_W 0x0002
3005
#define IOC_RW (IOC_R | IOC_W)
3006

    
3007
#define MAX_STRUCT_SIZE 4096
3008

    
3009
#ifdef CONFIG_FIEMAP
3010
/* So fiemap access checks don't overflow on 32 bit systems.
3011
 * This is very slightly smaller than the limit imposed by
3012
 * the underlying kernel.
3013
 */
3014
#define FIEMAP_MAX_EXTENTS ((UINT_MAX - sizeof(struct fiemap))  \
3015
                            / sizeof(struct fiemap_extent))
3016

    
3017
static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp,
3018
                                       int fd, abi_long cmd, abi_long arg)
3019
{
3020
    /* The parameter for this ioctl is a struct fiemap followed
3021
     * by an array of struct fiemap_extent whose size is set
3022
     * in fiemap->fm_extent_count. The array is filled in by the
3023
     * ioctl.
3024
     */
3025
    int target_size_in, target_size_out;
3026
    struct fiemap *fm;
3027
    const argtype *arg_type = ie->arg_type;
3028
    const argtype extent_arg_type[] = { MK_STRUCT(STRUCT_fiemap_extent) };
3029
    void *argptr, *p;
3030
    abi_long ret;
3031
    int i, extent_size = thunk_type_size(extent_arg_type, 0);
3032
    uint32_t outbufsz;
3033
    int free_fm = 0;
3034

    
3035
    assert(arg_type[0] == TYPE_PTR);
3036
    assert(ie->access == IOC_RW);
3037
    arg_type++;
3038
    target_size_in = thunk_type_size(arg_type, 0);
3039
    argptr = lock_user(VERIFY_READ, arg, target_size_in, 1);
3040
    if (!argptr) {
3041
        return -TARGET_EFAULT;
3042
    }
3043
    thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3044
    unlock_user(argptr, arg, 0);
3045
    fm = (struct fiemap *)buf_temp;
3046
    if (fm->fm_extent_count > FIEMAP_MAX_EXTENTS) {
3047
        return -TARGET_EINVAL;
3048
    }
3049

    
3050
    outbufsz = sizeof (*fm) +
3051
        (sizeof(struct fiemap_extent) * fm->fm_extent_count);
3052

    
3053
    if (outbufsz > MAX_STRUCT_SIZE) {
3054
        /* We can't fit all the extents into the fixed size buffer.
3055
         * Allocate one that is large enough and use it instead.
3056
         */
3057
        fm = malloc(outbufsz);
3058
        if (!fm) {
3059
            return -TARGET_ENOMEM;
3060
        }
3061
        memcpy(fm, buf_temp, sizeof(struct fiemap));
3062
        free_fm = 1;
3063
    }
3064
    ret = get_errno(ioctl(fd, ie->host_cmd, fm));
3065
    if (!is_error(ret)) {
3066
        target_size_out = target_size_in;
3067
        /* An extent_count of 0 means we were only counting the extents
3068
         * so there are no structs to copy
3069
         */
3070
        if (fm->fm_extent_count != 0) {
3071
            target_size_out += fm->fm_mapped_extents * extent_size;
3072
        }
3073
        argptr = lock_user(VERIFY_WRITE, arg, target_size_out, 0);
3074
        if (!argptr) {
3075
            ret = -TARGET_EFAULT;
3076
        } else {
3077
            /* Convert the struct fiemap */
3078
            thunk_convert(argptr, fm, arg_type, THUNK_TARGET);
3079
            if (fm->fm_extent_count != 0) {
3080
                p = argptr + target_size_in;
3081
                /* ...and then all the struct fiemap_extents */
3082
                for (i = 0; i < fm->fm_mapped_extents; i++) {
3083
                    thunk_convert(p, &fm->fm_extents[i], extent_arg_type,
3084
                                  THUNK_TARGET);
3085
                    p += extent_size;
3086
                }
3087
            }
3088
            unlock_user(argptr, arg, target_size_out);
3089
        }
3090
    }
3091
    if (free_fm) {
3092
        free(fm);
3093
    }
3094
    return ret;
3095
}
3096
#endif
3097

    
3098
static IOCTLEntry ioctl_entries[] = {
3099
#define IOCTL(cmd, access, ...) \
3100
    { TARGET_ ## cmd, cmd, #cmd, access, 0, {  __VA_ARGS__ } },
3101
#define IOCTL_SPECIAL(cmd, access, dofn, ...)                      \
3102
    { TARGET_ ## cmd, cmd, #cmd, access, dofn, {  __VA_ARGS__ } },
3103
#include "ioctls.h"
3104
    { 0, 0, },
3105
};
3106

    
3107
/* ??? Implement proper locking for ioctls.  */
3108
/* do_ioctl() Must return target values and target errnos. */
3109
static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
3110
{
3111
    const IOCTLEntry *ie;
3112
    const argtype *arg_type;
3113
    abi_long ret;
3114
    uint8_t buf_temp[MAX_STRUCT_SIZE];
3115
    int target_size;
3116
    void *argptr;
3117

    
3118
    ie = ioctl_entries;
3119
    for(;;) {
3120
        if (ie->target_cmd == 0) {
3121
            gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
3122
            return -TARGET_ENOSYS;
3123
        }
3124
        if (ie->target_cmd == cmd)
3125
            break;
3126
        ie++;
3127
    }
3128
    arg_type = ie->arg_type;
3129
#if defined(DEBUG)
3130
    gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
3131
#endif
3132
    if (ie->do_ioctl) {
3133
        return ie->do_ioctl(ie, buf_temp, fd, cmd, arg);
3134
    }
3135

    
3136
    switch(arg_type[0]) {
3137
    case TYPE_NULL:
3138
        /* no argument */
3139
        ret = get_errno(ioctl(fd, ie->host_cmd));
3140
        break;
3141
    case TYPE_PTRVOID:
3142
    case TYPE_INT:
3143
        /* int argment */
3144
        ret = get_errno(ioctl(fd, ie->host_cmd, arg));
3145
        break;
3146
    case TYPE_PTR:
3147
        arg_type++;
3148
        target_size = thunk_type_size(arg_type, 0);
3149
        switch(ie->access) {
3150
        case IOC_R:
3151
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3152
            if (!is_error(ret)) {
3153
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3154
                if (!argptr)
3155
                    return -TARGET_EFAULT;
3156
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
3157
                unlock_user(argptr, arg, target_size);
3158
            }
3159
            break;
3160
        case IOC_W:
3161
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3162
            if (!argptr)
3163
                return -TARGET_EFAULT;
3164
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3165
            unlock_user(argptr, arg, 0);
3166
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3167
            break;
3168
        default:
3169
        case IOC_RW:
3170
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3171
            if (!argptr)
3172
                return -TARGET_EFAULT;
3173
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3174
            unlock_user(argptr, arg, 0);
3175
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3176
            if (!is_error(ret)) {
3177
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3178
                if (!argptr)
3179
                    return -TARGET_EFAULT;
3180
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
3181
                unlock_user(argptr, arg, target_size);
3182
            }
3183
            break;
3184
        }
3185
        break;
3186
    default:
3187
        gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
3188
                 (long)cmd, arg_type[0]);
3189
        ret = -TARGET_ENOSYS;
3190
        break;
3191
    }
3192
    return ret;
3193
}
3194

    
3195
static const bitmask_transtbl iflag_tbl[] = {
3196
        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
3197
        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
3198
        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
3199
        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
3200
        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
3201
        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
3202
        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
3203
        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
3204
        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
3205
        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
3206
        { TARGET_IXON, TARGET_IXON, IXON, IXON },
3207
        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
3208
        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
3209
        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
3210
        { 0, 0, 0, 0 }
3211
};
3212

    
3213
static const bitmask_transtbl oflag_tbl[] = {
3214
        { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
3215
        { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
3216
        { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
3217
        { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
3218
        { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
3219
        { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
3220
        { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
3221
        { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
3222
        { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
3223
        { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
3224
        { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
3225
        { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
3226
        { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
3227
        { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
3228
        { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
3229
        { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
3230
        { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
3231
        { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
3232
        { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
3233
        { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
3234
        { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
3235
        { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
3236
        { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
3237
        { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
3238
        { 0, 0, 0, 0 }
3239
};
3240

    
3241
static const bitmask_transtbl cflag_tbl[] = {
3242
        { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
3243
        { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
3244
        { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
3245
        { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
3246
        { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
3247
        { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
3248
        { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
3249
        { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
3250
        { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
3251
        { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
3252
        { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
3253
        { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
3254
        { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
3255
        { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
3256
        { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
3257
        { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
3258
        { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
3259
        { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
3260
        { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
3261
        { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
3262
        { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
3263
        { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
3264
        { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
3265
        { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
3266
        { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
3267
        { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
3268
        { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
3269
        { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
3270
        { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
3271
        { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
3272
        { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
3273
        { 0, 0, 0, 0 }
3274
};
3275

    
3276
static const bitmask_transtbl lflag_tbl[] = {
3277
        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
3278
        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
3279
        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
3280
        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
3281
        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
3282
        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
3283
        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
3284
        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
3285
        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
3286
        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
3287
        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
3288
        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
3289
        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
3290
        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
3291
        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
3292
        { 0, 0, 0, 0 }
3293
};
3294

    
3295
static void target_to_host_termios (void *dst, const void *src)
3296
{
3297
    struct host_termios *host = dst;
3298
    const struct target_termios *target = src;
3299

    
3300
    host->c_iflag =
3301
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
3302
    host->c_oflag =
3303
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
3304
    host->c_cflag =
3305
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
3306
    host->c_lflag =
3307
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
3308
    host->c_line = target->c_line;
3309

    
3310
    memset(host->c_cc, 0, sizeof(host->c_cc));
3311
    host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
3312
    host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
3313
    host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
3314
    host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
3315
    host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
3316
    host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
3317
    host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
3318
    host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
3319
    host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
3320
    host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
3321
    host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
3322
    host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
3323
    host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
3324
    host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
3325
    host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
3326
    host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
3327
    host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
3328
}
3329

    
3330
static void host_to_target_termios (void *dst, const void *src)
3331
{
3332
    struct target_termios *target = dst;
3333
    const struct host_termios *host = src;
3334

    
3335
    target->c_iflag =
3336
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
3337
    target->c_oflag =
3338
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
3339
    target->c_cflag =
3340
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
3341
    target->c_lflag =
3342
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
3343
    target->c_line = host->c_line;
3344

    
3345
    memset(target->c_cc, 0, sizeof(target->c_cc));
3346
    target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
3347
    target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
3348
    target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
3349
    target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
3350
    target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
3351
    target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
3352
    target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
3353
    target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
3354
    target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
3355
    target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
3356
    target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
3357
    target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
3358
    target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
3359
    target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
3360
    target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
3361
    target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
3362
    target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
3363
}
3364

    
3365
static const StructEntry struct_termios_def = {
3366
    .convert = { host_to_target_termios, target_to_host_termios },
3367
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
3368
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
3369
};
3370

    
3371
static bitmask_transtbl mmap_flags_tbl[] = {
3372
        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
3373
        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
3374
        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
3375
        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
3376
        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
3377
        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
3378
        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
3379
        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
3380
        { 0, 0, 0, 0 }
3381
};
3382

    
3383
#if defined(TARGET_I386)
3384

    
3385
/* NOTE: there is really one LDT for all the threads */
3386
static uint8_t *ldt_table;
3387

    
3388
static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
3389
{
3390
    int size;
3391
    void *p;
3392

    
3393
    if (!ldt_table)
3394
        return 0;
3395
    size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
3396
    if (size > bytecount)
3397
        size = bytecount;
3398
    p = lock_user(VERIFY_WRITE, ptr, size, 0);
3399
    if (!p)
3400
        return -TARGET_EFAULT;
3401
    /* ??? Should this by byteswapped?  */
3402
    memcpy(p, ldt_table, size);
3403
    unlock_user(p, ptr, size);
3404
    return size;
3405
}
3406

    
3407
/* XXX: add locking support */
3408
static abi_long write_ldt(CPUX86State *env,
3409
                          abi_ulong ptr, unsigned long bytecount, int oldmode)
3410
{
3411
    struct target_modify_ldt_ldt_s ldt_info;
3412
    struct target_modify_ldt_ldt_s *target_ldt_info;
3413
    int seg_32bit, contents, read_exec_only, limit_in_pages;
3414
    int seg_not_present, useable, lm;
3415
    uint32_t *lp, entry_1, entry_2;
3416

    
3417
    if (bytecount != sizeof(ldt_info))
3418
        return -TARGET_EINVAL;
3419
    if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
3420
        return -TARGET_EFAULT;
3421
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3422
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
3423
    ldt_info.limit = tswap32(target_ldt_info->limit);
3424
    ldt_info.flags = tswap32(target_ldt_info->flags);
3425
    unlock_user_struct(target_ldt_info, ptr, 0);
3426

    
3427
    if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
3428
        return -TARGET_EINVAL;
3429
    seg_32bit = ldt_info.flags & 1;
3430
    contents = (ldt_info.flags >> 1) & 3;
3431
    read_exec_only = (ldt_info.flags >> 3) & 1;
3432
    limit_in_pages = (ldt_info.flags >> 4) & 1;
3433
    seg_not_present = (ldt_info.flags >> 5) & 1;
3434
    useable = (ldt_info.flags >> 6) & 1;
3435
#ifdef TARGET_ABI32
3436
    lm = 0;
3437
#else
3438
    lm = (ldt_info.flags >> 7) & 1;
3439
#endif
3440
    if (contents == 3) {
3441
        if (oldmode)
3442
            return -TARGET_EINVAL;
3443
        if (seg_not_present == 0)
3444
            return -TARGET_EINVAL;
3445
    }
3446
    /* allocate the LDT */
3447
    if (!ldt_table) {
3448
        env->ldt.base = target_mmap(0,
3449
                                    TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
3450
                                    PROT_READ|PROT_WRITE,
3451
                                    MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
3452
        if (env->ldt.base == -1)
3453
            return -TARGET_ENOMEM;
3454
        memset(g2h(env->ldt.base), 0,
3455
               TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
3456
        env->ldt.limit = 0xffff;
3457
        ldt_table = g2h(env->ldt.base);
3458
    }
3459

    
3460
    /* NOTE: same code as Linux kernel */
3461
    /* Allow LDTs to be cleared by the user. */
3462
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3463
        if (oldmode ||
3464
            (contents == 0                &&
3465
             read_exec_only == 1        &&
3466
             seg_32bit == 0                &&
3467
             limit_in_pages == 0        &&
3468
             seg_not_present == 1        &&
3469
             useable == 0 )) {
3470
            entry_1 = 0;
3471
            entry_2 = 0;
3472
            goto install;
3473
        }
3474
    }
3475

    
3476
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
3477
        (ldt_info.limit & 0x0ffff);
3478
    entry_2 = (ldt_info.base_addr & 0xff000000) |
3479
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3480
        (ldt_info.limit & 0xf0000) |
3481
        ((read_exec_only ^ 1) << 9) |
3482
        (contents << 10) |
3483
        ((seg_not_present ^ 1) << 15) |
3484
        (seg_32bit << 22) |
3485
        (limit_in_pages << 23) |
3486
        (lm << 21) |
3487
        0x7000;
3488
    if (!oldmode)
3489
        entry_2 |= (useable << 20);
3490

    
3491
    /* Install the new entry ...  */
3492
install:
3493
    lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
3494
    lp[0] = tswap32(entry_1);
3495
    lp[1] = tswap32(entry_2);
3496
    return 0;
3497
}
3498

    
3499
/* specific and weird i386 syscalls */
3500
static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
3501
                              unsigned long bytecount)
3502
{
3503
    abi_long ret;
3504

    
3505
    switch (func) {
3506
    case 0:
3507
        ret = read_ldt(ptr, bytecount);
3508
        break;
3509
    case 1:
3510
        ret = write_ldt(env, ptr, bytecount, 1);
3511
        break;
3512
    case 0x11:
3513
        ret = write_ldt(env, ptr, bytecount, 0);
3514
        break;
3515
    default:
3516
        ret = -TARGET_ENOSYS;
3517
        break;
3518
    }
3519
    return ret;
3520
}
3521

    
3522
#if defined(TARGET_I386) && defined(TARGET_ABI32)
3523
static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
3524
{
3525
    uint64_t *gdt_table = g2h(env->gdt.base);
3526
    struct target_modify_ldt_ldt_s ldt_info;
3527
    struct target_modify_ldt_ldt_s *target_ldt_info;
3528
    int seg_32bit, contents, read_exec_only, limit_in_pages;
3529
    int seg_not_present, useable, lm;
3530
    uint32_t *lp, entry_1, entry_2;
3531
    int i;
3532

    
3533
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3534
    if (!target_ldt_info)
3535
        return -TARGET_EFAULT;
3536
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3537
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
3538
    ldt_info.limit = tswap32(target_ldt_info->limit);
3539
    ldt_info.flags = tswap32(target_ldt_info->flags);
3540
    if (ldt_info.entry_number == -1) {
3541
        for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
3542
            if (gdt_table[i] == 0) {
3543
                ldt_info.entry_number = i;
3544
                target_ldt_info->entry_number = tswap32(i);
3545
                break;
3546
            }
3547
        }
3548
    }
3549
    unlock_user_struct(target_ldt_info, ptr, 1);
3550

    
3551
    if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || 
3552
        ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
3553
           return -TARGET_EINVAL;
3554
    seg_32bit = ldt_info.flags & 1;
3555
    contents = (ldt_info.flags >> 1) & 3;
3556
    read_exec_only = (ldt_info.flags >> 3) & 1;
3557
    limit_in_pages = (ldt_info.flags >> 4) & 1;
3558
    seg_not_present = (ldt_info.flags >> 5) & 1;
3559
    useable = (ldt_info.flags >> 6) & 1;
3560
#ifdef TARGET_ABI32
3561
    lm = 0;
3562
#else
3563
    lm = (ldt_info.flags >> 7) & 1;
3564
#endif
3565

    
3566
    if (contents == 3) {
3567
        if (seg_not_present == 0)
3568
            return -TARGET_EINVAL;
3569
    }
3570

    
3571
    /* NOTE: same code as Linux kernel */
3572
    /* Allow LDTs to be cleared by the user. */
3573
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3574
        if ((contents == 0             &&
3575
             read_exec_only == 1       &&
3576
             seg_32bit == 0            &&
3577
             limit_in_pages == 0       &&
3578
             seg_not_present == 1      &&
3579
             useable == 0 )) {
3580
            entry_1 = 0;
3581
            entry_2 = 0;
3582
            goto install;
3583
        }
3584
    }
3585

    
3586
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
3587
        (ldt_info.limit & 0x0ffff);
3588
    entry_2 = (ldt_info.base_addr & 0xff000000) |
3589
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3590
        (ldt_info.limit & 0xf0000) |
3591
        ((read_exec_only ^ 1) << 9) |
3592
        (contents << 10) |
3593
        ((seg_not_present ^ 1) << 15) |
3594
        (seg_32bit << 22) |
3595
        (limit_in_pages << 23) |
3596
        (useable << 20) |
3597
        (lm << 21) |
3598
        0x7000;
3599

    
3600
    /* Install the new entry ...  */
3601
install:
3602
    lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
3603
    lp[0] = tswap32(entry_1);
3604
    lp[1] = tswap32(entry_2);
3605
    return 0;
3606
}
3607

    
3608
static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
3609
{
3610
    struct target_modify_ldt_ldt_s *target_ldt_info;
3611
    uint64_t *gdt_table = g2h(env->gdt.base);
3612
    uint32_t base_addr, limit, flags;
3613
    int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
3614
    int seg_not_present, useable, lm;
3615
    uint32_t *lp, entry_1, entry_2;
3616

    
3617
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3618
    if (!target_ldt_info)
3619
        return -TARGET_EFAULT;
3620
    idx = tswap32(target_ldt_info->entry_number);
3621
    if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
3622
        idx > TARGET_GDT_ENTRY_TLS_MAX) {
3623
        unlock_user_struct(target_ldt_info, ptr, 1);
3624
        return -TARGET_EINVAL;
3625
    }
3626
    lp = (uint32_t *)(gdt_table + idx);
3627
    entry_1 = tswap32(lp[0]);
3628
    entry_2 = tswap32(lp[1]);
3629
    
3630
    read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
3631
    contents = (entry_2 >> 10) & 3;
3632
    seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
3633
    seg_32bit = (entry_2 >> 22) & 1;
3634
    limit_in_pages = (entry_2 >> 23) & 1;
3635
    useable = (entry_2 >> 20) & 1;
3636
#ifdef TARGET_ABI32
3637
    lm = 0;
3638
#else
3639
    lm = (entry_2 >> 21) & 1;
3640
#endif
3641
    flags = (seg_32bit << 0) | (contents << 1) |
3642
        (read_exec_only << 3) | (limit_in_pages << 4) |
3643
        (seg_not_present << 5) | (useable << 6) | (lm << 7);
3644
    limit = (entry_1 & 0xffff) | (entry_2  & 0xf0000);
3645
    base_addr = (entry_1 >> 16) | 
3646
        (entry_2 & 0xff000000) | 
3647
        ((entry_2 & 0xff) << 16);
3648
    target_ldt_info->base_addr = tswapl(base_addr);
3649
    target_ldt_info->limit = tswap32(limit);
3650
    target_ldt_info->flags = tswap32(flags);
3651
    unlock_user_struct(target_ldt_info, ptr, 1);
3652
    return 0;
3653
}
3654
#endif /* TARGET_I386 && TARGET_ABI32 */
3655

    
3656
#ifndef TARGET_ABI32
3657
static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
3658
{
3659
    abi_long ret;
3660
    abi_ulong val;
3661
    int idx;
3662
    
3663
    switch(code) {
3664
    case TARGET_ARCH_SET_GS:
3665
    case TARGET_ARCH_SET_FS:
3666
        if (code == TARGET_ARCH_SET_GS)
3667
            idx = R_GS;
3668
        else
3669
            idx = R_FS;
3670
        cpu_x86_load_seg(env, idx, 0);
3671
        env->segs[idx].base = addr;
3672
        break;
3673
    case TARGET_ARCH_GET_GS:
3674
    case TARGET_ARCH_GET_FS:
3675
        if (code == TARGET_ARCH_GET_GS)
3676
            idx = R_GS;
3677
        else
3678
            idx = R_FS;
3679
        val = env->segs[idx].base;
3680
        if (put_user(val, addr, abi_ulong))
3681
            return -TARGET_EFAULT;
3682
        break;
3683
    default:
3684
        ret = -TARGET_EINVAL;
3685
        break;
3686
    }
3687
    return 0;
3688
}
3689
#endif
3690

    
3691
#endif /* defined(TARGET_I386) */
3692

    
3693
#if defined(CONFIG_USE_NPTL)
3694

    
3695
#define NEW_STACK_SIZE PTHREAD_STACK_MIN
3696

    
3697
static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
3698
typedef struct {
3699
    CPUState *env;
3700
    pthread_mutex_t mutex;
3701
    pthread_cond_t cond;
3702
    pthread_t thread;
3703
    uint32_t tid;
3704
    abi_ulong child_tidptr;
3705
    abi_ulong parent_tidptr;
3706
    sigset_t sigmask;
3707
} new_thread_info;
3708

    
3709
static void *clone_func(void *arg)
3710
{
3711
    new_thread_info *info = arg;
3712
    CPUState *env;
3713
    TaskState *ts;
3714

    
3715
    env = info->env;
3716
    thread_env = env;
3717
    ts = (TaskState *)thread_env->opaque;
3718
    info->tid = gettid();
3719
    env->host_tid = info->tid;
3720
    task_settid(ts);
3721
    if (info->child_tidptr)
3722
        put_user_u32(info->tid, info->child_tidptr);
3723
    if (info->parent_tidptr)
3724
        put_user_u32(info->tid, info->parent_tidptr);
3725
    /* Enable signals.  */
3726
    sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
3727
    /* Signal to the parent that we're ready.  */
3728
    pthread_mutex_lock(&info->mutex);
3729
    pthread_cond_broadcast(&info->cond);
3730
    pthread_mutex_unlock(&info->mutex);
3731
    /* Wait until the parent has finshed initializing the tls state.  */
3732
    pthread_mutex_lock(&clone_lock);
3733
    pthread_mutex_unlock(&clone_lock);
3734
    cpu_loop(env);
3735
    /* never exits */
3736
    return NULL;
3737
}
3738
#else
3739
/* this stack is the equivalent of the kernel stack associated with a
3740
   thread/process */
3741
#define NEW_STACK_SIZE 8192
3742

    
3743
static int clone_func(void *arg)
3744
{
3745
    CPUState *env = arg;
3746
    cpu_loop(env);
3747
    /* never exits */
3748
    return 0;
3749
}
3750
#endif
3751

    
3752
/* do_fork() Must return host values and target errnos (unlike most
3753
   do_*() functions). */
3754
static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
3755
                   abi_ulong parent_tidptr, target_ulong newtls,
3756
                   abi_ulong child_tidptr)
3757
{
3758
    int ret;
3759
    TaskState *ts;
3760
    CPUState *new_env;
3761
#if defined(CONFIG_USE_NPTL)
3762
    unsigned int nptl_flags;
3763
    sigset_t sigmask;
3764
#else
3765
    uint8_t *new_stack;
3766
#endif
3767

    
3768
    /* Emulate vfork() with fork() */
3769
    if (flags & CLONE_VFORK)
3770
        flags &= ~(CLONE_VFORK | CLONE_VM);
3771

    
3772
    if (flags & CLONE_VM) {
3773
        TaskState *parent_ts = (TaskState *)env->opaque;
3774
#if defined(CONFIG_USE_NPTL)
3775
        new_thread_info info;
3776
        pthread_attr_t attr;
3777
#endif
3778
        ts = qemu_mallocz(sizeof(TaskState));
3779
        init_task_state(ts);
3780
        /* we create a new CPU instance. */
3781
        new_env = cpu_copy(env);
3782
#if defined(TARGET_I386) || defined(TARGET_SPARC) || defined(TARGET_PPC)
3783
        cpu_reset(new_env);
3784
#endif
3785
        /* Init regs that differ from the parent.  */
3786
        cpu_clone_regs(new_env, newsp);
3787
        new_env->opaque = ts;
3788
        ts->bprm = parent_ts->bprm;
3789
        ts->info = parent_ts->info;
3790
#if defined(CONFIG_USE_NPTL)
3791
        nptl_flags = flags;
3792
        flags &= ~CLONE_NPTL_FLAGS2;
3793

    
3794
        if (nptl_flags & CLONE_CHILD_CLEARTID) {
3795
            ts->child_tidptr = child_tidptr;
3796
        }
3797

    
3798
        if (nptl_flags & CLONE_SETTLS)
3799
            cpu_set_tls (new_env, newtls);
3800

    
3801
        /* Grab a mutex so that thread setup appears atomic.  */
3802
        pthread_mutex_lock(&clone_lock);
3803

    
3804
        memset(&info, 0, sizeof(info));
3805
        pthread_mutex_init(&info.mutex, NULL);
3806
        pthread_mutex_lock(&info.mutex);
3807
        pthread_cond_init(&info.cond, NULL);
3808
        info.env = new_env;
3809
        if (nptl_flags & CLONE_CHILD_SETTID)
3810
            info.child_tidptr = child_tidptr;
3811
        if (nptl_flags & CLONE_PARENT_SETTID)
3812
            info.parent_tidptr = parent_tidptr;
3813

    
3814
        ret = pthread_attr_init(&attr);
3815
        ret = pthread_attr_setstacksize(&attr, NEW_STACK_SIZE);
3816
        ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
3817
        /* It is not safe to deliver signals until the child has finished
3818
           initializing, so temporarily block all signals.  */
3819
        sigfillset(&sigmask);
3820
        sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
3821

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

    
3825
        sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
3826
        pthread_attr_destroy(&attr);
3827
        if (ret == 0) {
3828
            /* Wait for the child to initialize.  */
3829
            pthread_cond_wait(&info.cond, &info.mutex);
3830
            ret = info.tid;
3831
            if (flags & CLONE_PARENT_SETTID)
3832
                put_user_u32(ret, parent_tidptr);
3833
        } else {
3834
            ret = -1;
3835
        }
3836
        pthread_mutex_unlock(&info.mutex);
3837
        pthread_cond_destroy(&info.cond);
3838
        pthread_mutex_destroy(&info.mutex);
3839
        pthread_mutex_unlock(&clone_lock);
3840
#else
3841
        if (flags & CLONE_NPTL_FLAGS2)
3842
            return -EINVAL;
3843
        /* This is probably going to die very quickly, but do it anyway.  */
3844
        new_stack = qemu_mallocz (NEW_STACK_SIZE);
3845
#ifdef __ia64__
3846
        ret = __clone2(clone_func, new_stack, NEW_STACK_SIZE, flags, new_env);
3847
#else
3848
        ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
3849
#endif
3850
#endif
3851
    } else {
3852
        /* if no CLONE_VM, we consider it is a fork */
3853
        if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
3854
            return -EINVAL;
3855
        fork_start();
3856
        ret = fork();
3857
        if (ret == 0) {
3858
            /* Child Process.  */
3859
            cpu_clone_regs(env, newsp);
3860
            fork_end(1);
3861
#if defined(CONFIG_USE_NPTL)
3862
            /* There is a race condition here.  The parent process could
3863
               theoretically read the TID in the child process before the child
3864
               tid is set.  This would require using either ptrace
3865
               (not implemented) or having *_tidptr to point at a shared memory
3866
               mapping.  We can't repeat the spinlock hack used above because
3867
               the child process gets its own copy of the lock.  */
3868
            if (flags & CLONE_CHILD_SETTID)
3869
                put_user_u32(gettid(), child_tidptr);
3870
            if (flags & CLONE_PARENT_SETTID)
3871
                put_user_u32(gettid(), parent_tidptr);
3872
            ts = (TaskState *)env->opaque;
3873
            if (flags & CLONE_SETTLS)
3874
                cpu_set_tls (env, newtls);
3875
            if (flags & CLONE_CHILD_CLEARTID)
3876
                ts->child_tidptr = child_tidptr;
3877
#endif
3878
        } else {
3879
            fork_end(0);
3880
        }
3881
    }
3882
    return ret;
3883
}
3884

    
3885
/* warning : doesn't handle linux specific flags... */
3886
static int target_to_host_fcntl_cmd(int cmd)
3887
{
3888
    switch(cmd) {
3889
        case TARGET_F_DUPFD:
3890
        case TARGET_F_GETFD:
3891
        case TARGET_F_SETFD:
3892
        case TARGET_F_GETFL:
3893
        case TARGET_F_SETFL:
3894
            return cmd;
3895
        case TARGET_F_GETLK:
3896
            return F_GETLK;
3897
        case TARGET_F_SETLK:
3898
            return F_SETLK;
3899
        case TARGET_F_SETLKW:
3900
            return F_SETLKW;
3901
        case TARGET_F_GETOWN:
3902
            return F_GETOWN;
3903
        case TARGET_F_SETOWN:
3904
            return F_SETOWN;
3905
        case TARGET_F_GETSIG:
3906
            return F_GETSIG;
3907
        case TARGET_F_SETSIG:
3908
            return F_SETSIG;
3909
#if TARGET_ABI_BITS == 32
3910
        case TARGET_F_GETLK64:
3911
            return F_GETLK64;
3912
        case TARGET_F_SETLK64:
3913
            return F_SETLK64;
3914
        case TARGET_F_SETLKW64:
3915
            return F_SETLKW64;
3916
#endif
3917
        case TARGET_F_SETLEASE:
3918
            return F_SETLEASE;
3919
        case TARGET_F_GETLEASE:
3920
            return F_GETLEASE;
3921
#ifdef F_DUPFD_CLOEXEC
3922
        case TARGET_F_DUPFD_CLOEXEC:
3923
            return F_DUPFD_CLOEXEC;
3924
#endif
3925
        case TARGET_F_NOTIFY:
3926
            return F_NOTIFY;
3927
        default:
3928
            return -TARGET_EINVAL;
3929
    }
3930
    return -TARGET_EINVAL;
3931
}
3932

    
3933
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
3934
{
3935
    struct flock fl;
3936
    struct target_flock *target_fl;
3937
    struct flock64 fl64;
3938
    struct target_flock64 *target_fl64;
3939
    abi_long ret;
3940
    int host_cmd = target_to_host_fcntl_cmd(cmd);
3941

    
3942
    if (host_cmd == -TARGET_EINVAL)
3943
            return host_cmd;
3944

    
3945
    switch(cmd) {
3946
    case TARGET_F_GETLK:
3947
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3948
            return -TARGET_EFAULT;
3949
        fl.l_type = tswap16(target_fl->l_type);
3950
        fl.l_whence = tswap16(target_fl->l_whence);
3951
        fl.l_start = tswapl(target_fl->l_start);
3952
        fl.l_len = tswapl(target_fl->l_len);
3953
        fl.l_pid = tswap32(target_fl->l_pid);
3954
        unlock_user_struct(target_fl, arg, 0);
3955
        ret = get_errno(fcntl(fd, host_cmd, &fl));
3956
        if (ret == 0) {
3957
            if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
3958
                return -TARGET_EFAULT;
3959
            target_fl->l_type = tswap16(fl.l_type);
3960
            target_fl->l_whence = tswap16(fl.l_whence);
3961
            target_fl->l_start = tswapl(fl.l_start);
3962
            target_fl->l_len = tswapl(fl.l_len);
3963
            target_fl->l_pid = tswap32(fl.l_pid);
3964
            unlock_user_struct(target_fl, arg, 1);
3965
        }
3966
        break;
3967

    
3968
    case TARGET_F_SETLK:
3969
    case TARGET_F_SETLKW:
3970
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3971
            return -TARGET_EFAULT;
3972
        fl.l_type = tswap16(target_fl->l_type);
3973
        fl.l_whence = tswap16(target_fl->l_whence);
3974
        fl.l_start = tswapl(target_fl->l_start);
3975
        fl.l_len = tswapl(target_fl->l_len);
3976
        fl.l_pid = tswap32(target_fl->l_pid);
3977
        unlock_user_struct(target_fl, arg, 0);
3978
        ret = get_errno(fcntl(fd, host_cmd, &fl));
3979
        break;
3980

    
3981
    case TARGET_F_GETLK64:
3982
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3983
            return -TARGET_EFAULT;
3984
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3985
        fl64.l_whence = tswap16(target_fl64->l_whence);
3986
        fl64.l_start = tswapl(target_fl64->l_start);
3987
        fl64.l_len = tswapl(target_fl64->l_len);
3988
        fl64.l_pid = tswap32(target_fl64->l_pid);
3989
        unlock_user_struct(target_fl64, arg, 0);
3990
        ret = get_errno(fcntl(fd, host_cmd, &fl64));
3991
        if (ret == 0) {
3992
            if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
3993
                return -TARGET_EFAULT;
3994
            target_fl64->l_type = tswap16(fl64.l_type) >> 1;
3995
            target_fl64->l_whence = tswap16(fl64.l_whence);
3996
            target_fl64->l_start = tswapl(fl64.l_start);
3997
            target_fl64->l_len = tswapl(fl64.l_len);
3998
            target_fl64->l_pid = tswap32(fl64.l_pid);
3999
            unlock_user_struct(target_fl64, arg, 1);
4000
        }
4001
        break;
4002
    case TARGET_F_SETLK64:
4003
    case TARGET_F_SETLKW64:
4004
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
4005
            return -TARGET_EFAULT;
4006
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
4007
        fl64.l_whence = tswap16(target_fl64->l_whence);
4008
        fl64.l_start = tswapl(target_fl64->l_start);
4009
        fl64.l_len = tswapl(target_fl64->l_len);
4010
        fl64.l_pid = tswap32(target_fl64->l_pid);
4011
        unlock_user_struct(target_fl64, arg, 0);
4012
        ret = get_errno(fcntl(fd, host_cmd, &fl64));
4013
        break;
4014

    
4015
    case TARGET_F_GETFL:
4016
        ret = get_errno(fcntl(fd, host_cmd, arg));
4017
        if (ret >= 0) {
4018
            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
4019
        }
4020
        break;
4021

    
4022
    case TARGET_F_SETFL:
4023
        ret = get_errno(fcntl(fd, host_cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
4024
        break;
4025

    
4026
    case TARGET_F_SETOWN:
4027
    case TARGET_F_GETOWN:
4028
    case TARGET_F_SETSIG:
4029
    case TARGET_F_GETSIG:
4030
    case TARGET_F_SETLEASE:
4031
    case TARGET_F_GETLEASE:
4032
        ret = get_errno(fcntl(fd, host_cmd, arg));
4033
        break;
4034

    
4035
    default:
4036
        ret = get_errno(fcntl(fd, cmd, arg));
4037
        break;
4038
    }
4039
    return ret;
4040
}
4041

    
4042
#ifdef USE_UID16
4043

    
4044
static inline int high2lowuid(int uid)
4045
{
4046
    if (uid > 65535)
4047
        return 65534;
4048
    else
4049
        return uid;
4050
}
4051

    
4052
static inline int high2lowgid(int gid)
4053
{
4054
    if (gid > 65535)
4055
        return 65534;
4056
    else
4057
        return gid;
4058
}
4059

    
4060
static inline int low2highuid(int uid)
4061
{
4062
    if ((int16_t)uid == -1)
4063
        return -1;
4064
    else
4065
        return uid;
4066
}
4067

    
4068
static inline int low2highgid(int gid)
4069
{
4070
    if ((int16_t)gid == -1)
4071
        return -1;
4072
    else
4073
        return gid;
4074
}
4075

    
4076
#endif /* USE_UID16 */
4077

    
4078
void syscall_init(void)
4079
{
4080
    IOCTLEntry *ie;
4081
    const argtype *arg_type;
4082
    int size;
4083
    int i;
4084

    
4085
#define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
4086
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
4087
#include "syscall_types.h"
4088
#undef STRUCT
4089
#undef STRUCT_SPECIAL
4090

    
4091
    /* we patch the ioctl size if necessary. We rely on the fact that
4092
       no ioctl has all the bits at '1' in the size field */
4093
    ie = ioctl_entries;
4094
    while (ie->target_cmd != 0) {
4095
        if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
4096
            TARGET_IOC_SIZEMASK) {
4097
            arg_type = ie->arg_type;
4098
            if (arg_type[0] != TYPE_PTR) {
4099
                fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
4100
                        ie->target_cmd);
4101
                exit(1);
4102
            }
4103
            arg_type++;
4104
            size = thunk_type_size(arg_type, 0);
4105
            ie->target_cmd = (ie->target_cmd &
4106
                              ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
4107
                (size << TARGET_IOC_SIZESHIFT);
4108
        }
4109

    
4110
        /* Build target_to_host_errno_table[] table from
4111
         * host_to_target_errno_table[]. */
4112
        for (i=0; i < ERRNO_TABLE_SIZE; i++)
4113
                target_to_host_errno_table[host_to_target_errno_table[i]] = i;
4114

    
4115
        /* automatic consistency check if same arch */
4116
#if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
4117
    (defined(__x86_64__) && defined(TARGET_X86_64))
4118
        if (unlikely(ie->target_cmd != ie->host_cmd)) {
4119
            fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
4120
                    ie->name, ie->target_cmd, ie->host_cmd);
4121
        }
4122
#endif
4123
        ie++;
4124
    }
4125
}
4126

    
4127
#if TARGET_ABI_BITS == 32
4128
static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
4129
{
4130
#ifdef TARGET_WORDS_BIGENDIAN
4131
    return ((uint64_t)word0 << 32) | word1;
4132
#else
4133
    return ((uint64_t)word1 << 32) | word0;
4134
#endif
4135
}
4136
#else /* TARGET_ABI_BITS == 32 */
4137
static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
4138
{
4139
    return word0;
4140
}
4141
#endif /* TARGET_ABI_BITS != 32 */
4142

    
4143
#ifdef TARGET_NR_truncate64
4144
static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
4145
                                         abi_long arg2,
4146
                                         abi_long arg3,
4147
                                         abi_long arg4)
4148
{
4149
#ifdef TARGET_ARM
4150
    if (((CPUARMState *)cpu_env)->eabi)
4151
      {
4152
        arg2 = arg3;
4153
        arg3 = arg4;
4154
      }
4155
#endif
4156
    return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
4157
}
4158
#endif
4159

    
4160
#ifdef TARGET_NR_ftruncate64
4161
static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
4162
                                          abi_long arg2,
4163
                                          abi_long arg3,
4164
                                          abi_long arg4)
4165
{
4166
#ifdef TARGET_ARM
4167
    if (((CPUARMState *)cpu_env)->eabi)
4168
      {
4169
        arg2 = arg3;
4170
        arg3 = arg4;
4171
      }
4172
#endif
4173
    return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
4174
}
4175
#endif
4176

    
4177
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
4178
                                               abi_ulong target_addr)
4179
{
4180
    struct target_timespec *target_ts;
4181

    
4182
    if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
4183
        return -TARGET_EFAULT;
4184
    host_ts->tv_sec = tswapl(target_ts->tv_sec);
4185
    host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
4186
    unlock_user_struct(target_ts, target_addr, 0);
4187
    return 0;
4188
}
4189

    
4190
static inline abi_long host_to_target_timespec(abi_ulong target_addr,
4191
                                               struct timespec *host_ts)
4192
{
4193
    struct target_timespec *target_ts;
4194

    
4195
    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
4196
        return -TARGET_EFAULT;
4197
    target_ts->tv_sec = tswapl(host_ts->tv_sec);
4198
    target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
4199
    unlock_user_struct(target_ts, target_addr, 1);
4200
    return 0;
4201
}
4202

    
4203
#if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
4204
static inline abi_long host_to_target_stat64(void *cpu_env,
4205
                                             abi_ulong target_addr,
4206
                                             struct stat *host_st)
4207
{
4208
#ifdef TARGET_ARM
4209
    if (((CPUARMState *)cpu_env)->eabi) {
4210
        struct target_eabi_stat64 *target_st;
4211

    
4212
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
4213
            return -TARGET_EFAULT;
4214
        memset(target_st, 0, sizeof(struct target_eabi_stat64));
4215
        __put_user(host_st->st_dev, &target_st->st_dev);
4216
        __put_user(host_st->st_ino, &target_st->st_ino);
4217
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4218
        __put_user(host_st->st_ino, &target_st->__st_ino);
4219
#endif
4220
        __put_user(host_st->st_mode, &target_st->st_mode);
4221
        __put_user(host_st->st_nlink, &target_st->st_nlink);
4222
        __put_user(host_st->st_uid, &target_st->st_uid);
4223
        __put_user(host_st->st_gid, &target_st->st_gid);
4224
        __put_user(host_st->st_rdev, &target_st->st_rdev);
4225
        __put_user(host_st->st_size, &target_st->st_size);
4226
        __put_user(host_st->st_blksize, &target_st->st_blksize);
4227
        __put_user(host_st->st_blocks, &target_st->st_blocks);
4228
        __put_user(host_st->st_atime, &target_st->target_st_atime);
4229
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
4230
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
4231
        unlock_user_struct(target_st, target_addr, 1);
4232
    } else
4233
#endif
4234
    {
4235
#if TARGET_ABI_BITS == 64 && !defined(TARGET_ALPHA)
4236
        struct target_stat *target_st;
4237
#else
4238
        struct target_stat64 *target_st;
4239
#endif
4240

    
4241
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
4242
            return -TARGET_EFAULT;
4243
        memset(target_st, 0, sizeof(*target_st));
4244
        __put_user(host_st->st_dev, &target_st->st_dev);
4245
        __put_user(host_st->st_ino, &target_st->st_ino);
4246
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4247
        __put_user(host_st->st_ino, &target_st->__st_ino);
4248
#endif
4249
        __put_user(host_st->st_mode, &target_st->st_mode);
4250
        __put_user(host_st->st_nlink, &target_st->st_nlink);
4251
        __put_user(host_st->st_uid, &target_st->st_uid);
4252
        __put_user(host_st->st_gid, &target_st->st_gid);
4253
        __put_user(host_st->st_rdev, &target_st->st_rdev);
4254
        /* XXX: better use of kernel struct */
4255
        __put_user(host_st->st_size, &target_st->st_size);
4256
        __put_user(host_st->st_blksize, &target_st->st_blksize);
4257
        __put_user(host_st->st_blocks, &target_st->st_blocks);
4258
        __put_user(host_st->st_atime, &target_st->target_st_atime);
4259
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
4260
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
4261
        unlock_user_struct(target_st, target_addr, 1);
4262
    }
4263

    
4264
    return 0;
4265
}
4266
#endif
4267

    
4268
#if defined(CONFIG_USE_NPTL)
4269
/* ??? Using host futex calls even when target atomic operations
4270
   are not really atomic probably breaks things.  However implementing
4271
   futexes locally would make futexes shared between multiple processes
4272
   tricky.  However they're probably useless because guest atomic
4273
   operations won't work either.  */
4274
static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
4275
                    target_ulong uaddr2, int val3)
4276
{
4277
    struct timespec ts, *pts;
4278
    int base_op;
4279

    
4280
    /* ??? We assume FUTEX_* constants are the same on both host
4281
       and target.  */
4282
#ifdef FUTEX_CMD_MASK
4283
    base_op = op & FUTEX_CMD_MASK;
4284
#else
4285
    base_op = op;
4286
#endif
4287
    switch (base_op) {
4288
    case FUTEX_WAIT:
4289
        if (timeout) {
4290
            pts = &ts;
4291
            target_to_host_timespec(pts, timeout);
4292
        } else {
4293
            pts = NULL;
4294
        }
4295
        return get_errno(sys_futex(g2h(uaddr), op, tswap32(val),
4296
                         pts, NULL, 0));
4297
    case FUTEX_WAKE:
4298
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4299
    case FUTEX_FD:
4300
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4301
    case FUTEX_REQUEUE:
4302
    case FUTEX_CMP_REQUEUE:
4303
    case FUTEX_WAKE_OP:
4304
        /* For FUTEX_REQUEUE, FUTEX_CMP_REQUEUE, and FUTEX_WAKE_OP, the
4305
           TIMEOUT parameter is interpreted as a uint32_t by the kernel.
4306
           But the prototype takes a `struct timespec *'; insert casts
4307
           to satisfy the compiler.  We do not need to tswap TIMEOUT
4308
           since it's not compared to guest memory.  */
4309
        pts = (struct timespec *)(uintptr_t) timeout;
4310
        return get_errno(sys_futex(g2h(uaddr), op, val, pts,
4311
                                   g2h(uaddr2),
4312
                                   (base_op == FUTEX_CMP_REQUEUE
4313
                                    ? tswap32(val3)
4314
                                    : val3)));
4315
    default:
4316
        return -TARGET_ENOSYS;
4317
    }
4318
}
4319
#endif
4320

    
4321
/* Map host to target signal numbers for the wait family of syscalls.
4322
   Assume all other status bits are the same.  */
4323
static int host_to_target_waitstatus(int status)
4324
{
4325
    if (WIFSIGNALED(status)) {
4326
        return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f);
4327
    }
4328
    if (WIFSTOPPED(status)) {
4329
        return (host_to_target_signal(WSTOPSIG(status)) << 8)
4330
               | (status & 0xff);
4331
    }
4332
    return status;
4333
}
4334

    
4335
int get_osversion(void)
4336
{
4337
    static int osversion;
4338
    struct new_utsname buf;
4339
    const char *s;
4340
    int i, n, tmp;
4341
    if (osversion)
4342
        return osversion;
4343
    if (qemu_uname_release && *qemu_uname_release) {
4344
        s = qemu_uname_release;
4345
    } else {
4346
        if (sys_uname(&buf))
4347
            return 0;
4348
        s = buf.release;
4349
    }
4350
    tmp = 0;
4351
    for (i = 0; i < 3; i++) {
4352
        n = 0;
4353
        while (*s >= '0' && *s <= '9') {
4354
            n *= 10;
4355
            n += *s - '0';
4356
            s++;
4357
        }
4358
        tmp = (tmp << 8) + n;
4359
        if (*s == '.')
4360
            s++;
4361
    }
4362
    osversion = tmp;
4363
    return osversion;
4364
}
4365

    
4366
/* do_syscall() should always have a single exit point at the end so
4367
   that actions, such as logging of syscall results, can be performed.
4368
   All errnos that do_syscall() returns must be -TARGET_<errcode>. */
4369
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4370
                    abi_long arg2, abi_long arg3, abi_long arg4,
4371
                    abi_long arg5, abi_long arg6)
4372
{
4373
    abi_long ret;
4374
    struct stat st;
4375
    struct statfs stfs;
4376
    void *p;
4377

    
4378
#ifdef DEBUG
4379
    gemu_log("syscall %d", num);
4380
#endif
4381
    if(do_strace)
4382
        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
4383

    
4384
    switch(num) {
4385
    case TARGET_NR_exit:
4386
#ifdef CONFIG_USE_NPTL
4387
      /* In old applications this may be used to implement _exit(2).
4388
         However in threaded applictions it is used for thread termination,
4389
         and _exit_group is used for application termination.
4390
         Do thread termination if we have more then one thread.  */
4391
      /* FIXME: This probably breaks if a signal arrives.  We should probably
4392
         be disabling signals.  */
4393
      if (first_cpu->next_cpu) {
4394
          TaskState *ts;
4395
          CPUState **lastp;
4396
          CPUState *p;
4397

    
4398
          cpu_list_lock();
4399
          lastp = &first_cpu;
4400
          p = first_cpu;
4401
          while (p && p != (CPUState *)cpu_env) {
4402
              lastp = &p->next_cpu;
4403
              p = p->next_cpu;
4404
          }
4405
          /* If we didn't find the CPU for this thread then something is
4406
             horribly wrong.  */
4407
          if (!p)
4408
              abort();
4409
          /* Remove the CPU from the list.  */
4410
          *lastp = p->next_cpu;
4411
          cpu_list_unlock();
4412
          ts = ((CPUState *)cpu_env)->opaque;
4413
          if (ts->child_tidptr) {
4414
              put_user_u32(0, ts->child_tidptr);
4415
              sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
4416
                        NULL, NULL, 0);
4417
          }
4418
          thread_env = NULL;
4419
          qemu_free(cpu_env);
4420
          qemu_free(ts);
4421
          pthread_exit(NULL);
4422
      }
4423
#endif
4424
#ifdef TARGET_GPROF
4425
        _mcleanup();
4426
#endif
4427
        gdb_exit(cpu_env, arg1);
4428
        _exit(arg1);
4429
        ret = 0; /* avoid warning */
4430
        break;
4431
    case TARGET_NR_read:
4432
        if (arg3 == 0)
4433
            ret = 0;
4434
        else {
4435
            if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
4436
                goto efault;
4437
            ret = get_errno(read(arg1, p, arg3));
4438
            unlock_user(p, arg2, ret);
4439
        }
4440
        break;
4441
    case TARGET_NR_write:
4442
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
4443
            goto efault;
4444
        ret = get_errno(write(arg1, p, arg3));
4445
        unlock_user(p, arg2, 0);
4446
        break;
4447
    case TARGET_NR_open:
4448
        if (!(p = lock_user_string(arg1)))
4449
            goto efault;
4450
        ret = get_errno(open(path(p),
4451
                             target_to_host_bitmask(arg2, fcntl_flags_tbl),
4452
                             arg3));
4453
        unlock_user(p, arg1, 0);
4454
        break;
4455
#if defined(TARGET_NR_openat) && defined(__NR_openat)
4456
    case TARGET_NR_openat:
4457
        if (!(p = lock_user_string(arg2)))
4458
            goto efault;
4459
        ret = get_errno(sys_openat(arg1,
4460
                                   path(p),
4461
                                   target_to_host_bitmask(arg3, fcntl_flags_tbl),
4462
                                   arg4));
4463
        unlock_user(p, arg2, 0);
4464
        break;
4465
#endif
4466
    case TARGET_NR_close:
4467
        ret = get_errno(close(arg1));
4468
        break;
4469
    case TARGET_NR_brk:
4470
        ret = do_brk(arg1);
4471
        break;
4472
    case TARGET_NR_fork:
4473
        ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
4474
        break;
4475
#ifdef TARGET_NR_waitpid
4476
    case TARGET_NR_waitpid:
4477
        {
4478
            int status;
4479
            ret = get_errno(waitpid(arg1, &status, arg3));
4480
            if (!is_error(ret) && arg2
4481
                && put_user_s32(host_to_target_waitstatus(status), arg2))
4482
                goto efault;
4483
        }
4484
        break;
4485
#endif
4486
#ifdef TARGET_NR_waitid
4487
    case TARGET_NR_waitid:
4488
        {
4489
            siginfo_t info;
4490
            info.si_pid = 0;
4491
            ret = get_errno(waitid(arg1, arg2, &info, arg4));
4492
            if (!is_error(ret) && arg3 && info.si_pid != 0) {
4493
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
4494
                    goto efault;
4495
                host_to_target_siginfo(p, &info);
4496
                unlock_user(p, arg3, sizeof(target_siginfo_t));
4497
            }
4498
        }
4499
        break;
4500
#endif
4501
#ifdef TARGET_NR_creat /* not on alpha */
4502
    case TARGET_NR_creat:
4503
        if (!(p = lock_user_string(arg1)))
4504
            goto efault;
4505
        ret = get_errno(creat(p, arg2));
4506
        unlock_user(p, arg1, 0);
4507
        break;
4508
#endif
4509
    case TARGET_NR_link:
4510
        {
4511
            void * p2;
4512
            p = lock_user_string(arg1);
4513
            p2 = lock_user_string(arg2);
4514
            if (!p || !p2)
4515
                ret = -TARGET_EFAULT;
4516
            else
4517
                ret = get_errno(link(p, p2));
4518
            unlock_user(p2, arg2, 0);
4519
            unlock_user(p, arg1, 0);
4520
        }
4521
        break;
4522
#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
4523
    case TARGET_NR_linkat:
4524
        {
4525
            void * p2 = NULL;
4526
            if (!arg2 || !arg4)
4527
                goto efault;
4528
            p  = lock_user_string(arg2);
4529
            p2 = lock_user_string(arg4);
4530
            if (!p || !p2)
4531
                ret = -TARGET_EFAULT;
4532
            else
4533
                ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
4534
            unlock_user(p, arg2, 0);
4535
            unlock_user(p2, arg4, 0);
4536
        }
4537
        break;
4538
#endif
4539
    case TARGET_NR_unlink:
4540
        if (!(p = lock_user_string(arg1)))
4541
            goto efault;
4542
        ret = get_errno(unlink(p));
4543
        unlock_user(p, arg1, 0);
4544
        break;
4545
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
4546
    case TARGET_NR_unlinkat:
4547
        if (!(p = lock_user_string(arg2)))
4548
            goto efault;
4549
        ret = get_errno(sys_unlinkat(arg1, p, arg3));
4550
        unlock_user(p, arg2, 0);
4551
        break;
4552
#endif
4553
    case TARGET_NR_execve:
4554
        {
4555
            char **argp, **envp;
4556
            int argc, envc;
4557
            abi_ulong gp;
4558
            abi_ulong guest_argp;
4559
            abi_ulong guest_envp;
4560
            abi_ulong addr;
4561
            char **q;
4562

    
4563
            argc = 0;
4564
            guest_argp = arg2;
4565
            for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
4566
                if (get_user_ual(addr, gp))
4567
                    goto efault;
4568
                if (!addr)
4569
                    break;
4570
                argc++;
4571
            }
4572
            envc = 0;
4573
            guest_envp = arg3;
4574
            for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
4575
                if (get_user_ual(addr, gp))
4576
                    goto efault;
4577
                if (!addr)
4578
                    break;
4579
                envc++;
4580
            }
4581

    
4582
            argp = alloca((argc + 1) * sizeof(void *));
4583
            envp = alloca((envc + 1) * sizeof(void *));
4584

    
4585
            for (gp = guest_argp, q = argp; gp;
4586
                  gp += sizeof(abi_ulong), q++) {
4587
                if (get_user_ual(addr, gp))
4588
                    goto execve_efault;
4589
                if (!addr)
4590
                    break;
4591
                if (!(*q = lock_user_string(addr)))
4592
                    goto execve_efault;
4593
            }
4594
            *q = NULL;
4595

    
4596
            for (gp = guest_envp, q = envp; gp;
4597
                  gp += sizeof(abi_ulong), q++) {
4598
                if (get_user_ual(addr, gp))
4599
                    goto execve_efault;
4600
                if (!addr)
4601
                    break;
4602
                if (!(*q = lock_user_string(addr)))
4603
                    goto execve_efault;
4604
            }
4605
            *q = NULL;
4606

    
4607
            if (!(p = lock_user_string(arg1)))
4608
                goto execve_efault;
4609
            ret = get_errno(execve(p, argp, envp));
4610
            unlock_user(p, arg1, 0);
4611

    
4612
            goto execve_end;
4613

    
4614
        execve_efault:
4615
            ret = -TARGET_EFAULT;
4616

    
4617
        execve_end:
4618
            for (gp = guest_argp, q = argp; *q;
4619
                  gp += sizeof(abi_ulong), q++) {
4620
                if (get_user_ual(addr, gp)
4621
                    || !addr)
4622
                    break;
4623
                unlock_user(*q, addr, 0);
4624
            }
4625
            for (gp = guest_envp, q = envp; *q;
4626
                  gp += sizeof(abi_ulong), q++) {
4627
                if (get_user_ual(addr, gp)
4628
                    || !addr)
4629
                    break;
4630
                unlock_user(*q, addr, 0);
4631
            }
4632
        }
4633
        break;
4634
    case TARGET_NR_chdir:
4635
        if (!(p = lock_user_string(arg1)))
4636
            goto efault;
4637
        ret = get_errno(chdir(p));
4638
        unlock_user(p, arg1, 0);
4639
        break;
4640
#ifdef TARGET_NR_time
4641
    case TARGET_NR_time:
4642
        {
4643
            time_t host_time;
4644
            ret = get_errno(time(&host_time));
4645
            if (!is_error(ret)
4646
                && arg1
4647
                && put_user_sal(host_time, arg1))
4648
                goto efault;
4649
        }
4650
        break;
4651
#endif
4652
    case TARGET_NR_mknod:
4653
        if (!(p = lock_user_string(arg1)))
4654
            goto efault;
4655
        ret = get_errno(mknod(p, arg2, arg3));
4656
        unlock_user(p, arg1, 0);
4657
        break;
4658
#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
4659
    case TARGET_NR_mknodat:
4660
        if (!(p = lock_user_string(arg2)))
4661
            goto efault;
4662
        ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
4663
        unlock_user(p, arg2, 0);
4664
        break;
4665
#endif
4666
    case TARGET_NR_chmod:
4667
        if (!(p = lock_user_string(arg1)))
4668
            goto efault;
4669
        ret = get_errno(chmod(p, arg2));
4670
        unlock_user(p, arg1, 0);
4671
        break;
4672
#ifdef TARGET_NR_break
4673
    case TARGET_NR_break:
4674
        goto unimplemented;
4675
#endif
4676
#ifdef TARGET_NR_oldstat
4677
    case TARGET_NR_oldstat:
4678
        goto unimplemented;
4679
#endif
4680
    case TARGET_NR_lseek:
4681
        ret = get_errno(lseek(arg1, arg2, arg3));
4682
        break;
4683
#if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA)
4684
    /* Alpha specific */
4685
    case TARGET_NR_getxpid:
4686
        ((CPUAlphaState *)cpu_env)->ir[IR_A4] = getppid();
4687
        ret = get_errno(getpid());
4688
        break;
4689
#endif
4690
#ifdef TARGET_NR_getpid
4691
    case TARGET_NR_getpid:
4692
        ret = get_errno(getpid());
4693
        break;
4694
#endif
4695
    case TARGET_NR_mount:
4696
                {
4697
                        /* need to look at the data field */
4698
                        void *p2, *p3;
4699
                        p = lock_user_string(arg1);
4700
                        p2 = lock_user_string(arg2);
4701
                        p3 = lock_user_string(arg3);
4702
                        if (!p || !p2 || !p3)
4703
                            ret = -TARGET_EFAULT;
4704
                        else {
4705
                            /* FIXME - arg5 should be locked, but it isn't clear how to
4706
                             * do that since it's not guaranteed to be a NULL-terminated
4707
                             * string.
4708
                             */
4709
                            if ( ! arg5 )
4710
                                ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, NULL));
4711
                            else
4712
                                ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
4713
                        }
4714
                        unlock_user(p, arg1, 0);
4715
                        unlock_user(p2, arg2, 0);
4716
                        unlock_user(p3, arg3, 0);
4717
                        break;
4718
                }
4719
#ifdef TARGET_NR_umount
4720
    case TARGET_NR_umount:
4721
        if (!(p = lock_user_string(arg1)))
4722
            goto efault;
4723
        ret = get_errno(umount(p));
4724
        unlock_user(p, arg1, 0);
4725
        break;
4726
#endif
4727
#ifdef TARGET_NR_stime /* not on alpha */
4728
    case TARGET_NR_stime:
4729
        {
4730
            time_t host_time;
4731
            if (get_user_sal(host_time, arg1))
4732
                goto efault;
4733
            ret = get_errno(stime(&host_time));
4734
        }
4735
        break;
4736
#endif
4737
    case TARGET_NR_ptrace:
4738
        goto unimplemented;
4739
#ifdef TARGET_NR_alarm /* not on alpha */
4740
    case TARGET_NR_alarm:
4741
        ret = alarm(arg1);
4742
        break;
4743
#endif
4744
#ifdef TARGET_NR_oldfstat
4745
    case TARGET_NR_oldfstat:
4746
        goto unimplemented;
4747
#endif
4748
#ifdef TARGET_NR_pause /* not on alpha */
4749
    case TARGET_NR_pause:
4750
        ret = get_errno(pause());
4751
        break;
4752
#endif
4753
#ifdef TARGET_NR_utime
4754
    case TARGET_NR_utime:
4755
        {
4756
            struct utimbuf tbuf, *host_tbuf;
4757
            struct target_utimbuf *target_tbuf;
4758
            if (arg2) {
4759
                if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
4760
                    goto efault;
4761
                tbuf.actime = tswapl(target_tbuf->actime);
4762
                tbuf.modtime = tswapl(target_tbuf->modtime);
4763
                unlock_user_struct(target_tbuf, arg2, 0);
4764
                host_tbuf = &tbuf;
4765
            } else {
4766
                host_tbuf = NULL;
4767
            }
4768
            if (!(p = lock_user_string(arg1)))
4769
                goto efault;
4770
            ret = get_errno(utime(p, host_tbuf));
4771
            unlock_user(p, arg1, 0);
4772
        }
4773
        break;
4774
#endif
4775
    case TARGET_NR_utimes:
4776
        {
4777
            struct timeval *tvp, tv[2];
4778
            if (arg2) {
4779
                if (copy_from_user_timeval(&tv[0], arg2)
4780
                    || copy_from_user_timeval(&tv[1],
4781
                                              arg2 + sizeof(struct target_timeval)))
4782
                    goto efault;
4783
                tvp = tv;
4784
            } else {
4785
                tvp = NULL;
4786
            }
4787
            if (!(p = lock_user_string(arg1)))
4788
                goto efault;
4789
            ret = get_errno(utimes(p, tvp));
4790
            unlock_user(p, arg1, 0);
4791
        }
4792
        break;
4793
#if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
4794
    case TARGET_NR_futimesat:
4795
        {
4796
            struct timeval *tvp, tv[2];
4797
            if (arg3) {
4798
                if (copy_from_user_timeval(&tv[0], arg3)
4799
                    || copy_from_user_timeval(&tv[1],
4800
                                              arg3 + sizeof(struct target_timeval)))
4801
                    goto efault;
4802
                tvp = tv;
4803
            } else {
4804
                tvp = NULL;
4805
            }
4806
            if (!(p = lock_user_string(arg2)))
4807
                goto efault;
4808
            ret = get_errno(sys_futimesat(arg1, path(p), tvp));
4809
            unlock_user(p, arg2, 0);
4810
        }
4811
        break;
4812
#endif
4813
#ifdef TARGET_NR_stty
4814
    case TARGET_NR_stty:
4815
        goto unimplemented;
4816
#endif
4817
#ifdef TARGET_NR_gtty
4818
    case TARGET_NR_gtty:
4819
        goto unimplemented;
4820
#endif
4821
    case TARGET_NR_access:
4822
        if (!(p = lock_user_string(arg1)))
4823
            goto efault;
4824
        ret = get_errno(access(path(p), arg2));
4825
        unlock_user(p, arg1, 0);
4826
        break;
4827
#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
4828
    case TARGET_NR_faccessat:
4829
        if (!(p = lock_user_string(arg2)))
4830
            goto efault;
4831
        ret = get_errno(sys_faccessat(arg1, p, arg3));
4832
        unlock_user(p, arg2, 0);
4833
        break;
4834
#endif
4835
#ifdef TARGET_NR_nice /* not on alpha */
4836
    case TARGET_NR_nice:
4837
        ret = get_errno(nice(arg1));
4838
        break;
4839
#endif
4840
#ifdef TARGET_NR_ftime
4841
    case TARGET_NR_ftime:
4842
        goto unimplemented;
4843
#endif
4844
    case TARGET_NR_sync:
4845
        sync();
4846
        ret = 0;
4847
        break;
4848
    case TARGET_NR_kill:
4849
        ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
4850
        break;
4851
    case TARGET_NR_rename:
4852
        {
4853
            void *p2;
4854
            p = lock_user_string(arg1);
4855
            p2 = lock_user_string(arg2);
4856
            if (!p || !p2)
4857
                ret = -TARGET_EFAULT;
4858
            else
4859
                ret = get_errno(rename(p, p2));
4860
            unlock_user(p2, arg2, 0);
4861
            unlock_user(p, arg1, 0);
4862
        }
4863
        break;
4864
#if defined(TARGET_NR_renameat) && defined(__NR_renameat)
4865
    case TARGET_NR_renameat:
4866
        {
4867
            void *p2;
4868
            p  = lock_user_string(arg2);
4869
            p2 = lock_user_string(arg4);
4870
            if (!p || !p2)
4871
                ret = -TARGET_EFAULT;
4872
            else
4873
                ret = get_errno(sys_renameat(arg1, p, arg3, p2));
4874
            unlock_user(p2, arg4, 0);
4875
            unlock_user(p, arg2, 0);
4876
        }
4877
        break;
4878
#endif
4879
    case TARGET_NR_mkdir:
4880
        if (!(p = lock_user_string(arg1)))
4881
            goto efault;
4882
        ret = get_errno(mkdir(p, arg2));
4883
        unlock_user(p, arg1, 0);
4884
        break;
4885
#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
4886
    case TARGET_NR_mkdirat:
4887
        if (!(p = lock_user_string(arg2)))
4888
            goto efault;
4889
        ret = get_errno(sys_mkdirat(arg1, p, arg3));
4890
        unlock_user(p, arg2, 0);
4891
        break;
4892
#endif
4893
    case TARGET_NR_rmdir:
4894
        if (!(p = lock_user_string(arg1)))
4895
            goto efault;
4896
        ret = get_errno(rmdir(p));
4897
        unlock_user(p, arg1, 0);
4898
        break;
4899
    case TARGET_NR_dup:
4900
        ret = get_errno(dup(arg1));
4901
        break;
4902
    case TARGET_NR_pipe:
4903
        ret = do_pipe(cpu_env, arg1, 0, 0);
4904
        break;
4905
#ifdef TARGET_NR_pipe2
4906
    case TARGET_NR_pipe2:
4907
        ret = do_pipe(cpu_env, arg1, arg2, 1);
4908
        break;
4909
#endif
4910
    case TARGET_NR_times:
4911
        {
4912
            struct target_tms *tmsp;
4913
            struct tms tms;
4914
            ret = get_errno(times(&tms));
4915
            if (arg1) {
4916
                tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
4917
                if (!tmsp)
4918
                    goto efault;
4919
                tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
4920
                tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
4921
                tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
4922
                tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime));
4923
            }
4924
            if (!is_error(ret))
4925
                ret = host_to_target_clock_t(ret);
4926
        }
4927
        break;
4928
#ifdef TARGET_NR_prof
4929
    case TARGET_NR_prof:
4930
        goto unimplemented;
4931
#endif
4932
#ifdef TARGET_NR_signal
4933
    case TARGET_NR_signal:
4934
        goto unimplemented;
4935
#endif
4936
    case TARGET_NR_acct:
4937
        if (arg1 == 0) {
4938
            ret = get_errno(acct(NULL));
4939
        } else {
4940
            if (!(p = lock_user_string(arg1)))
4941
                goto efault;
4942
            ret = get_errno(acct(path(p)));
4943
            unlock_user(p, arg1, 0);
4944
        }
4945
        break;
4946
#ifdef TARGET_NR_umount2 /* not on alpha */
4947
    case TARGET_NR_umount2:
4948
        if (!(p = lock_user_string(arg1)))
4949
            goto efault;
4950
        ret = get_errno(umount2(p, arg2));
4951
        unlock_user(p, arg1, 0);
4952
        break;
4953
#endif
4954
#ifdef TARGET_NR_lock
4955
    case TARGET_NR_lock:
4956
        goto unimplemented;
4957
#endif
4958
    case TARGET_NR_ioctl:
4959
        ret = do_ioctl(arg1, arg2, arg3);
4960
        break;
4961
    case TARGET_NR_fcntl:
4962
        ret = do_fcntl(arg1, arg2, arg3);
4963
        break;
4964
#ifdef TARGET_NR_mpx
4965
    case TARGET_NR_mpx:
4966
        goto unimplemented;
4967
#endif
4968
    case TARGET_NR_setpgid:
4969
        ret = get_errno(setpgid(arg1, arg2));
4970
        break;
4971
#ifdef TARGET_NR_ulimit
4972
    case TARGET_NR_ulimit:
4973
        goto unimplemented;
4974
#endif
4975
#ifdef TARGET_NR_oldolduname
4976
    case TARGET_NR_oldolduname:
4977
        goto unimplemented;
4978
#endif
4979
    case TARGET_NR_umask:
4980
        ret = get_errno(umask(arg1));
4981
        break;
4982
    case TARGET_NR_chroot:
4983
        if (!(p = lock_user_string(arg1)))
4984
            goto efault;
4985
        ret = get_errno(chroot(p));
4986
        unlock_user(p, arg1, 0);
4987
        break;
4988
    case TARGET_NR_ustat:
4989
        goto unimplemented;
4990
    case TARGET_NR_dup2:
4991
        ret = get_errno(dup2(arg1, arg2));
4992
        break;
4993
#if defined(CONFIG_DUP3) && defined(TARGET_NR_dup3)
4994
    case TARGET_NR_dup3:
4995
        ret = get_errno(dup3(arg1, arg2, arg3));