Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ 465c9f06

History | View | Annotate | Download (202.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, write to the Free Software
18
 *  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19
 *  MA 02110-1301, USA.
20
 */
21
#include <stdlib.h>
22
#include <stdio.h>
23
#include <stdarg.h>
24
#include <string.h>
25
#include <elf.h>
26
#include <endian.h>
27
#include <errno.h>
28
#include <unistd.h>
29
#include <fcntl.h>
30
#include <time.h>
31
#include <limits.h>
32
#include <mqueue.h>
33
#include <sys/types.h>
34
#include <sys/ipc.h>
35
#include <sys/msg.h>
36
#include <sys/wait.h>
37
#include <sys/time.h>
38
#include <sys/stat.h>
39
#include <sys/mount.h>
40
#include <sys/prctl.h>
41
#include <sys/resource.h>
42
#include <sys/mman.h>
43
#include <sys/swap.h>
44
#include <signal.h>
45
#include <sched.h>
46
#include <sys/socket.h>
47
#include <sys/un.h>
48
#include <sys/uio.h>
49
#include <sys/poll.h>
50
#include <sys/times.h>
51
#include <sys/shm.h>
52
#include <sys/sem.h>
53
#include <sys/statfs.h>
54
#include <utime.h>
55
#include <sys/sysinfo.h>
56
#include <sys/utsname.h>
57
//#include <sys/user.h>
58
#include <netinet/ip.h>
59
#include <netinet/tcp.h>
60
#include <qemu-common.h>
61
#ifdef HAVE_GPROF
62
#include <sys/gmon.h>
63
#endif
64

    
65
#define termios host_termios
66
#define winsize host_winsize
67
#define termio host_termio
68
#define sgttyb host_sgttyb /* same as target */
69
#define tchars host_tchars /* same as target */
70
#define ltchars host_ltchars /* same as target */
71

    
72
#include <linux/termios.h>
73
#include <linux/unistd.h>
74
#include <linux/utsname.h>
75
#include <linux/cdrom.h>
76
#include <linux/hdreg.h>
77
#include <linux/soundcard.h>
78
#include <linux/kd.h>
79
#include <linux/mtio.h>
80
#include "linux_loop.h"
81

    
82
#include "qemu.h"
83
#include "qemu-common.h"
84

    
85
#if defined(USE_NPTL)
86
#include <linux/futex.h>
87
#define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
88
    CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
89
#else
90
/* XXX: Hardcode the above values.  */
91
#define CLONE_NPTL_FLAGS2 0
92
#endif
93

    
94
//#define DEBUG
95

    
96
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \
97
    || defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS)
98
/* 16 bit uid wrappers emulation */
99
#define USE_UID16
100
#endif
101

    
102
//#include <linux/msdos_fs.h>
103
#define        VFAT_IOCTL_READDIR_BOTH                _IOR('r', 1, struct linux_dirent [2])
104
#define        VFAT_IOCTL_READDIR_SHORT        _IOR('r', 2, struct linux_dirent [2])
105

    
106

    
107
#undef _syscall0
108
#undef _syscall1
109
#undef _syscall2
110
#undef _syscall3
111
#undef _syscall4
112
#undef _syscall5
113
#undef _syscall6
114

    
115
#define _syscall0(type,name)                \
116
static type name (void)                        \
117
{                                        \
118
        return syscall(__NR_##name);        \
119
}
120

    
121
#define _syscall1(type,name,type1,arg1)                \
122
static type name (type1 arg1)                        \
123
{                                                \
124
        return syscall(__NR_##name, arg1);        \
125
}
126

    
127
#define _syscall2(type,name,type1,arg1,type2,arg2)        \
128
static type name (type1 arg1,type2 arg2)                \
129
{                                                        \
130
        return syscall(__NR_##name, arg1, arg2);        \
131
}
132

    
133
#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)        \
134
static type name (type1 arg1,type2 arg2,type3 arg3)                \
135
{                                                                \
136
        return syscall(__NR_##name, arg1, arg2, arg3);                \
137
}
138

    
139
#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)        \
140
static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4)                        \
141
{                                                                                \
142
        return syscall(__NR_##name, arg1, arg2, arg3, arg4);                        \
143
}
144

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

    
152

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

    
161

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

    
191
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
192
#define __NR__llseek __NR_lseek
193
#endif
194

    
195
#ifdef __NR_gettid
196
_syscall0(int, gettid)
197
#else
198
/* This is a replacement for the host gettid() and must return a host
199
   errno. */
200
static int gettid(void) {
201
    return -ENOSYS;
202
}
203
#endif
204
#if TARGET_ABI_BITS == 32
205
_syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
206
#endif
207
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
208
_syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
209
#endif
210
_syscall2(int, sys_getpriority, int, which, int, who);
211
#if !defined (__x86_64__)
212
_syscall5(int, _llseek,  uint,  fd, ulong, hi, ulong, lo,
213
          loff_t *, res, uint, wh);
214
#endif
215
_syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
216
_syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
217
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
218
_syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
219
#endif
220
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
221
_syscall2(int,sys_tkill,int,tid,int,sig)
222
#endif
223
#ifdef __NR_exit_group
224
_syscall1(int,exit_group,int,error_code)
225
#endif
226
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
227
_syscall1(int,set_tid_address,int *,tidptr)
228
#endif
229
#if defined(USE_NPTL)
230
#if defined(TARGET_NR_futex) && defined(__NR_futex)
231
_syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
232
          const struct timespec *,timeout,int *,uaddr2,int,val3)
233
#endif
234
#endif
235

    
236
static bitmask_transtbl fcntl_flags_tbl[] = {
237
  { TARGET_O_ACCMODE,   TARGET_O_WRONLY,    O_ACCMODE,   O_WRONLY,    },
238
  { TARGET_O_ACCMODE,   TARGET_O_RDWR,      O_ACCMODE,   O_RDWR,      },
239
  { TARGET_O_CREAT,     TARGET_O_CREAT,     O_CREAT,     O_CREAT,     },
240
  { TARGET_O_EXCL,      TARGET_O_EXCL,      O_EXCL,      O_EXCL,      },
241
  { TARGET_O_NOCTTY,    TARGET_O_NOCTTY,    O_NOCTTY,    O_NOCTTY,    },
242
  { TARGET_O_TRUNC,     TARGET_O_TRUNC,     O_TRUNC,     O_TRUNC,     },
243
  { TARGET_O_APPEND,    TARGET_O_APPEND,    O_APPEND,    O_APPEND,    },
244
  { TARGET_O_NONBLOCK,  TARGET_O_NONBLOCK,  O_NONBLOCK,  O_NONBLOCK,  },
245
  { TARGET_O_SYNC,      TARGET_O_SYNC,      O_SYNC,      O_SYNC,      },
246
  { TARGET_FASYNC,      TARGET_FASYNC,      FASYNC,      FASYNC,      },
247
  { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
248
  { TARGET_O_NOFOLLOW,  TARGET_O_NOFOLLOW,  O_NOFOLLOW,  O_NOFOLLOW,  },
249
  { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
250
#if defined(O_DIRECT)
251
  { TARGET_O_DIRECT,    TARGET_O_DIRECT,    O_DIRECT,    O_DIRECT,    },
252
#endif
253
  { 0, 0, 0, 0 }
254
};
255

    
256
#define COPY_UTSNAME_FIELD(dest, src) \
257
  do { \
258
      /* __NEW_UTS_LEN doesn't include terminating null */ \
259
      (void) strncpy((dest), (src), __NEW_UTS_LEN); \
260
      (dest)[__NEW_UTS_LEN] = '\0'; \
261
  } while (0)
262

    
263
static int sys_uname(struct new_utsname *buf)
264
{
265
  struct utsname uts_buf;
266

    
267
  if (uname(&uts_buf) < 0)
268
      return (-1);
269

    
270
  /*
271
   * Just in case these have some differences, we
272
   * translate utsname to new_utsname (which is the
273
   * struct linux kernel uses).
274
   */
275

    
276
  bzero(buf, sizeof (*buf));
277
  COPY_UTSNAME_FIELD(buf->sysname, uts_buf.sysname);
278
  COPY_UTSNAME_FIELD(buf->nodename, uts_buf.nodename);
279
  COPY_UTSNAME_FIELD(buf->release, uts_buf.release);
280
  COPY_UTSNAME_FIELD(buf->version, uts_buf.version);
281
  COPY_UTSNAME_FIELD(buf->machine, uts_buf.machine);
282
#ifdef _GNU_SOURCE
283
  COPY_UTSNAME_FIELD(buf->domainname, uts_buf.domainname);
284
#endif
285
  return (0);
286

    
287
#undef COPY_UTSNAME_FIELD
288
}
289

    
290
static int sys_getcwd1(char *buf, size_t size)
291
{
292
  if (getcwd(buf, size) == NULL) {
293
      /* getcwd() sets errno */
294
      return (-1);
295
  }
296
  return strlen(buf)+1;
297
}
298

    
299
#ifdef CONFIG_ATFILE
300
/*
301
 * Host system seems to have atfile syscall stubs available.  We
302
 * now enable them one by one as specified by target syscall_nr.h.
303
 */
304

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

    
376
      /*
377
       * Get the 'mode' parameter and translate it to
378
       * host bits.
379
       */
380
      va_start(ap, flags);
381
      mode = va_arg(ap, mode_t);
382
      mode = target_to_host_bitmask(mode, fcntl_flags_tbl);
383
      va_end(ap);
384

    
385
      return (openat(dirfd, pathname, flags, mode));
386
  }
387
  return (openat(dirfd, pathname, flags));
388
}
389
#endif
390
#ifdef TARGET_NR_readlinkat
391
static int sys_readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz)
392
{
393
  return (readlinkat(dirfd, pathname, buf, bufsiz));
394
}
395
#endif
396
#ifdef TARGET_NR_renameat
397
static int sys_renameat(int olddirfd, const char *oldpath,
398
    int newdirfd, const char *newpath)
399
{
400
  return (renameat(olddirfd, oldpath, newdirfd, newpath));
401
}
402
#endif
403
#ifdef TARGET_NR_symlinkat
404
static int sys_symlinkat(const char *oldpath, int newdirfd, const char *newpath)
405
{
406
  return (symlinkat(oldpath, newdirfd, newpath));
407
}
408
#endif
409
#ifdef TARGET_NR_unlinkat
410
static int sys_unlinkat(int dirfd, const char *pathname, int flags)
411
{
412
  return (unlinkat(dirfd, pathname, flags));
413
}
414
#endif
415
#ifdef TARGET_NR_utimensat
416
static int sys_utimensat(int dirfd, const char *pathname,
417
    const struct timespec times[2], int flags)
418
{
419
  return (utimensat(dirfd, pathname, times, flags));
420
}
421
#endif
422
#else /* !CONFIG_ATFILE */
423

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

    
485
#endif /* CONFIG_ATFILE */
486

    
487
#ifdef CONFIG_INOTIFY
488
#include <sys/inotify.h>
489

    
490
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
491
static int sys_inotify_init(void)
492
{
493
  return (inotify_init());
494
}
495
#endif
496
#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
497
static int sys_inotify_add_watch(int fd,const char *pathname, int32_t mask)
498
{
499
  return (inotify_add_watch(fd, pathname, mask));
500
}
501
#endif
502
#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
503
static int sys_inotify_rm_watch(int fd, int32_t wd)
504
{
505
  return (inotify_rm_watch(fd, wd));
506
}
507
#endif
508
#else
509
/* Userspace can usually survive runtime without inotify */
510
#undef TARGET_NR_inotify_init
511
#undef TARGET_NR_inotify_add_watch
512
#undef TARGET_NR_inotify_rm_watch
513
#endif /* CONFIG_INOTIFY  */
514

    
515

    
516
extern int personality(int);
517
extern int flock(int, int);
518
extern int setfsuid(int);
519
extern int setfsgid(int);
520
extern int setgroups(int, gid_t *);
521

    
522
#define ERRNO_TABLE_SIZE 1200
523

    
524
/* target_to_host_errno_table[] is initialized from
525
 * host_to_target_errno_table[] in syscall_init(). */
526
static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
527
};
528

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

    
641
static inline int host_to_target_errno(int err)
642
{
643
    if(host_to_target_errno_table[err])
644
        return host_to_target_errno_table[err];
645
    return err;
646
}
647

    
648
static inline int target_to_host_errno(int err)
649
{
650
    if (target_to_host_errno_table[err])
651
        return target_to_host_errno_table[err];
652
    return err;
653
}
654

    
655
static inline abi_long get_errno(abi_long ret)
656
{
657
    if (ret == -1)
658
        return -host_to_target_errno(errno);
659
    else
660
        return ret;
661
}
662

    
663
static inline int is_error(abi_long ret)
664
{
665
    return (abi_ulong)ret >= (abi_ulong)(-4096);
666
}
667

    
668
char *target_strerror(int err)
669
{
670
    return strerror(target_to_host_errno(err));
671
}
672

    
673
static abi_ulong target_brk;
674
static abi_ulong target_original_brk;
675

    
676
void target_set_brk(abi_ulong new_brk)
677
{
678
    target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
679
}
680

    
681
/* do_brk() must return target values and target errnos. */
682
abi_long do_brk(abi_ulong new_brk)
683
{
684
    abi_ulong brk_page;
685
    abi_long mapped_addr;
686
    int        new_alloc_size;
687

    
688
    if (!new_brk)
689
        return target_brk;
690
    if (new_brk < target_original_brk)
691
        return target_brk;
692

    
693
    brk_page = HOST_PAGE_ALIGN(target_brk);
694

    
695
    /* If the new brk is less than this, set it and we're done... */
696
    if (new_brk < brk_page) {
697
        target_brk = new_brk;
698
            return target_brk;
699
    }
700

    
701
    /* We need to allocate more memory after the brk... */
702
    new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
703
    mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
704
                                        PROT_READ|PROT_WRITE,
705
                                        MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
706

    
707
    if (!is_error(mapped_addr))
708
        target_brk = new_brk;
709
    
710
    return target_brk;
711
}
712

    
713
static inline abi_long copy_from_user_fdset(fd_set *fds,
714
                                            abi_ulong target_fds_addr,
715
                                            int n)
716
{
717
    int i, nw, j, k;
718
    abi_ulong b, *target_fds;
719

    
720
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
721
    if (!(target_fds = lock_user(VERIFY_READ,
722
                                 target_fds_addr,
723
                                 sizeof(abi_ulong) * nw,
724
                                 1)))
725
        return -TARGET_EFAULT;
726

    
727
    FD_ZERO(fds);
728
    k = 0;
729
    for (i = 0; i < nw; i++) {
730
        /* grab the abi_ulong */
731
        __get_user(b, &target_fds[i]);
732
        for (j = 0; j < TARGET_ABI_BITS; j++) {
733
            /* check the bit inside the abi_ulong */
734
            if ((b >> j) & 1)
735
                FD_SET(k, fds);
736
            k++;
737
        }
738
    }
739

    
740
    unlock_user(target_fds, target_fds_addr, 0);
741

    
742
    return 0;
743
}
744

    
745
static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
746
                                          const fd_set *fds,
747
                                          int n)
748
{
749
    int i, nw, j, k;
750
    abi_long v;
751
    abi_ulong *target_fds;
752

    
753
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
754
    if (!(target_fds = lock_user(VERIFY_WRITE,
755
                                 target_fds_addr,
756
                                 sizeof(abi_ulong) * nw,
757
                                 0)))
758
        return -TARGET_EFAULT;
759

    
760
    k = 0;
761
    for (i = 0; i < nw; i++) {
762
        v = 0;
763
        for (j = 0; j < TARGET_ABI_BITS; j++) {
764
            v |= ((FD_ISSET(k, fds) != 0) << j);
765
            k++;
766
        }
767
        __put_user(v, &target_fds[i]);
768
    }
769

    
770
    unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
771

    
772
    return 0;
773
}
774

    
775
#if defined(__alpha__)
776
#define HOST_HZ 1024
777
#else
778
#define HOST_HZ 100
779
#endif
780

    
781
static inline abi_long host_to_target_clock_t(long ticks)
782
{
783
#if HOST_HZ == TARGET_HZ
784
    return ticks;
785
#else
786
    return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
787
#endif
788
}
789

    
790
static inline abi_long host_to_target_rusage(abi_ulong target_addr,
791
                                             const struct rusage *rusage)
792
{
793
    struct target_rusage *target_rusage;
794

    
795
    if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
796
        return -TARGET_EFAULT;
797
    target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
798
    target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
799
    target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
800
    target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec);
801
    target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss);
802
    target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss);
803
    target_rusage->ru_idrss = tswapl(rusage->ru_idrss);
804
    target_rusage->ru_isrss = tswapl(rusage->ru_isrss);
805
    target_rusage->ru_minflt = tswapl(rusage->ru_minflt);
806
    target_rusage->ru_majflt = tswapl(rusage->ru_majflt);
807
    target_rusage->ru_nswap = tswapl(rusage->ru_nswap);
808
    target_rusage->ru_inblock = tswapl(rusage->ru_inblock);
809
    target_rusage->ru_oublock = tswapl(rusage->ru_oublock);
810
    target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd);
811
    target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv);
812
    target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);
813
    target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
814
    target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
815
    unlock_user_struct(target_rusage, target_addr, 1);
816

    
817
    return 0;
818
}
819

    
820
static inline abi_long copy_from_user_timeval(struct timeval *tv,
821
                                              abi_ulong target_tv_addr)
822
{
823
    struct target_timeval *target_tv;
824

    
825
    if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
826
        return -TARGET_EFAULT;
827

    
828
    __get_user(tv->tv_sec, &target_tv->tv_sec);
829
    __get_user(tv->tv_usec, &target_tv->tv_usec);
830

    
831
    unlock_user_struct(target_tv, target_tv_addr, 0);
832

    
833
    return 0;
834
}
835

    
836
static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
837
                                            const struct timeval *tv)
838
{
839
    struct target_timeval *target_tv;
840

    
841
    if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
842
        return -TARGET_EFAULT;
843

    
844
    __put_user(tv->tv_sec, &target_tv->tv_sec);
845
    __put_user(tv->tv_usec, &target_tv->tv_usec);
846

    
847
    unlock_user_struct(target_tv, target_tv_addr, 1);
848

    
849
    return 0;
850
}
851

    
852
static inline abi_long copy_from_user_mq_attr(struct mq_attr *attr,
853
                                              abi_ulong target_mq_attr_addr)
854
{
855
    struct target_mq_attr *target_mq_attr;
856

    
857
    if (!lock_user_struct(VERIFY_READ, target_mq_attr,
858
                          target_mq_attr_addr, 1))
859
        return -TARGET_EFAULT;
860

    
861
    __get_user(attr->mq_flags, &target_mq_attr->mq_flags);
862
    __get_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
863
    __get_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
864
    __get_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
865

    
866
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0);
867

    
868
    return 0;
869
}
870

    
871
static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr,
872
                                            const struct mq_attr *attr)
873
{
874
    struct target_mq_attr *target_mq_attr;
875

    
876
    if (!lock_user_struct(VERIFY_WRITE, target_mq_attr,
877
                          target_mq_attr_addr, 0))
878
        return -TARGET_EFAULT;
879

    
880
    __put_user(attr->mq_flags, &target_mq_attr->mq_flags);
881
    __put_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
882
    __put_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
883
    __put_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
884

    
885
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1);
886

    
887
    return 0;
888
}
889

    
890
/* do_select() must return target values and target errnos. */
891
static abi_long do_select(int n,
892
                          abi_ulong rfd_addr, abi_ulong wfd_addr,
893
                          abi_ulong efd_addr, abi_ulong target_tv_addr)
894
{
895
    fd_set rfds, wfds, efds;
896
    fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
897
    struct timeval tv, *tv_ptr;
898
    abi_long ret;
899

    
900
    if (rfd_addr) {
901
        if (copy_from_user_fdset(&rfds, rfd_addr, n))
902
            return -TARGET_EFAULT;
903
        rfds_ptr = &rfds;
904
    } else {
905
        rfds_ptr = NULL;
906
    }
907
    if (wfd_addr) {
908
        if (copy_from_user_fdset(&wfds, wfd_addr, n))
909
            return -TARGET_EFAULT;
910
        wfds_ptr = &wfds;
911
    } else {
912
        wfds_ptr = NULL;
913
    }
914
    if (efd_addr) {
915
        if (copy_from_user_fdset(&efds, efd_addr, n))
916
            return -TARGET_EFAULT;
917
        efds_ptr = &efds;
918
    } else {
919
        efds_ptr = NULL;
920
    }
921

    
922
    if (target_tv_addr) {
923
        if (copy_from_user_timeval(&tv, target_tv_addr))
924
            return -TARGET_EFAULT;
925
        tv_ptr = &tv;
926
    } else {
927
        tv_ptr = NULL;
928
    }
929

    
930
    ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
931

    
932
    if (!is_error(ret)) {
933
        if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
934
            return -TARGET_EFAULT;
935
        if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
936
            return -TARGET_EFAULT;
937
        if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
938
            return -TARGET_EFAULT;
939

    
940
        if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
941
            return -TARGET_EFAULT;
942
    }
943

    
944
    return ret;
945
}
946

    
947
static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
948
                                               abi_ulong target_addr,
949
                                               socklen_t len)
950
{
951
    const socklen_t unix_maxlen = sizeof (struct sockaddr_un);
952
    sa_family_t sa_family;
953
    struct target_sockaddr *target_saddr;
954

    
955
    target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
956
    if (!target_saddr)
957
        return -TARGET_EFAULT;
958

    
959
    sa_family = tswap16(target_saddr->sa_family);
960

    
961
    /* Oops. The caller might send a incomplete sun_path; sun_path
962
     * must be terminated by \0 (see the manual page), but
963
     * unfortunately it is quite common to specify sockaddr_un
964
     * length as "strlen(x->sun_path)" while it should be
965
     * "strlen(...) + 1". We'll fix that here if needed.
966
     * Linux kernel has a similar feature.
967
     */
968

    
969
    if (sa_family == AF_UNIX) {
970
        if (len < unix_maxlen && len > 0) {
971
            char *cp = (char*)target_saddr;
972

    
973
            if ( cp[len-1] && !cp[len] )
974
                len++;
975
        }
976
        if (len > unix_maxlen)
977
            len = unix_maxlen;
978
    }
979

    
980
    memcpy(addr, target_saddr, len);
981
    addr->sa_family = sa_family;
982
    unlock_user(target_saddr, target_addr, 0);
983

    
984
    return 0;
985
}
986

    
987
static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
988
                                               struct sockaddr *addr,
989
                                               socklen_t len)
990
{
991
    struct target_sockaddr *target_saddr;
992

    
993
    target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
994
    if (!target_saddr)
995
        return -TARGET_EFAULT;
996
    memcpy(target_saddr, addr, len);
997
    target_saddr->sa_family = tswap16(addr->sa_family);
998
    unlock_user(target_saddr, target_addr, len);
999

    
1000
    return 0;
1001
}
1002

    
1003
/* ??? Should this also swap msgh->name?  */
1004
static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
1005
                                           struct target_msghdr *target_msgh)
1006
{
1007
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1008
    abi_long msg_controllen;
1009
    abi_ulong target_cmsg_addr;
1010
    struct target_cmsghdr *target_cmsg;
1011
    socklen_t space = 0;
1012
    
1013
    msg_controllen = tswapl(target_msgh->msg_controllen);
1014
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1015
        goto the_end;
1016
    target_cmsg_addr = tswapl(target_msgh->msg_control);
1017
    target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
1018
    if (!target_cmsg)
1019
        return -TARGET_EFAULT;
1020

    
1021
    while (cmsg && target_cmsg) {
1022
        void *data = CMSG_DATA(cmsg);
1023
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
1024

    
1025
        int len = tswapl(target_cmsg->cmsg_len)
1026
                  - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
1027

    
1028
        space += CMSG_SPACE(len);
1029
        if (space > msgh->msg_controllen) {
1030
            space -= CMSG_SPACE(len);
1031
            gemu_log("Host cmsg overflow\n");
1032
            break;
1033
        }
1034

    
1035
        cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
1036
        cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
1037
        cmsg->cmsg_len = CMSG_LEN(len);
1038

    
1039
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1040
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1041
            memcpy(data, target_data, len);
1042
        } else {
1043
            int *fd = (int *)data;
1044
            int *target_fd = (int *)target_data;
1045
            int i, numfds = len / sizeof(int);
1046

    
1047
            for (i = 0; i < numfds; i++)
1048
                fd[i] = tswap32(target_fd[i]);
1049
        }
1050

    
1051
        cmsg = CMSG_NXTHDR(msgh, cmsg);
1052
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1053
    }
1054
    unlock_user(target_cmsg, target_cmsg_addr, 0);
1055
 the_end:
1056
    msgh->msg_controllen = space;
1057
    return 0;
1058
}
1059

    
1060
/* ??? Should this also swap msgh->name?  */
1061
static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
1062
                                           struct msghdr *msgh)
1063
{
1064
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1065
    abi_long msg_controllen;
1066
    abi_ulong target_cmsg_addr;
1067
    struct target_cmsghdr *target_cmsg;
1068
    socklen_t space = 0;
1069

    
1070
    msg_controllen = tswapl(target_msgh->msg_controllen);
1071
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1072
        goto the_end;
1073
    target_cmsg_addr = tswapl(target_msgh->msg_control);
1074
    target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
1075
    if (!target_cmsg)
1076
        return -TARGET_EFAULT;
1077

    
1078
    while (cmsg && target_cmsg) {
1079
        void *data = CMSG_DATA(cmsg);
1080
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
1081

    
1082
        int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
1083

    
1084
        space += TARGET_CMSG_SPACE(len);
1085
        if (space > msg_controllen) {
1086
            space -= TARGET_CMSG_SPACE(len);
1087
            gemu_log("Target cmsg overflow\n");
1088
            break;
1089
        }
1090

    
1091
        target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
1092
        target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
1093
        target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
1094

    
1095
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1096
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1097
            memcpy(target_data, data, len);
1098
        } else {
1099
            int *fd = (int *)data;
1100
            int *target_fd = (int *)target_data;
1101
            int i, numfds = len / sizeof(int);
1102

    
1103
            for (i = 0; i < numfds; i++)
1104
                target_fd[i] = tswap32(fd[i]);
1105
        }
1106

    
1107
        cmsg = CMSG_NXTHDR(msgh, cmsg);
1108
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1109
    }
1110
    unlock_user(target_cmsg, target_cmsg_addr, space);
1111
 the_end:
1112
    target_msgh->msg_controllen = tswapl(space);
1113
    return 0;
1114
}
1115

    
1116
/* do_setsockopt() Must return target values and target errnos. */
1117
static abi_long do_setsockopt(int sockfd, int level, int optname,
1118
                              abi_ulong optval_addr, socklen_t optlen)
1119
{
1120
    abi_long ret;
1121
    int val;
1122

    
1123
    switch(level) {
1124
    case SOL_TCP:
1125
        /* TCP options all take an 'int' value.  */
1126
        if (optlen < sizeof(uint32_t))
1127
            return -TARGET_EINVAL;
1128

    
1129
        if (get_user_u32(val, optval_addr))
1130
            return -TARGET_EFAULT;
1131
        ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1132
        break;
1133
    case SOL_IP:
1134
        switch(optname) {
1135
        case IP_TOS:
1136
        case IP_TTL:
1137
        case IP_HDRINCL:
1138
        case IP_ROUTER_ALERT:
1139
        case IP_RECVOPTS:
1140
        case IP_RETOPTS:
1141
        case IP_PKTINFO:
1142
        case IP_MTU_DISCOVER:
1143
        case IP_RECVERR:
1144
        case IP_RECVTOS:
1145
#ifdef IP_FREEBIND
1146
        case IP_FREEBIND:
1147
#endif
1148
        case IP_MULTICAST_TTL:
1149
        case IP_MULTICAST_LOOP:
1150
            val = 0;
1151
            if (optlen >= sizeof(uint32_t)) {
1152
                if (get_user_u32(val, optval_addr))
1153
                    return -TARGET_EFAULT;
1154
            } else if (optlen >= 1) {
1155
                if (get_user_u8(val, optval_addr))
1156
                    return -TARGET_EFAULT;
1157
            }
1158
            ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1159
            break;
1160
        default:
1161
            goto unimplemented;
1162
        }
1163
        break;
1164
    case TARGET_SOL_SOCKET:
1165
        switch (optname) {
1166
            /* Options with 'int' argument.  */
1167
        case TARGET_SO_DEBUG:
1168
                optname = SO_DEBUG;
1169
                break;
1170
        case TARGET_SO_REUSEADDR:
1171
                optname = SO_REUSEADDR;
1172
                break;
1173
        case TARGET_SO_TYPE:
1174
                optname = SO_TYPE;
1175
                break;
1176
        case TARGET_SO_ERROR:
1177
                optname = SO_ERROR;
1178
                break;
1179
        case TARGET_SO_DONTROUTE:
1180
                optname = SO_DONTROUTE;
1181
                break;
1182
        case TARGET_SO_BROADCAST:
1183
                optname = SO_BROADCAST;
1184
                break;
1185
        case TARGET_SO_SNDBUF:
1186
                optname = SO_SNDBUF;
1187
                break;
1188
        case TARGET_SO_RCVBUF:
1189
                optname = SO_RCVBUF;
1190
                break;
1191
        case TARGET_SO_KEEPALIVE:
1192
                optname = SO_KEEPALIVE;
1193
                break;
1194
        case TARGET_SO_OOBINLINE:
1195
                optname = SO_OOBINLINE;
1196
                break;
1197
        case TARGET_SO_NO_CHECK:
1198
                optname = SO_NO_CHECK;
1199
                break;
1200
        case TARGET_SO_PRIORITY:
1201
                optname = SO_PRIORITY;
1202
                break;
1203
#ifdef SO_BSDCOMPAT
1204
        case TARGET_SO_BSDCOMPAT:
1205
                optname = SO_BSDCOMPAT;
1206
                break;
1207
#endif
1208
        case TARGET_SO_PASSCRED:
1209
                optname = SO_PASSCRED;
1210
                break;
1211
        case TARGET_SO_TIMESTAMP:
1212
                optname = SO_TIMESTAMP;
1213
                break;
1214
        case TARGET_SO_RCVLOWAT:
1215
                optname = SO_RCVLOWAT;
1216
                break;
1217
        case TARGET_SO_RCVTIMEO:
1218
                optname = SO_RCVTIMEO;
1219
                break;
1220
        case TARGET_SO_SNDTIMEO:
1221
                optname = SO_SNDTIMEO;
1222
                break;
1223
            break;
1224
        default:
1225
            goto unimplemented;
1226
        }
1227
        if (optlen < sizeof(uint32_t))
1228
            return -TARGET_EINVAL;
1229

    
1230
        if (get_user_u32(val, optval_addr))
1231
            return -TARGET_EFAULT;
1232
        ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
1233
        break;
1234
    default:
1235
    unimplemented:
1236
        gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
1237
        ret = -TARGET_ENOPROTOOPT;
1238
    }
1239
    return ret;
1240
}
1241

    
1242
/* do_getsockopt() Must return target values and target errnos. */
1243
static abi_long do_getsockopt(int sockfd, int level, int optname,
1244
                              abi_ulong optval_addr, abi_ulong optlen)
1245
{
1246
    abi_long ret;
1247
    int len, val;
1248
    socklen_t lv;
1249

    
1250
    switch(level) {
1251
    case TARGET_SOL_SOCKET:
1252
            level = SOL_SOCKET;
1253
        switch (optname) {
1254
        case TARGET_SO_LINGER:
1255
        case TARGET_SO_RCVTIMEO:
1256
        case TARGET_SO_SNDTIMEO:
1257
        case TARGET_SO_PEERCRED:
1258
        case TARGET_SO_PEERNAME:
1259
            /* These don't just return a single integer */
1260
            goto unimplemented;
1261
        default:
1262
            goto int_case;
1263
        }
1264
        break;
1265
    case SOL_TCP:
1266
        /* TCP options all take an 'int' value.  */
1267
    int_case:
1268
        if (get_user_u32(len, optlen))
1269
            return -TARGET_EFAULT;
1270
        if (len < 0)
1271
            return -TARGET_EINVAL;
1272
        lv = sizeof(int);
1273
        ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1274
        if (ret < 0)
1275
            return ret;
1276
        val = tswap32(val);
1277
        if (len > lv)
1278
            len = lv;
1279
        if (len == 4) {
1280
            if (put_user_u32(val, optval_addr))
1281
                return -TARGET_EFAULT;
1282
        } else {
1283
            if (put_user_u8(val, optval_addr))
1284
                return -TARGET_EFAULT;
1285
        }
1286
        if (put_user_u32(len, optlen))
1287
            return -TARGET_EFAULT;
1288
        break;
1289
    case SOL_IP:
1290
        switch(optname) {
1291
        case IP_TOS:
1292
        case IP_TTL:
1293
        case IP_HDRINCL:
1294
        case IP_ROUTER_ALERT:
1295
        case IP_RECVOPTS:
1296
        case IP_RETOPTS:
1297
        case IP_PKTINFO:
1298
        case IP_MTU_DISCOVER:
1299
        case IP_RECVERR:
1300
        case IP_RECVTOS:
1301
#ifdef IP_FREEBIND
1302
        case IP_FREEBIND:
1303
#endif
1304
        case IP_MULTICAST_TTL:
1305
        case IP_MULTICAST_LOOP:
1306
            if (get_user_u32(len, optlen))
1307
                return -TARGET_EFAULT;
1308
            if (len < 0)
1309
                return -TARGET_EINVAL;
1310
            lv = sizeof(int);
1311
            ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1312
            if (ret < 0)
1313
                return ret;
1314
            if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
1315
                len = 1;
1316
                if (put_user_u32(len, optlen)
1317
                    || put_user_u8(val, optval_addr))
1318
                    return -TARGET_EFAULT;
1319
            } else {
1320
                if (len > sizeof(int))
1321
                    len = sizeof(int);
1322
                if (put_user_u32(len, optlen)
1323
                    || put_user_u32(val, optval_addr))
1324
                    return -TARGET_EFAULT;
1325
            }
1326
            break;
1327
        default:
1328
            ret = -TARGET_ENOPROTOOPT;
1329
            break;
1330
        }
1331
        break;
1332
    default:
1333
    unimplemented:
1334
        gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1335
                 level, optname);
1336
        ret = -TARGET_EOPNOTSUPP;
1337
        break;
1338
    }
1339
    return ret;
1340
}
1341

    
1342
/* FIXME
1343
 * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1344
 * other lock functions have a return code of 0 for failure.
1345
 */
1346
static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1347
                           int count, int copy)
1348
{
1349
    struct target_iovec *target_vec;
1350
    abi_ulong base;
1351
    int i;
1352

    
1353
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1354
    if (!target_vec)
1355
        return -TARGET_EFAULT;
1356
    for(i = 0;i < count; i++) {
1357
        base = tswapl(target_vec[i].iov_base);
1358
        vec[i].iov_len = tswapl(target_vec[i].iov_len);
1359
        if (vec[i].iov_len != 0) {
1360
            vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
1361
            /* Don't check lock_user return value. We must call writev even
1362
               if a element has invalid base address. */
1363
        } else {
1364
            /* zero length pointer is ignored */
1365
            vec[i].iov_base = NULL;
1366
        }
1367
    }
1368
    unlock_user (target_vec, target_addr, 0);
1369
    return 0;
1370
}
1371

    
1372
static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1373
                             int count, int copy)
1374
{
1375
    struct target_iovec *target_vec;
1376
    abi_ulong base;
1377
    int i;
1378

    
1379
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1380
    if (!target_vec)
1381
        return -TARGET_EFAULT;
1382
    for(i = 0;i < count; i++) {
1383
        if (target_vec[i].iov_base) {
1384
            base = tswapl(target_vec[i].iov_base);
1385
            unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1386
        }
1387
    }
1388
    unlock_user (target_vec, target_addr, 0);
1389

    
1390
    return 0;
1391
}
1392

    
1393
/* do_socket() Must return target values and target errnos. */
1394
static abi_long do_socket(int domain, int type, int protocol)
1395
{
1396
#if defined(TARGET_MIPS)
1397
    switch(type) {
1398
    case TARGET_SOCK_DGRAM:
1399
        type = SOCK_DGRAM;
1400
        break;
1401
    case TARGET_SOCK_STREAM:
1402
        type = SOCK_STREAM;
1403
        break;
1404
    case TARGET_SOCK_RAW:
1405
        type = SOCK_RAW;
1406
        break;
1407
    case TARGET_SOCK_RDM:
1408
        type = SOCK_RDM;
1409
        break;
1410
    case TARGET_SOCK_SEQPACKET:
1411
        type = SOCK_SEQPACKET;
1412
        break;
1413
    case TARGET_SOCK_PACKET:
1414
        type = SOCK_PACKET;
1415
        break;
1416
    }
1417
#endif
1418
    if (domain == PF_NETLINK)
1419
        return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1420
    return get_errno(socket(domain, type, protocol));
1421
}
1422

    
1423
/* do_bind() Must return target values and target errnos. */
1424
static abi_long do_bind(int sockfd, abi_ulong target_addr,
1425
                        socklen_t addrlen)
1426
{
1427
    void *addr;
1428

    
1429
    if (addrlen < 0)
1430
        return -TARGET_EINVAL;
1431

    
1432
    addr = alloca(addrlen+1);
1433

    
1434
    target_to_host_sockaddr(addr, target_addr, addrlen);
1435
    return get_errno(bind(sockfd, addr, addrlen));
1436
}
1437

    
1438
/* do_connect() Must return target values and target errnos. */
1439
static abi_long do_connect(int sockfd, abi_ulong target_addr,
1440
                           socklen_t addrlen)
1441
{
1442
    void *addr;
1443

    
1444
    if (addrlen < 0)
1445
        return -TARGET_EINVAL;
1446

    
1447
    addr = alloca(addrlen);
1448

    
1449
    target_to_host_sockaddr(addr, target_addr, addrlen);
1450
    return get_errno(connect(sockfd, addr, addrlen));
1451
}
1452

    
1453
/* do_sendrecvmsg() Must return target values and target errnos. */
1454
static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1455
                               int flags, int send)
1456
{
1457
    abi_long ret, len;
1458
    struct target_msghdr *msgp;
1459
    struct msghdr msg;
1460
    int count;
1461
    struct iovec *vec;
1462
    abi_ulong target_vec;
1463

    
1464
    /* FIXME */
1465
    if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1466
                          msgp,
1467
                          target_msg,
1468
                          send ? 1 : 0))
1469
        return -TARGET_EFAULT;
1470
    if (msgp->msg_name) {
1471
        msg.msg_namelen = tswap32(msgp->msg_namelen);
1472
        msg.msg_name = alloca(msg.msg_namelen);
1473
        target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
1474
                                msg.msg_namelen);
1475
    } else {
1476
        msg.msg_name = NULL;
1477
        msg.msg_namelen = 0;
1478
    }
1479
    msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
1480
    msg.msg_control = alloca(msg.msg_controllen);
1481
    msg.msg_flags = tswap32(msgp->msg_flags);
1482

    
1483
    count = tswapl(msgp->msg_iovlen);
1484
    vec = alloca(count * sizeof(struct iovec));
1485
    target_vec = tswapl(msgp->msg_iov);
1486
    lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1487
    msg.msg_iovlen = count;
1488
    msg.msg_iov = vec;
1489

    
1490
    if (send) {
1491
        ret = target_to_host_cmsg(&msg, msgp);
1492
        if (ret == 0)
1493
            ret = get_errno(sendmsg(fd, &msg, flags));
1494
    } else {
1495
        ret = get_errno(recvmsg(fd, &msg, flags));
1496
        if (!is_error(ret)) {
1497
            len = ret;
1498
            ret = host_to_target_cmsg(msgp, &msg);
1499
            if (!is_error(ret))
1500
                ret = len;
1501
        }
1502
    }
1503
    unlock_iovec(vec, target_vec, count, !send);
1504
    unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1505
    return ret;
1506
}
1507

    
1508
/* do_accept() Must return target values and target errnos. */
1509
static abi_long do_accept(int fd, abi_ulong target_addr,
1510
                          abi_ulong target_addrlen_addr)
1511
{
1512
    socklen_t addrlen;
1513
    void *addr;
1514
    abi_long ret;
1515

    
1516
    if (get_user_u32(addrlen, target_addrlen_addr))
1517
        return -TARGET_EFAULT;
1518

    
1519
    if (addrlen < 0)
1520
        return -TARGET_EINVAL;
1521

    
1522
    addr = alloca(addrlen);
1523

    
1524
    ret = get_errno(accept(fd, addr, &addrlen));
1525
    if (!is_error(ret)) {
1526
        host_to_target_sockaddr(target_addr, addr, addrlen);
1527
        if (put_user_u32(addrlen, target_addrlen_addr))
1528
            ret = -TARGET_EFAULT;
1529
    }
1530
    return ret;
1531
}
1532

    
1533
/* do_getpeername() Must return target values and target errnos. */
1534
static abi_long do_getpeername(int fd, abi_ulong target_addr,
1535
                               abi_ulong target_addrlen_addr)
1536
{
1537
    socklen_t addrlen;
1538
    void *addr;
1539
    abi_long ret;
1540

    
1541
    if (get_user_u32(addrlen, target_addrlen_addr))
1542
        return -TARGET_EFAULT;
1543

    
1544
    if (addrlen < 0)
1545
        return -TARGET_EINVAL;
1546

    
1547
    addr = alloca(addrlen);
1548

    
1549
    ret = get_errno(getpeername(fd, addr, &addrlen));
1550
    if (!is_error(ret)) {
1551
        host_to_target_sockaddr(target_addr, addr, addrlen);
1552
        if (put_user_u32(addrlen, target_addrlen_addr))
1553
            ret = -TARGET_EFAULT;
1554
    }
1555
    return ret;
1556
}
1557

    
1558
/* do_getsockname() Must return target values and target errnos. */
1559
static abi_long do_getsockname(int fd, abi_ulong target_addr,
1560
                               abi_ulong target_addrlen_addr)
1561
{
1562
    socklen_t addrlen;
1563
    void *addr;
1564
    abi_long ret;
1565

    
1566
    if (target_addr == 0)
1567
       return get_errno(accept(fd, NULL, NULL));
1568

    
1569
    if (get_user_u32(addrlen, target_addrlen_addr))
1570
        return -TARGET_EFAULT;
1571

    
1572
    if (addrlen < 0)
1573
        return -TARGET_EINVAL;
1574

    
1575
    addr = alloca(addrlen);
1576

    
1577
    ret = get_errno(getsockname(fd, addr, &addrlen));
1578
    if (!is_error(ret)) {
1579
        host_to_target_sockaddr(target_addr, addr, addrlen);
1580
        if (put_user_u32(addrlen, target_addrlen_addr))
1581
            ret = -TARGET_EFAULT;
1582
    }
1583
    return ret;
1584
}
1585

    
1586
/* do_socketpair() Must return target values and target errnos. */
1587
static abi_long do_socketpair(int domain, int type, int protocol,
1588
                              abi_ulong target_tab_addr)
1589
{
1590
    int tab[2];
1591
    abi_long ret;
1592

    
1593
    ret = get_errno(socketpair(domain, type, protocol, tab));
1594
    if (!is_error(ret)) {
1595
        if (put_user_s32(tab[0], target_tab_addr)
1596
            || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1597
            ret = -TARGET_EFAULT;
1598
    }
1599
    return ret;
1600
}
1601

    
1602
/* do_sendto() Must return target values and target errnos. */
1603
static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
1604
                          abi_ulong target_addr, socklen_t addrlen)
1605
{
1606
    void *addr;
1607
    void *host_msg;
1608
    abi_long ret;
1609

    
1610
    if (addrlen < 0)
1611
        return -TARGET_EINVAL;
1612

    
1613
    host_msg = lock_user(VERIFY_READ, msg, len, 1);
1614
    if (!host_msg)
1615
        return -TARGET_EFAULT;
1616
    if (target_addr) {
1617
        addr = alloca(addrlen);
1618
        target_to_host_sockaddr(addr, target_addr, addrlen);
1619
        ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
1620
    } else {
1621
        ret = get_errno(send(fd, host_msg, len, flags));
1622
    }
1623
    unlock_user(host_msg, msg, 0);
1624
    return ret;
1625
}
1626

    
1627
/* do_recvfrom() Must return target values and target errnos. */
1628
static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
1629
                            abi_ulong target_addr,
1630
                            abi_ulong target_addrlen)
1631
{
1632
    socklen_t addrlen;
1633
    void *addr;
1634
    void *host_msg;
1635
    abi_long ret;
1636

    
1637
    host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
1638
    if (!host_msg)
1639
        return -TARGET_EFAULT;
1640
    if (target_addr) {
1641
        if (get_user_u32(addrlen, target_addrlen)) {
1642
            ret = -TARGET_EFAULT;
1643
            goto fail;
1644
        }
1645
        if (addrlen < 0) {
1646
            ret = -TARGET_EINVAL;
1647
            goto fail;
1648
        }
1649
        addr = alloca(addrlen);
1650
        ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
1651
    } else {
1652
        addr = NULL; /* To keep compiler quiet.  */
1653
        ret = get_errno(recv(fd, host_msg, len, flags));
1654
    }
1655
    if (!is_error(ret)) {
1656
        if (target_addr) {
1657
            host_to_target_sockaddr(target_addr, addr, addrlen);
1658
            if (put_user_u32(addrlen, target_addrlen)) {
1659
                ret = -TARGET_EFAULT;
1660
                goto fail;
1661
            }
1662
        }
1663
        unlock_user(host_msg, msg, len);
1664
    } else {
1665
fail:
1666
        unlock_user(host_msg, msg, 0);
1667
    }
1668
    return ret;
1669
}
1670

    
1671
#ifdef TARGET_NR_socketcall
1672
/* do_socketcall() Must return target values and target errnos. */
1673
static abi_long do_socketcall(int num, abi_ulong vptr)
1674
{
1675
    abi_long ret;
1676
    const int n = sizeof(abi_ulong);
1677

    
1678
    switch(num) {
1679
    case SOCKOP_socket:
1680
        {
1681
            int domain, type, protocol;
1682

    
1683
            if (get_user_s32(domain, vptr)
1684
                || get_user_s32(type, vptr + n)
1685
                || get_user_s32(protocol, vptr + 2 * n))
1686
                return -TARGET_EFAULT;
1687

    
1688
            ret = do_socket(domain, type, protocol);
1689
        }
1690
        break;
1691
    case SOCKOP_bind:
1692
        {
1693
            int sockfd;
1694
            abi_ulong target_addr;
1695
            socklen_t addrlen;
1696

    
1697
            if (get_user_s32(sockfd, vptr)
1698
                || get_user_ual(target_addr, vptr + n)
1699
                || get_user_u32(addrlen, vptr + 2 * n))
1700
                return -TARGET_EFAULT;
1701

    
1702
            ret = do_bind(sockfd, target_addr, addrlen);
1703
        }
1704
        break;
1705
    case SOCKOP_connect:
1706
        {
1707
            int sockfd;
1708
            abi_ulong target_addr;
1709
            socklen_t addrlen;
1710

    
1711
            if (get_user_s32(sockfd, vptr)
1712
                || get_user_ual(target_addr, vptr + n)
1713
                || get_user_u32(addrlen, vptr + 2 * n))
1714
                return -TARGET_EFAULT;
1715

    
1716
            ret = do_connect(sockfd, target_addr, addrlen);
1717
        }
1718
        break;
1719
    case SOCKOP_listen:
1720
        {
1721
            int sockfd, backlog;
1722

    
1723
            if (get_user_s32(sockfd, vptr)
1724
                || get_user_s32(backlog, vptr + n))
1725
                return -TARGET_EFAULT;
1726

    
1727
            ret = get_errno(listen(sockfd, backlog));
1728
        }
1729
        break;
1730
    case SOCKOP_accept:
1731
        {
1732
            int sockfd;
1733
            abi_ulong target_addr, target_addrlen;
1734

    
1735
            if (get_user_s32(sockfd, vptr)
1736
                || get_user_ual(target_addr, vptr + n)
1737
                || get_user_u32(target_addrlen, vptr + 2 * n))
1738
                return -TARGET_EFAULT;
1739

    
1740
            ret = do_accept(sockfd, target_addr, target_addrlen);
1741
        }
1742
        break;
1743
    case SOCKOP_getsockname:
1744
        {
1745
            int sockfd;
1746
            abi_ulong target_addr, target_addrlen;
1747

    
1748
            if (get_user_s32(sockfd, vptr)
1749
                || get_user_ual(target_addr, vptr + n)
1750
                || get_user_u32(target_addrlen, vptr + 2 * n))
1751
                return -TARGET_EFAULT;
1752

    
1753
            ret = do_getsockname(sockfd, target_addr, target_addrlen);
1754
        }
1755
        break;
1756
    case SOCKOP_getpeername:
1757
        {
1758
            int sockfd;
1759
            abi_ulong target_addr, target_addrlen;
1760

    
1761
            if (get_user_s32(sockfd, vptr)
1762
                || get_user_ual(target_addr, vptr + n)
1763
                || get_user_u32(target_addrlen, vptr + 2 * n))
1764
                return -TARGET_EFAULT;
1765

    
1766
            ret = do_getpeername(sockfd, target_addr, target_addrlen);
1767
        }
1768
        break;
1769
    case SOCKOP_socketpair:
1770
        {
1771
            int domain, type, protocol;
1772
            abi_ulong tab;
1773

    
1774
            if (get_user_s32(domain, vptr)
1775
                || get_user_s32(type, vptr + n)
1776
                || get_user_s32(protocol, vptr + 2 * n)
1777
                || get_user_ual(tab, vptr + 3 * n))
1778
                return -TARGET_EFAULT;
1779

    
1780
            ret = do_socketpair(domain, type, protocol, tab);
1781
        }
1782
        break;
1783
    case SOCKOP_send:
1784
        {
1785
            int sockfd;
1786
            abi_ulong msg;
1787
            size_t len;
1788
            int flags;
1789

    
1790
            if (get_user_s32(sockfd, vptr)
1791
                || get_user_ual(msg, vptr + n)
1792
                || get_user_ual(len, vptr + 2 * n)
1793
                || get_user_s32(flags, vptr + 3 * n))
1794
                return -TARGET_EFAULT;
1795

    
1796
            ret = do_sendto(sockfd, msg, len, flags, 0, 0);
1797
        }
1798
        break;
1799
    case SOCKOP_recv:
1800
        {
1801
            int sockfd;
1802
            abi_ulong msg;
1803
            size_t len;
1804
            int flags;
1805

    
1806
            if (get_user_s32(sockfd, vptr)
1807
                || get_user_ual(msg, vptr + n)
1808
                || get_user_ual(len, vptr + 2 * n)
1809
                || get_user_s32(flags, vptr + 3 * n))
1810
                return -TARGET_EFAULT;
1811

    
1812
            ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
1813
        }
1814
        break;
1815
    case SOCKOP_sendto:
1816
        {
1817
            int sockfd;
1818
            abi_ulong msg;
1819
            size_t len;
1820
            int flags;
1821
            abi_ulong addr;
1822
            socklen_t addrlen;
1823

    
1824
            if (get_user_s32(sockfd, vptr)
1825
                || get_user_ual(msg, vptr + n)
1826
                || get_user_ual(len, vptr + 2 * n)
1827
                || get_user_s32(flags, vptr + 3 * n)
1828
                || get_user_ual(addr, vptr + 4 * n)
1829
                || get_user_u32(addrlen, vptr + 5 * n))
1830
                return -TARGET_EFAULT;
1831

    
1832
            ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
1833
        }
1834
        break;
1835
    case SOCKOP_recvfrom:
1836
        {
1837
            int sockfd;
1838
            abi_ulong msg;
1839
            size_t len;
1840
            int flags;
1841
            abi_ulong addr;
1842
            socklen_t addrlen;
1843

    
1844
            if (get_user_s32(sockfd, vptr)
1845
                || get_user_ual(msg, vptr + n)
1846
                || get_user_ual(len, vptr + 2 * n)
1847
                || get_user_s32(flags, vptr + 3 * n)
1848
                || get_user_ual(addr, vptr + 4 * n)
1849
                || get_user_u32(addrlen, vptr + 5 * n))
1850
                return -TARGET_EFAULT;
1851

    
1852
            ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
1853
        }
1854
        break;
1855
    case SOCKOP_shutdown:
1856
        {
1857
            int sockfd, how;
1858

    
1859
            if (get_user_s32(sockfd, vptr)
1860
                || get_user_s32(how, vptr + n))
1861
                return -TARGET_EFAULT;
1862

    
1863
            ret = get_errno(shutdown(sockfd, how));
1864
        }
1865
        break;
1866
    case SOCKOP_sendmsg:
1867
    case SOCKOP_recvmsg:
1868
        {
1869
            int fd;
1870
            abi_ulong target_msg;
1871
            int flags;
1872

    
1873
            if (get_user_s32(fd, vptr)
1874
                || get_user_ual(target_msg, vptr + n)
1875
                || get_user_s32(flags, vptr + 2 * n))
1876
                return -TARGET_EFAULT;
1877

    
1878
            ret = do_sendrecvmsg(fd, target_msg, flags,
1879
                                 (num == SOCKOP_sendmsg));
1880
        }
1881
        break;
1882
    case SOCKOP_setsockopt:
1883
        {
1884
            int sockfd;
1885
            int level;
1886
            int optname;
1887
            abi_ulong optval;
1888
            socklen_t optlen;
1889

    
1890
            if (get_user_s32(sockfd, vptr)
1891
                || get_user_s32(level, vptr + n)
1892
                || get_user_s32(optname, vptr + 2 * n)
1893
                || get_user_ual(optval, vptr + 3 * n)
1894
                || get_user_u32(optlen, vptr + 4 * n))
1895
                return -TARGET_EFAULT;
1896

    
1897
            ret = do_setsockopt(sockfd, level, optname, optval, optlen);
1898
        }
1899
        break;
1900
    case SOCKOP_getsockopt:
1901
        {
1902
            int sockfd;
1903
            int level;
1904
            int optname;
1905
            abi_ulong optval;
1906
            socklen_t optlen;
1907

    
1908
            if (get_user_s32(sockfd, vptr)
1909
                || get_user_s32(level, vptr + n)
1910
                || get_user_s32(optname, vptr + 2 * n)
1911
                || get_user_ual(optval, vptr + 3 * n)
1912
                || get_user_u32(optlen, vptr + 4 * n))
1913
                return -TARGET_EFAULT;
1914

    
1915
            ret = do_getsockopt(sockfd, level, optname, optval, optlen);
1916
        }
1917
        break;
1918
    default:
1919
        gemu_log("Unsupported socketcall: %d\n", num);
1920
        ret = -TARGET_ENOSYS;
1921
        break;
1922
    }
1923
    return ret;
1924
}
1925
#endif
1926

    
1927
#ifdef TARGET_NR_ipc
1928
#define N_SHM_REGIONS        32
1929

    
1930
static struct shm_region {
1931
    abi_ulong        start;
1932
    abi_ulong        size;
1933
} shm_regions[N_SHM_REGIONS];
1934
#endif
1935

    
1936
struct target_ipc_perm
1937
{
1938
    abi_long __key;
1939
    abi_ulong uid;
1940
    abi_ulong gid;
1941
    abi_ulong cuid;
1942
    abi_ulong cgid;
1943
    unsigned short int mode;
1944
    unsigned short int __pad1;
1945
    unsigned short int __seq;
1946
    unsigned short int __pad2;
1947
    abi_ulong __unused1;
1948
    abi_ulong __unused2;
1949
};
1950

    
1951
struct target_semid_ds
1952
{
1953
  struct target_ipc_perm sem_perm;
1954
  abi_ulong sem_otime;
1955
  abi_ulong __unused1;
1956
  abi_ulong sem_ctime;
1957
  abi_ulong __unused2;
1958
  abi_ulong sem_nsems;
1959
  abi_ulong __unused3;
1960
  abi_ulong __unused4;
1961
};
1962

    
1963
static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
1964
                                               abi_ulong target_addr)
1965
{
1966
    struct target_ipc_perm *target_ip;
1967
    struct target_semid_ds *target_sd;
1968

    
1969
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
1970
        return -TARGET_EFAULT;
1971
    target_ip=&(target_sd->sem_perm);
1972
    host_ip->__key = tswapl(target_ip->__key);
1973
    host_ip->uid = tswapl(target_ip->uid);
1974
    host_ip->gid = tswapl(target_ip->gid);
1975
    host_ip->cuid = tswapl(target_ip->cuid);
1976
    host_ip->cgid = tswapl(target_ip->cgid);
1977
    host_ip->mode = tswapl(target_ip->mode);
1978
    unlock_user_struct(target_sd, target_addr, 0);
1979
    return 0;
1980
}
1981

    
1982
static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
1983
                                               struct ipc_perm *host_ip)
1984
{
1985
    struct target_ipc_perm *target_ip;
1986
    struct target_semid_ds *target_sd;
1987

    
1988
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
1989
        return -TARGET_EFAULT;
1990
    target_ip = &(target_sd->sem_perm);
1991
    target_ip->__key = tswapl(host_ip->__key);
1992
    target_ip->uid = tswapl(host_ip->uid);
1993
    target_ip->gid = tswapl(host_ip->gid);
1994
    target_ip->cuid = tswapl(host_ip->cuid);
1995
    target_ip->cgid = tswapl(host_ip->cgid);
1996
    target_ip->mode = tswapl(host_ip->mode);
1997
    unlock_user_struct(target_sd, target_addr, 1);
1998
    return 0;
1999
}
2000

    
2001
static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
2002
                                               abi_ulong target_addr)
2003
{
2004
    struct target_semid_ds *target_sd;
2005

    
2006
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2007
        return -TARGET_EFAULT;
2008
    if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr))
2009
        return -TARGET_EFAULT;
2010
    host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
2011
    host_sd->sem_otime = tswapl(target_sd->sem_otime);
2012
    host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
2013
    unlock_user_struct(target_sd, target_addr, 0);
2014
    return 0;
2015
}
2016

    
2017
static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
2018
                                               struct semid_ds *host_sd)
2019
{
2020
    struct target_semid_ds *target_sd;
2021

    
2022
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2023
        return -TARGET_EFAULT;
2024
    if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
2025
        return -TARGET_EFAULT;;
2026
    target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
2027
    target_sd->sem_otime = tswapl(host_sd->sem_otime);
2028
    target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
2029
    unlock_user_struct(target_sd, target_addr, 1);
2030
    return 0;
2031
}
2032

    
2033
struct target_seminfo {
2034
    int semmap;
2035
    int semmni;
2036
    int semmns;
2037
    int semmnu;
2038
    int semmsl;
2039
    int semopm;
2040
    int semume;
2041
    int semusz;
2042
    int semvmx;
2043
    int semaem;
2044
};
2045

    
2046
static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
2047
                                              struct seminfo *host_seminfo)
2048
{
2049
    struct target_seminfo *target_seminfo;
2050
    if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
2051
        return -TARGET_EFAULT;
2052
    __put_user(host_seminfo->semmap, &target_seminfo->semmap);
2053
    __put_user(host_seminfo->semmni, &target_seminfo->semmni);
2054
    __put_user(host_seminfo->semmns, &target_seminfo->semmns);
2055
    __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
2056
    __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
2057
    __put_user(host_seminfo->semopm, &target_seminfo->semopm);
2058
    __put_user(host_seminfo->semume, &target_seminfo->semume);
2059
    __put_user(host_seminfo->semusz, &target_seminfo->semusz);
2060
    __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
2061
    __put_user(host_seminfo->semaem, &target_seminfo->semaem);
2062
    unlock_user_struct(target_seminfo, target_addr, 1);
2063
    return 0;
2064
}
2065

    
2066
union semun {
2067
        int val;
2068
        struct semid_ds *buf;
2069
        unsigned short *array;
2070
        struct seminfo *__buf;
2071
};
2072

    
2073
union target_semun {
2074
        int val;
2075
        abi_ulong buf;
2076
        abi_ulong array;
2077
        abi_ulong __buf;
2078
};
2079

    
2080
static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
2081
                                               abi_ulong target_addr)
2082
{
2083
    int nsems;
2084
    unsigned short *array;
2085
    union semun semun;
2086
    struct semid_ds semid_ds;
2087
    int i, ret;
2088

    
2089
    semun.buf = &semid_ds;
2090

    
2091
    ret = semctl(semid, 0, IPC_STAT, semun);
2092
    if (ret == -1)
2093
        return get_errno(ret);
2094

    
2095
    nsems = semid_ds.sem_nsems;
2096

    
2097
    *host_array = malloc(nsems*sizeof(unsigned short));
2098
    array = lock_user(VERIFY_READ, target_addr,
2099
                      nsems*sizeof(unsigned short), 1);
2100
    if (!array)
2101
        return -TARGET_EFAULT;
2102

    
2103
    for(i=0; i<nsems; i++) {
2104
        __get_user((*host_array)[i], &array[i]);
2105
    }
2106
    unlock_user(array, target_addr, 0);
2107

    
2108
    return 0;
2109
}
2110

    
2111
static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
2112
                                               unsigned short **host_array)
2113
{
2114
    int nsems;
2115
    unsigned short *array;
2116
    union semun semun;
2117
    struct semid_ds semid_ds;
2118
    int i, ret;
2119

    
2120
    semun.buf = &semid_ds;
2121

    
2122
    ret = semctl(semid, 0, IPC_STAT, semun);
2123
    if (ret == -1)
2124
        return get_errno(ret);
2125

    
2126
    nsems = semid_ds.sem_nsems;
2127

    
2128
    array = lock_user(VERIFY_WRITE, target_addr,
2129
                      nsems*sizeof(unsigned short), 0);
2130
    if (!array)
2131
        return -TARGET_EFAULT;
2132

    
2133
    for(i=0; i<nsems; i++) {
2134
        __put_user((*host_array)[i], &array[i]);
2135
    }
2136
    free(*host_array);
2137
    unlock_user(array, target_addr, 1);
2138

    
2139
    return 0;
2140
}
2141

    
2142
static inline abi_long do_semctl(int semid, int semnum, int cmd,
2143
                                 union target_semun target_su)
2144
{
2145
    union semun arg;
2146
    struct semid_ds dsarg;
2147
    unsigned short *array;
2148
    struct seminfo seminfo;
2149
    abi_long ret = -TARGET_EINVAL;
2150
    abi_long err;
2151
    cmd &= 0xff;
2152

    
2153
    switch( cmd ) {
2154
        case GETVAL:
2155
        case SETVAL:
2156
            arg.val = tswapl(target_su.val);
2157
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2158
            target_su.val = tswapl(arg.val);
2159
            break;
2160
        case GETALL:
2161
        case SETALL:
2162
            err = target_to_host_semarray(semid, &array, target_su.array);
2163
            if (err)
2164
                return err;
2165
            arg.array = array;
2166
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2167
            err = host_to_target_semarray(semid, target_su.array, &array);
2168
            if (err)
2169
                return err;
2170
            break;
2171
        case IPC_STAT:
2172
        case IPC_SET:
2173
        case SEM_STAT:
2174
            err = target_to_host_semid_ds(&dsarg, target_su.buf);
2175
            if (err)
2176
                return err;
2177
            arg.buf = &dsarg;
2178
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2179
            err = host_to_target_semid_ds(target_su.buf, &dsarg);
2180
            if (err)
2181
                return err;
2182
            break;
2183
        case IPC_INFO:
2184
        case SEM_INFO:
2185
            arg.__buf = &seminfo;
2186
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2187
            err = host_to_target_seminfo(target_su.__buf, &seminfo);
2188
            if (err)
2189
                return err;
2190
            break;
2191
        case IPC_RMID:
2192
        case GETPID:
2193
        case GETNCNT:
2194
        case GETZCNT:
2195
            ret = get_errno(semctl(semid, semnum, cmd, NULL));
2196
            break;
2197
    }
2198

    
2199
    return ret;
2200
}
2201

    
2202
struct target_sembuf {
2203
    unsigned short sem_num;
2204
    short sem_op;
2205
    short sem_flg;
2206
};
2207

    
2208
static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
2209
                                             abi_ulong target_addr,
2210
                                             unsigned nsops)
2211
{
2212
    struct target_sembuf *target_sembuf;
2213
    int i;
2214

    
2215
    target_sembuf = lock_user(VERIFY_READ, target_addr,
2216
                              nsops*sizeof(struct target_sembuf), 1);
2217
    if (!target_sembuf)
2218
        return -TARGET_EFAULT;
2219

    
2220
    for(i=0; i<nsops; i++) {
2221
        __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
2222
        __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
2223
        __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
2224
    }
2225

    
2226
    unlock_user(target_sembuf, target_addr, 0);
2227

    
2228
    return 0;
2229
}
2230

    
2231
static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
2232
{
2233
    struct sembuf sops[nsops];
2234

    
2235
    if (target_to_host_sembuf(sops, ptr, nsops))
2236
        return -TARGET_EFAULT;
2237

    
2238
    return semop(semid, sops, nsops);
2239
}
2240

    
2241
struct target_msqid_ds
2242
{
2243
    struct target_ipc_perm msg_perm;
2244
    abi_ulong msg_stime;
2245
#if TARGET_ABI_BITS == 32
2246
    abi_ulong __unused1;
2247
#endif
2248
    abi_ulong msg_rtime;
2249
#if TARGET_ABI_BITS == 32
2250
    abi_ulong __unused2;
2251
#endif
2252
    abi_ulong msg_ctime;
2253
#if TARGET_ABI_BITS == 32
2254
    abi_ulong __unused3;
2255
#endif
2256
    abi_ulong __msg_cbytes;
2257
    abi_ulong msg_qnum;
2258
    abi_ulong msg_qbytes;
2259
    abi_ulong msg_lspid;
2260
    abi_ulong msg_lrpid;
2261
    abi_ulong __unused4;
2262
    abi_ulong __unused5;
2263
};
2264

    
2265
static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
2266
                                               abi_ulong target_addr)
2267
{
2268
    struct target_msqid_ds *target_md;
2269

    
2270
    if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
2271
        return -TARGET_EFAULT;
2272
    if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
2273
        return -TARGET_EFAULT;
2274
    host_md->msg_stime = tswapl(target_md->msg_stime);
2275
    host_md->msg_rtime = tswapl(target_md->msg_rtime);
2276
    host_md->msg_ctime = tswapl(target_md->msg_ctime);
2277
    host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
2278
    host_md->msg_qnum = tswapl(target_md->msg_qnum);
2279
    host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
2280
    host_md->msg_lspid = tswapl(target_md->msg_lspid);
2281
    host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
2282
    unlock_user_struct(target_md, target_addr, 0);
2283
    return 0;
2284
}
2285

    
2286
static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
2287
                                               struct msqid_ds *host_md)
2288
{
2289
    struct target_msqid_ds *target_md;
2290

    
2291
    if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
2292
        return -TARGET_EFAULT;
2293
    if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
2294
        return -TARGET_EFAULT;
2295
    target_md->msg_stime = tswapl(host_md->msg_stime);
2296
    target_md->msg_rtime = tswapl(host_md->msg_rtime);
2297
    target_md->msg_ctime = tswapl(host_md->msg_ctime);
2298
    target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
2299
    target_md->msg_qnum = tswapl(host_md->msg_qnum);
2300
    target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
2301
    target_md->msg_lspid = tswapl(host_md->msg_lspid);
2302
    target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
2303
    unlock_user_struct(target_md, target_addr, 1);
2304
    return 0;
2305
}
2306

    
2307
struct target_msginfo {
2308
    int msgpool;
2309
    int msgmap;
2310
    int msgmax;
2311
    int msgmnb;
2312
    int msgmni;
2313
    int msgssz;
2314
    int msgtql;
2315
    unsigned short int msgseg;
2316
};
2317

    
2318
static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
2319
                                              struct msginfo *host_msginfo)
2320
{
2321
    struct target_msginfo *target_msginfo;
2322
    if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
2323
        return -TARGET_EFAULT;
2324
    __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
2325
    __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
2326
    __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
2327
    __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
2328
    __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
2329
    __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
2330
    __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
2331
    __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
2332
    unlock_user_struct(target_msginfo, target_addr, 1);
2333
    return 0;
2334
}
2335

    
2336
static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
2337
{
2338
    struct msqid_ds dsarg;
2339
    struct msginfo msginfo;
2340
    abi_long ret = -TARGET_EINVAL;
2341

    
2342
    cmd &= 0xff;
2343

    
2344
    switch (cmd) {
2345
    case IPC_STAT:
2346
    case IPC_SET:
2347
    case MSG_STAT:
2348
        if (target_to_host_msqid_ds(&dsarg,ptr))
2349
            return -TARGET_EFAULT;
2350
        ret = get_errno(msgctl(msgid, cmd, &dsarg));
2351
        if (host_to_target_msqid_ds(ptr,&dsarg))
2352
            return -TARGET_EFAULT;
2353
        break;
2354
    case IPC_RMID:
2355
        ret = get_errno(msgctl(msgid, cmd, NULL));
2356
        break;
2357
    case IPC_INFO:
2358
    case MSG_INFO:
2359
        ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
2360
        if (host_to_target_msginfo(ptr, &msginfo))
2361
            return -TARGET_EFAULT;
2362
        break;
2363
    }
2364

    
2365
    return ret;
2366
}
2367

    
2368
struct target_msgbuf {
2369
    abi_long mtype;
2370
    char        mtext[1];
2371
};
2372

    
2373
static inline abi_long do_msgsnd(int msqid, abi_long msgp,
2374
                                 unsigned int msgsz, int msgflg)
2375
{
2376
    struct target_msgbuf *target_mb;
2377
    struct msgbuf *host_mb;
2378
    abi_long ret = 0;
2379

    
2380
    if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
2381
        return -TARGET_EFAULT;
2382
    host_mb = malloc(msgsz+sizeof(long));
2383
    host_mb->mtype = (abi_long) tswapl(target_mb->mtype);
2384
    memcpy(host_mb->mtext, target_mb->mtext, msgsz);
2385
    ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
2386
    free(host_mb);
2387
    unlock_user_struct(target_mb, msgp, 0);
2388

    
2389
    return ret;
2390
}
2391

    
2392
static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2393
                                 unsigned int msgsz, abi_long msgtyp,
2394
                                 int msgflg)
2395
{
2396
    struct target_msgbuf *target_mb;
2397
    char *target_mtext;
2398
    struct msgbuf *host_mb;
2399
    abi_long ret = 0;
2400

    
2401
    if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2402
        return -TARGET_EFAULT;
2403

    
2404
    host_mb = malloc(msgsz+sizeof(long));
2405
    ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapl(msgtyp), msgflg));
2406

    
2407
    if (ret > 0) {
2408
        abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2409
        target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2410
        if (!target_mtext) {
2411
            ret = -TARGET_EFAULT;
2412
            goto end;
2413
        }
2414
        memcpy(target_mb->mtext, host_mb->mtext, ret);
2415
        unlock_user(target_mtext, target_mtext_addr, ret);
2416
    }
2417

    
2418
    target_mb->mtype = tswapl(host_mb->mtype);
2419
    free(host_mb);
2420

    
2421
end:
2422
    if (target_mb)
2423
        unlock_user_struct(target_mb, msgp, 1);
2424
    return ret;
2425
}
2426

    
2427
#ifdef TARGET_NR_ipc
2428
/* ??? This only works with linear mappings.  */
2429
/* do_ipc() must return target values and target errnos. */
2430
static abi_long do_ipc(unsigned int call, int first,
2431
                       int second, int third,
2432
                       abi_long ptr, abi_long fifth)
2433
{
2434
    int version;
2435
    abi_long ret = 0;
2436
    struct shmid_ds shm_info;
2437
    int i;
2438

    
2439
    version = call >> 16;
2440
    call &= 0xffff;
2441

    
2442
    switch (call) {
2443
    case IPCOP_semop:
2444
        ret = do_semop(first, ptr, second);
2445
        break;
2446

    
2447
    case IPCOP_semget:
2448
        ret = get_errno(semget(first, second, third));
2449
        break;
2450

    
2451
    case IPCOP_semctl:
2452
        ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr);
2453
        break;
2454

    
2455
    case IPCOP_msgget:
2456
        ret = get_errno(msgget(first, second));
2457
        break;
2458

    
2459
    case IPCOP_msgsnd:
2460
        ret = do_msgsnd(first, ptr, second, third);
2461
        break;
2462

    
2463
    case IPCOP_msgctl:
2464
        ret = do_msgctl(first, second, ptr);
2465
        break;
2466

    
2467
    case IPCOP_msgrcv:
2468
        switch (version) {
2469
        case 0:
2470
            {
2471
                struct target_ipc_kludge {
2472
                    abi_long msgp;
2473
                    abi_long msgtyp;
2474
                } *tmp;
2475

    
2476
                if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
2477
                    ret = -TARGET_EFAULT;
2478
                    break;
2479
                }
2480

    
2481
                ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
2482

    
2483
                unlock_user_struct(tmp, ptr, 0);
2484
                break;
2485
            }
2486
        default:
2487
            ret = do_msgrcv(first, ptr, second, fifth, third);
2488
        }
2489
        break;
2490

    
2491
    case IPCOP_shmat:
2492
        {
2493
            abi_ulong raddr;
2494
            void *host_addr;
2495
            /* SHM_* flags are the same on all linux platforms */
2496
            host_addr = shmat(first, (void *)g2h(ptr), second);
2497
            if (host_addr == (void *)-1) {
2498
                ret = get_errno((long)host_addr);
2499
                break;
2500
            }
2501
            raddr = h2g((unsigned long)host_addr);
2502
            /* find out the length of the shared memory segment */
2503
            
2504
            ret = get_errno(shmctl(first, IPC_STAT, &shm_info));
2505
            if (is_error(ret)) {
2506
                /* can't get length, bail out */
2507
                shmdt(host_addr);
2508
                break;
2509
            }
2510
            page_set_flags(raddr, raddr + shm_info.shm_segsz,
2511
                           PAGE_VALID | PAGE_READ |
2512
                           ((second & SHM_RDONLY)? 0: PAGE_WRITE));
2513
            for (i = 0; i < N_SHM_REGIONS; ++i) {
2514
                if (shm_regions[i].start == 0) {
2515
                    shm_regions[i].start = raddr;
2516
                    shm_regions[i].size = shm_info.shm_segsz;
2517
                    break;
2518
                }
2519
            }
2520
            if (put_user_ual(raddr, third))
2521
                return -TARGET_EFAULT;
2522
            ret = 0;
2523
        }
2524
        break;
2525
    case IPCOP_shmdt:
2526
        for (i = 0; i < N_SHM_REGIONS; ++i) {
2527
            if (shm_regions[i].start == ptr) {
2528
                shm_regions[i].start = 0;
2529
                page_set_flags(ptr, shm_regions[i].size, 0);
2530
                break;
2531
            }
2532
        }
2533
        ret = get_errno(shmdt((void *)g2h(ptr)));
2534
        break;
2535

    
2536
    case IPCOP_shmget:
2537
        /* IPC_* flag values are the same on all linux platforms */
2538
        ret = get_errno(shmget(first, second, third));
2539
        break;
2540

    
2541
        /* IPC_* and SHM_* command values are the same on all linux platforms */
2542
    case IPCOP_shmctl:
2543
        switch(second) {
2544
        case IPC_RMID:
2545
        case SHM_LOCK:
2546
        case SHM_UNLOCK:
2547
            ret = get_errno(shmctl(first, second, NULL));
2548
            break;
2549
        default:
2550
            goto unimplemented;
2551
        }
2552
        break;
2553
    default:
2554
    unimplemented:
2555
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2556
        ret = -TARGET_ENOSYS;
2557
        break;
2558
    }
2559
    return ret;
2560
}
2561
#endif
2562

    
2563
/* kernel structure types definitions */
2564
#define IFNAMSIZ        16
2565

    
2566
#define STRUCT(name, list...) STRUCT_ ## name,
2567
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
2568
enum {
2569
#include "syscall_types.h"
2570
};
2571
#undef STRUCT
2572
#undef STRUCT_SPECIAL
2573

    
2574
#define STRUCT(name, list...) static const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };
2575
#define STRUCT_SPECIAL(name)
2576
#include "syscall_types.h"
2577
#undef STRUCT
2578
#undef STRUCT_SPECIAL
2579

    
2580
typedef struct IOCTLEntry {
2581
    unsigned int target_cmd;
2582
    unsigned int host_cmd;
2583
    const char *name;
2584
    int access;
2585
    const argtype arg_type[5];
2586
} IOCTLEntry;
2587

    
2588
#define IOC_R 0x0001
2589
#define IOC_W 0x0002
2590
#define IOC_RW (IOC_R | IOC_W)
2591

    
2592
#define MAX_STRUCT_SIZE 4096
2593

    
2594
static IOCTLEntry ioctl_entries[] = {
2595
#define IOCTL(cmd, access, types...) \
2596
    { TARGET_ ## cmd, cmd, #cmd, access, { types } },
2597
#include "ioctls.h"
2598
    { 0, 0, },
2599
};
2600

    
2601
/* ??? Implement proper locking for ioctls.  */
2602
/* do_ioctl() Must return target values and target errnos. */
2603
static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
2604
{
2605
    const IOCTLEntry *ie;
2606
    const argtype *arg_type;
2607
    abi_long ret;
2608
    uint8_t buf_temp[MAX_STRUCT_SIZE];
2609
    int target_size;
2610
    void *argptr;
2611

    
2612
    ie = ioctl_entries;
2613
    for(;;) {
2614
        if (ie->target_cmd == 0) {
2615
            gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
2616
            return -TARGET_ENOSYS;
2617
        }
2618
        if (ie->target_cmd == cmd)
2619
            break;
2620
        ie++;
2621
    }
2622
    arg_type = ie->arg_type;
2623
#if defined(DEBUG)
2624
    gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
2625
#endif
2626
    switch(arg_type[0]) {
2627
    case TYPE_NULL:
2628
        /* no argument */
2629
        ret = get_errno(ioctl(fd, ie->host_cmd));
2630
        break;
2631
    case TYPE_PTRVOID:
2632
    case TYPE_INT:
2633
        /* int argment */
2634
        ret = get_errno(ioctl(fd, ie->host_cmd, arg));
2635
        break;
2636
    case TYPE_PTR:
2637
        arg_type++;
2638
        target_size = thunk_type_size(arg_type, 0);
2639
        switch(ie->access) {
2640
        case IOC_R:
2641
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2642
            if (!is_error(ret)) {
2643
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2644
                if (!argptr)
2645
                    return -TARGET_EFAULT;
2646
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2647
                unlock_user(argptr, arg, target_size);
2648
            }
2649
            break;
2650
        case IOC_W:
2651
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2652
            if (!argptr)
2653
                return -TARGET_EFAULT;
2654
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2655
            unlock_user(argptr, arg, 0);
2656
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2657
            break;
2658
        default:
2659
        case IOC_RW:
2660
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2661
            if (!argptr)
2662
                return -TARGET_EFAULT;
2663
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2664
            unlock_user(argptr, arg, 0);
2665
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2666
            if (!is_error(ret)) {
2667
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2668
                if (!argptr)
2669
                    return -TARGET_EFAULT;
2670
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2671
                unlock_user(argptr, arg, target_size);
2672
            }
2673
            break;
2674
        }
2675
        break;
2676
    default:
2677
        gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
2678
                 (long)cmd, arg_type[0]);
2679
        ret = -TARGET_ENOSYS;
2680
        break;
2681
    }
2682
    return ret;
2683
}
2684

    
2685
static const bitmask_transtbl iflag_tbl[] = {
2686
        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
2687
        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
2688
        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
2689
        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
2690
        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
2691
        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
2692
        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
2693
        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
2694
        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
2695
        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
2696
        { TARGET_IXON, TARGET_IXON, IXON, IXON },
2697
        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
2698
        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
2699
        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
2700
        { 0, 0, 0, 0 }
2701
};
2702

    
2703
static const bitmask_transtbl oflag_tbl[] = {
2704
        { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
2705
        { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
2706
        { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
2707
        { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
2708
        { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
2709
        { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
2710
        { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
2711
        { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
2712
        { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
2713
        { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
2714
        { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
2715
        { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
2716
        { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
2717
        { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
2718
        { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
2719
        { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
2720
        { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
2721
        { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
2722
        { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
2723
        { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
2724
        { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
2725
        { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
2726
        { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
2727
        { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
2728
        { 0, 0, 0, 0 }
2729
};
2730

    
2731
static const bitmask_transtbl cflag_tbl[] = {
2732
        { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
2733
        { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
2734
        { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
2735
        { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
2736
        { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
2737
        { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
2738
        { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
2739
        { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
2740
        { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
2741
        { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
2742
        { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
2743
        { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
2744
        { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
2745
        { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
2746
        { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
2747
        { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
2748
        { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
2749
        { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
2750
        { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
2751
        { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
2752
        { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
2753
        { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
2754
        { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
2755
        { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
2756
        { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
2757
        { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
2758
        { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
2759
        { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
2760
        { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
2761
        { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
2762
        { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
2763
        { 0, 0, 0, 0 }
2764
};
2765

    
2766
static const bitmask_transtbl lflag_tbl[] = {
2767
        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
2768
        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
2769
        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
2770
        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
2771
        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
2772
        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
2773
        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
2774
        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
2775
        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
2776
        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
2777
        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
2778
        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
2779
        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
2780
        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
2781
        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
2782
        { 0, 0, 0, 0 }
2783
};
2784

    
2785
static void target_to_host_termios (void *dst, const void *src)
2786
{
2787
    struct host_termios *host = dst;
2788
    const struct target_termios *target = src;
2789

    
2790
    host->c_iflag =
2791
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
2792
    host->c_oflag =
2793
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
2794
    host->c_cflag =
2795
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
2796
    host->c_lflag =
2797
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
2798
    host->c_line = target->c_line;
2799

    
2800
    host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
2801
    host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
2802
    host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
2803
    host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
2804
    host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
2805
    host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
2806
    host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
2807
    host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
2808
    host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
2809
    host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
2810
    host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
2811
    host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
2812
    host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
2813
    host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
2814
    host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
2815
    host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
2816
    host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
2817
}
2818

    
2819
static void host_to_target_termios (void *dst, const void *src)
2820
{
2821
    struct target_termios *target = dst;
2822
    const struct host_termios *host = src;
2823

    
2824
    target->c_iflag =
2825
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
2826
    target->c_oflag =
2827
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
2828
    target->c_cflag =
2829
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
2830
    target->c_lflag =
2831
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
2832
    target->c_line = host->c_line;
2833

    
2834
    target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
2835
    target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
2836
    target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
2837
    target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
2838
    target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
2839
    target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
2840
    target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
2841
    target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
2842
    target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
2843
    target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
2844
    target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
2845
    target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
2846
    target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
2847
    target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
2848
    target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
2849
    target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
2850
    target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
2851
}
2852

    
2853
static const StructEntry struct_termios_def = {
2854
    .convert = { host_to_target_termios, target_to_host_termios },
2855
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
2856
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
2857
};
2858

    
2859
static bitmask_transtbl mmap_flags_tbl[] = {
2860
        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
2861
        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
2862
        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
2863
        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
2864
        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
2865
        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
2866
        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
2867
        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
2868
        { 0, 0, 0, 0 }
2869
};
2870

    
2871
#if defined(TARGET_I386)
2872

    
2873
/* NOTE: there is really one LDT for all the threads */
2874
static uint8_t *ldt_table;
2875

    
2876
static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
2877
{
2878
    int size;
2879
    void *p;
2880

    
2881
    if (!ldt_table)
2882
        return 0;
2883
    size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
2884
    if (size > bytecount)
2885
        size = bytecount;
2886
    p = lock_user(VERIFY_WRITE, ptr, size, 0);
2887
    if (!p)
2888
        return -TARGET_EFAULT;
2889
    /* ??? Should this by byteswapped?  */
2890
    memcpy(p, ldt_table, size);
2891
    unlock_user(p, ptr, size);
2892
    return size;
2893
}
2894

    
2895
/* XXX: add locking support */
2896
static abi_long write_ldt(CPUX86State *env,
2897
                          abi_ulong ptr, unsigned long bytecount, int oldmode)
2898
{
2899
    struct target_modify_ldt_ldt_s ldt_info;
2900
    struct target_modify_ldt_ldt_s *target_ldt_info;
2901
    int seg_32bit, contents, read_exec_only, limit_in_pages;
2902
    int seg_not_present, useable, lm;
2903
    uint32_t *lp, entry_1, entry_2;
2904

    
2905
    if (bytecount != sizeof(ldt_info))
2906
        return -TARGET_EINVAL;
2907
    if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
2908
        return -TARGET_EFAULT;
2909
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2910
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2911
    ldt_info.limit = tswap32(target_ldt_info->limit);
2912
    ldt_info.flags = tswap32(target_ldt_info->flags);
2913
    unlock_user_struct(target_ldt_info, ptr, 0);
2914

    
2915
    if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
2916
        return -TARGET_EINVAL;
2917
    seg_32bit = ldt_info.flags & 1;
2918
    contents = (ldt_info.flags >> 1) & 3;
2919
    read_exec_only = (ldt_info.flags >> 3) & 1;
2920
    limit_in_pages = (ldt_info.flags >> 4) & 1;
2921
    seg_not_present = (ldt_info.flags >> 5) & 1;
2922
    useable = (ldt_info.flags >> 6) & 1;
2923
#ifdef TARGET_ABI32
2924
    lm = 0;
2925
#else
2926
    lm = (ldt_info.flags >> 7) & 1;
2927
#endif
2928
    if (contents == 3) {
2929
        if (oldmode)
2930
            return -TARGET_EINVAL;
2931
        if (seg_not_present == 0)
2932
            return -TARGET_EINVAL;
2933
    }
2934
    /* allocate the LDT */
2935
    if (!ldt_table) {
2936
        env->ldt.base = target_mmap(0,
2937
                                    TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
2938
                                    PROT_READ|PROT_WRITE,
2939
                                    MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
2940
        if (env->ldt.base == -1)
2941
            return -TARGET_ENOMEM;
2942
        memset(g2h(env->ldt.base), 0,
2943
               TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
2944
        env->ldt.limit = 0xffff;
2945
        ldt_table = g2h(env->ldt.base);
2946
    }
2947

    
2948
    /* NOTE: same code as Linux kernel */
2949
    /* Allow LDTs to be cleared by the user. */
2950
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2951
        if (oldmode ||
2952
            (contents == 0                &&
2953
             read_exec_only == 1        &&
2954
             seg_32bit == 0                &&
2955
             limit_in_pages == 0        &&
2956
             seg_not_present == 1        &&
2957
             useable == 0 )) {
2958
            entry_1 = 0;
2959
            entry_2 = 0;
2960
            goto install;
2961
        }
2962
    }
2963

    
2964
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2965
        (ldt_info.limit & 0x0ffff);
2966
    entry_2 = (ldt_info.base_addr & 0xff000000) |
2967
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2968
        (ldt_info.limit & 0xf0000) |
2969
        ((read_exec_only ^ 1) << 9) |
2970
        (contents << 10) |
2971
        ((seg_not_present ^ 1) << 15) |
2972
        (seg_32bit << 22) |
2973
        (limit_in_pages << 23) |
2974
        (lm << 21) |
2975
        0x7000;
2976
    if (!oldmode)
2977
        entry_2 |= (useable << 20);
2978

    
2979
    /* Install the new entry ...  */
2980
install:
2981
    lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
2982
    lp[0] = tswap32(entry_1);
2983
    lp[1] = tswap32(entry_2);
2984
    return 0;
2985
}
2986

    
2987
/* specific and weird i386 syscalls */
2988
static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
2989
                              unsigned long bytecount)
2990
{
2991
    abi_long ret;
2992

    
2993
    switch (func) {
2994
    case 0:
2995
        ret = read_ldt(ptr, bytecount);
2996
        break;
2997
    case 1:
2998
        ret = write_ldt(env, ptr, bytecount, 1);
2999
        break;
3000
    case 0x11:
3001
        ret = write_ldt(env, ptr, bytecount, 0);
3002
        break;
3003
    default:
3004
        ret = -TARGET_ENOSYS;
3005
        break;
3006
    }
3007
    return ret;
3008
}
3009

    
3010
#if defined(TARGET_I386) && defined(TARGET_ABI32)
3011
static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
3012
{
3013
    uint64_t *gdt_table = g2h(env->gdt.base);
3014
    struct target_modify_ldt_ldt_s ldt_info;
3015
    struct target_modify_ldt_ldt_s *target_ldt_info;
3016
    int seg_32bit, contents, read_exec_only, limit_in_pages;
3017
    int seg_not_present, useable, lm;
3018
    uint32_t *lp, entry_1, entry_2;
3019
    int i;
3020

    
3021
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3022
    if (!target_ldt_info)
3023
        return -TARGET_EFAULT;
3024
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3025
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
3026
    ldt_info.limit = tswap32(target_ldt_info->limit);
3027
    ldt_info.flags = tswap32(target_ldt_info->flags);
3028
    if (ldt_info.entry_number == -1) {
3029
        for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
3030
            if (gdt_table[i] == 0) {
3031
                ldt_info.entry_number = i;
3032
                target_ldt_info->entry_number = tswap32(i);
3033
                break;
3034
            }
3035
        }
3036
    }
3037
    unlock_user_struct(target_ldt_info, ptr, 1);
3038

    
3039
    if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || 
3040
        ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
3041
           return -TARGET_EINVAL;
3042
    seg_32bit = ldt_info.flags & 1;
3043
    contents = (ldt_info.flags >> 1) & 3;
3044
    read_exec_only = (ldt_info.flags >> 3) & 1;
3045
    limit_in_pages = (ldt_info.flags >> 4) & 1;
3046
    seg_not_present = (ldt_info.flags >> 5) & 1;
3047
    useable = (ldt_info.flags >> 6) & 1;
3048
#ifdef TARGET_ABI32
3049
    lm = 0;
3050
#else
3051
    lm = (ldt_info.flags >> 7) & 1;
3052
#endif
3053

    
3054
    if (contents == 3) {
3055
        if (seg_not_present == 0)
3056
            return -TARGET_EINVAL;
3057
    }
3058

    
3059
    /* NOTE: same code as Linux kernel */
3060
    /* Allow LDTs to be cleared by the user. */
3061
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3062
        if ((contents == 0             &&
3063
             read_exec_only == 1       &&
3064
             seg_32bit == 0            &&
3065
             limit_in_pages == 0       &&
3066
             seg_not_present == 1      &&
3067
             useable == 0 )) {
3068
            entry_1 = 0;
3069
            entry_2 = 0;
3070
            goto install;
3071
        }
3072
    }
3073

    
3074
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
3075
        (ldt_info.limit & 0x0ffff);
3076
    entry_2 = (ldt_info.base_addr & 0xff000000) |
3077
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3078
        (ldt_info.limit & 0xf0000) |
3079
        ((read_exec_only ^ 1) << 9) |
3080
        (contents << 10) |
3081
        ((seg_not_present ^ 1) << 15) |
3082
        (seg_32bit << 22) |
3083
        (limit_in_pages << 23) |
3084
        (useable << 20) |
3085
        (lm << 21) |
3086
        0x7000;
3087

    
3088
    /* Install the new entry ...  */
3089
install:
3090
    lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
3091
    lp[0] = tswap32(entry_1);
3092
    lp[1] = tswap32(entry_2);
3093
    return 0;
3094
}
3095

    
3096
static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
3097
{
3098
    struct target_modify_ldt_ldt_s *target_ldt_info;
3099
    uint64_t *gdt_table = g2h(env->gdt.base);
3100
    uint32_t base_addr, limit, flags;
3101
    int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
3102
    int seg_not_present, useable, lm;
3103
    uint32_t *lp, entry_1, entry_2;
3104

    
3105
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3106
    if (!target_ldt_info)
3107
        return -TARGET_EFAULT;
3108
    idx = tswap32(target_ldt_info->entry_number);
3109
    if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
3110
        idx > TARGET_GDT_ENTRY_TLS_MAX) {
3111
        unlock_user_struct(target_ldt_info, ptr, 1);
3112
        return -TARGET_EINVAL;
3113
    }
3114
    lp = (uint32_t *)(gdt_table + idx);
3115
    entry_1 = tswap32(lp[0]);
3116
    entry_2 = tswap32(lp[1]);
3117
    
3118
    read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
3119
    contents = (entry_2 >> 10) & 3;
3120
    seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
3121
    seg_32bit = (entry_2 >> 22) & 1;
3122
    limit_in_pages = (entry_2 >> 23) & 1;
3123
    useable = (entry_2 >> 20) & 1;
3124
#ifdef TARGET_ABI32
3125
    lm = 0;
3126
#else
3127
    lm = (entry_2 >> 21) & 1;
3128
#endif
3129
    flags = (seg_32bit << 0) | (contents << 1) |
3130
        (read_exec_only << 3) | (limit_in_pages << 4) |
3131
        (seg_not_present << 5) | (useable << 6) | (lm << 7);
3132
    limit = (entry_1 & 0xffff) | (entry_2  & 0xf0000);
3133
    base_addr = (entry_1 >> 16) | 
3134
        (entry_2 & 0xff000000) | 
3135
        ((entry_2 & 0xff) << 16);
3136
    target_ldt_info->base_addr = tswapl(base_addr);
3137
    target_ldt_info->limit = tswap32(limit);
3138
    target_ldt_info->flags = tswap32(flags);
3139
    unlock_user_struct(target_ldt_info, ptr, 1);
3140
    return 0;
3141
}
3142
#endif /* TARGET_I386 && TARGET_ABI32 */
3143

    
3144
#ifndef TARGET_ABI32
3145
static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
3146
{
3147
    abi_long ret;
3148
    abi_ulong val;
3149
    int idx;
3150
    
3151
    switch(code) {
3152
    case TARGET_ARCH_SET_GS:
3153
    case TARGET_ARCH_SET_FS:
3154
        if (code == TARGET_ARCH_SET_GS)
3155
            idx = R_GS;
3156
        else
3157
            idx = R_FS;
3158
        cpu_x86_load_seg(env, idx, 0);
3159
        env->segs[idx].base = addr;
3160
        break;
3161
    case TARGET_ARCH_GET_GS:
3162
    case TARGET_ARCH_GET_FS:
3163
        if (code == TARGET_ARCH_GET_GS)
3164
            idx = R_GS;
3165
        else
3166
            idx = R_FS;
3167
        val = env->segs[idx].base;
3168
        if (put_user(val, addr, abi_ulong))
3169
            return -TARGET_EFAULT;
3170
        break;
3171
    default:
3172
        ret = -TARGET_EINVAL;
3173
        break;
3174
    }
3175
    return 0;
3176
}
3177
#endif
3178

    
3179
#endif /* defined(TARGET_I386) */
3180

    
3181
#if defined(USE_NPTL)
3182

    
3183
#define NEW_STACK_SIZE PTHREAD_STACK_MIN
3184

    
3185
static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
3186
typedef struct {
3187
    CPUState *env;
3188
    pthread_mutex_t mutex;
3189
    pthread_cond_t cond;
3190
    pthread_t thread;
3191
    uint32_t tid;
3192
    abi_ulong child_tidptr;
3193
    abi_ulong parent_tidptr;
3194
    sigset_t sigmask;
3195
} new_thread_info;
3196

    
3197
static void *clone_func(void *arg)
3198
{
3199
    new_thread_info *info = arg;
3200
    CPUState *env;
3201

    
3202
    env = info->env;
3203
    thread_env = env;
3204
    info->tid = gettid();
3205
    if (info->child_tidptr)
3206
        put_user_u32(info->tid, info->child_tidptr);
3207
    if (info->parent_tidptr)
3208
        put_user_u32(info->tid, info->parent_tidptr);
3209
    /* Enable signals.  */
3210
    sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
3211
    /* Signal to the parent that we're ready.  */
3212
    pthread_mutex_lock(&info->mutex);
3213
    pthread_cond_broadcast(&info->cond);
3214
    pthread_mutex_unlock(&info->mutex);
3215
    /* Wait until the parent has finshed initializing the tls state.  */
3216
    pthread_mutex_lock(&clone_lock);
3217
    pthread_mutex_unlock(&clone_lock);
3218
    cpu_loop(env);
3219
    /* never exits */
3220
    return NULL;
3221
}
3222
#else
3223
/* this stack is the equivalent of the kernel stack associated with a
3224
   thread/process */
3225
#define NEW_STACK_SIZE 8192
3226

    
3227
static int clone_func(void *arg)
3228
{
3229
    CPUState *env = arg;
3230
    cpu_loop(env);
3231
    /* never exits */
3232
    return 0;
3233
}
3234
#endif
3235

    
3236
/* do_fork() Must return host values and target errnos (unlike most
3237
   do_*() functions). */
3238
static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
3239
                   abi_ulong parent_tidptr, target_ulong newtls,
3240
                   abi_ulong child_tidptr)
3241
{
3242
    int ret;
3243
    TaskState *ts;
3244
    uint8_t *new_stack;
3245
    CPUState *new_env;
3246
#if defined(USE_NPTL)
3247
    unsigned int nptl_flags;
3248
    sigset_t sigmask;
3249
#endif
3250

    
3251
    /* Emulate vfork() with fork() */
3252
    if (flags & CLONE_VFORK)
3253
        flags &= ~(CLONE_VFORK | CLONE_VM);
3254

    
3255
    if (flags & CLONE_VM) {
3256
#if defined(USE_NPTL)
3257
        new_thread_info info;
3258
        pthread_attr_t attr;
3259
#endif
3260
        ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
3261
        init_task_state(ts);
3262
        new_stack = ts->stack;
3263
        /* we create a new CPU instance. */
3264
        new_env = cpu_copy(env);
3265
        /* Init regs that differ from the parent.  */
3266
        cpu_clone_regs(new_env, newsp);
3267
        new_env->opaque = ts;
3268
#if defined(USE_NPTL)
3269
        nptl_flags = flags;
3270
        flags &= ~CLONE_NPTL_FLAGS2;
3271

    
3272
        if (nptl_flags & CLONE_CHILD_CLEARTID) {
3273
            ts->child_tidptr = child_tidptr;
3274
        }
3275

    
3276
        if (nptl_flags & CLONE_SETTLS)
3277
            cpu_set_tls (new_env, newtls);
3278

    
3279
        /* Grab a mutex so that thread setup appears atomic.  */
3280
        pthread_mutex_lock(&clone_lock);
3281

    
3282
        memset(&info, 0, sizeof(info));
3283
        pthread_mutex_init(&info.mutex, NULL);
3284
        pthread_mutex_lock(&info.mutex);
3285
        pthread_cond_init(&info.cond, NULL);
3286
        info.env = new_env;
3287
        if (nptl_flags & CLONE_CHILD_SETTID)
3288
            info.child_tidptr = child_tidptr;
3289
        if (nptl_flags & CLONE_PARENT_SETTID)
3290
            info.parent_tidptr = parent_tidptr;
3291

    
3292
        ret = pthread_attr_init(&attr);
3293
        ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE);
3294
        /* It is not safe to deliver signals until the child has finished
3295
           initializing, so temporarily block all signals.  */
3296
        sigfillset(&sigmask);
3297
        sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
3298

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

    
3302
        sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
3303
        pthread_attr_destroy(&attr);
3304
        if (ret == 0) {
3305
            /* Wait for the child to initialize.  */
3306
            pthread_cond_wait(&info.cond, &info.mutex);
3307
            ret = info.tid;
3308
            if (flags & CLONE_PARENT_SETTID)
3309
                put_user_u32(ret, parent_tidptr);
3310
        } else {
3311
            ret = -1;
3312
        }
3313
        pthread_mutex_unlock(&info.mutex);
3314
        pthread_cond_destroy(&info.cond);
3315
        pthread_mutex_destroy(&info.mutex);
3316
        pthread_mutex_unlock(&clone_lock);
3317
#else
3318
        if (flags & CLONE_NPTL_FLAGS2)
3319
            return -EINVAL;
3320
        /* This is probably going to die very quickly, but do it anyway.  */
3321
#ifdef __ia64__
3322
        ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
3323
#else
3324
        ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
3325
#endif
3326
#endif
3327
    } else {
3328
        /* if no CLONE_VM, we consider it is a fork */
3329
        if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
3330
            return -EINVAL;
3331
        fork_start();
3332
        ret = fork();
3333
        if (ret == 0) {
3334
            /* Child Process.  */
3335
            cpu_clone_regs(env, newsp);
3336
            fork_end(1);
3337
#if defined(USE_NPTL)
3338
            /* There is a race condition here.  The parent process could
3339
               theoretically read the TID in the child process before the child
3340
               tid is set.  This would require using either ptrace
3341
               (not implemented) or having *_tidptr to point at a shared memory
3342
               mapping.  We can't repeat the spinlock hack used above because
3343
               the child process gets its own copy of the lock.  */
3344
            if (flags & CLONE_CHILD_SETTID)
3345
                put_user_u32(gettid(), child_tidptr);
3346
            if (flags & CLONE_PARENT_SETTID)
3347
                put_user_u32(gettid(), parent_tidptr);
3348
            ts = (TaskState *)env->opaque;
3349
            if (flags & CLONE_SETTLS)
3350
                cpu_set_tls (env, newtls);
3351
            if (flags & CLONE_CHILD_CLEARTID)
3352
                ts->child_tidptr = child_tidptr;
3353
#endif
3354
        } else {
3355
            fork_end(0);
3356
        }
3357
    }
3358
    return ret;
3359
}
3360

    
3361
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
3362
{
3363
    struct flock fl;
3364
    struct target_flock *target_fl;
3365
    struct flock64 fl64;
3366
    struct target_flock64 *target_fl64;
3367
    abi_long ret;
3368

    
3369
    switch(cmd) {
3370
    case TARGET_F_GETLK:
3371
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3372
            return -TARGET_EFAULT;
3373
        fl.l_type = tswap16(target_fl->l_type);
3374
        fl.l_whence = tswap16(target_fl->l_whence);
3375
        fl.l_start = tswapl(target_fl->l_start);
3376
        fl.l_len = tswapl(target_fl->l_len);
3377
        fl.l_pid = tswapl(target_fl->l_pid);
3378
        unlock_user_struct(target_fl, arg, 0);
3379
        ret = get_errno(fcntl(fd, cmd, &fl));
3380
        if (ret == 0) {
3381
            if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
3382
                return -TARGET_EFAULT;
3383
            target_fl->l_type = tswap16(fl.l_type);
3384
            target_fl->l_whence = tswap16(fl.l_whence);
3385
            target_fl->l_start = tswapl(fl.l_start);
3386
            target_fl->l_len = tswapl(fl.l_len);
3387
            target_fl->l_pid = tswapl(fl.l_pid);
3388
            unlock_user_struct(target_fl, arg, 1);
3389
        }
3390
        break;
3391

    
3392
    case TARGET_F_SETLK:
3393
    case TARGET_F_SETLKW:
3394
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3395
            return -TARGET_EFAULT;
3396
        fl.l_type = tswap16(target_fl->l_type);
3397
        fl.l_whence = tswap16(target_fl->l_whence);
3398
        fl.l_start = tswapl(target_fl->l_start);
3399
        fl.l_len = tswapl(target_fl->l_len);
3400
        fl.l_pid = tswapl(target_fl->l_pid);
3401
        unlock_user_struct(target_fl, arg, 0);
3402
        ret = get_errno(fcntl(fd, cmd, &fl));
3403
        break;
3404

    
3405
    case TARGET_F_GETLK64:
3406
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3407
            return -TARGET_EFAULT;
3408
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3409
        fl64.l_whence = tswap16(target_fl64->l_whence);
3410
        fl64.l_start = tswapl(target_fl64->l_start);
3411
        fl64.l_len = tswapl(target_fl64->l_len);
3412
        fl64.l_pid = tswap16(target_fl64->l_pid);
3413
        unlock_user_struct(target_fl64, arg, 0);
3414
        ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
3415
        if (ret == 0) {
3416
            if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
3417
                return -TARGET_EFAULT;
3418
            target_fl64->l_type = tswap16(fl64.l_type) >> 1;
3419
            target_fl64->l_whence = tswap16(fl64.l_whence);
3420
            target_fl64->l_start = tswapl(fl64.l_start);
3421
            target_fl64->l_len = tswapl(fl64.l_len);
3422
            target_fl64->l_pid = tswapl(fl64.l_pid);
3423
            unlock_user_struct(target_fl64, arg, 1);
3424
        }
3425
        break;
3426
    case TARGET_F_SETLK64:
3427
    case TARGET_F_SETLKW64:
3428
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3429
            return -TARGET_EFAULT;
3430
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3431
        fl64.l_whence = tswap16(target_fl64->l_whence);
3432
        fl64.l_start = tswapl(target_fl64->l_start);
3433
        fl64.l_len = tswapl(target_fl64->l_len);
3434
        fl64.l_pid = tswap16(target_fl64->l_pid);
3435
        unlock_user_struct(target_fl64, arg, 0);
3436
        ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
3437
        break;
3438

    
3439
    case F_GETFL:
3440
        ret = get_errno(fcntl(fd, cmd, arg));
3441
        if (ret >= 0) {
3442
            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
3443
        }
3444
        break;
3445

    
3446
    case F_SETFL:
3447
        ret = get_errno(fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
3448
        break;
3449

    
3450
    default:
3451
        ret = get_errno(fcntl(fd, cmd, arg));
3452
        break;
3453
    }
3454
    return ret;
3455
}
3456

    
3457
#ifdef USE_UID16
3458

    
3459
static inline int high2lowuid(int uid)
3460
{
3461
    if (uid > 65535)
3462
        return 65534;
3463
    else
3464
        return uid;
3465
}
3466

    
3467
static inline int high2lowgid(int gid)
3468
{
3469
    if (gid > 65535)
3470
        return 65534;
3471
    else
3472
        return gid;
3473
}
3474

    
3475
static inline int low2highuid(int uid)
3476
{
3477
    if ((int16_t)uid == -1)
3478
        return -1;
3479
    else
3480
        return uid;
3481
}
3482

    
3483
static inline int low2highgid(int gid)
3484
{
3485
    if ((int16_t)gid == -1)
3486
        return -1;
3487
    else
3488
        return gid;
3489
}
3490

    
3491
#endif /* USE_UID16 */
3492

    
3493
void syscall_init(void)
3494
{
3495
    IOCTLEntry *ie;
3496
    const argtype *arg_type;
3497
    int size;
3498
    int i;
3499

    
3500
#define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3501
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3502
#include "syscall_types.h"
3503
#undef STRUCT
3504
#undef STRUCT_SPECIAL
3505

    
3506
    /* we patch the ioctl size if necessary. We rely on the fact that
3507
       no ioctl has all the bits at '1' in the size field */
3508
    ie = ioctl_entries;
3509
    while (ie->target_cmd != 0) {
3510
        if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
3511
            TARGET_IOC_SIZEMASK) {
3512
            arg_type = ie->arg_type;
3513
            if (arg_type[0] != TYPE_PTR) {
3514
                fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
3515
                        ie->target_cmd);
3516
                exit(1);
3517
            }
3518
            arg_type++;
3519
            size = thunk_type_size(arg_type, 0);
3520
            ie->target_cmd = (ie->target_cmd &
3521
                              ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
3522
                (size << TARGET_IOC_SIZESHIFT);
3523
        }
3524

    
3525
        /* Build target_to_host_errno_table[] table from
3526
         * host_to_target_errno_table[]. */
3527
        for (i=0; i < ERRNO_TABLE_SIZE; i++)
3528
                target_to_host_errno_table[host_to_target_errno_table[i]] = i;
3529

    
3530
        /* automatic consistency check if same arch */
3531
#if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
3532
    (defined(__x86_64__) && defined(TARGET_X86_64))
3533
        if (unlikely(ie->target_cmd != ie->host_cmd)) {
3534
            fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
3535
                    ie->name, ie->target_cmd, ie->host_cmd);
3536
        }
3537
#endif
3538
        ie++;
3539
    }
3540
}
3541

    
3542
#if TARGET_ABI_BITS == 32
3543
static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
3544
{
3545
#ifdef TARGET_WORDS_BIGENDIAN
3546
    return ((uint64_t)word0 << 32) | word1;
3547
#else
3548
    return ((uint64_t)word1 << 32) | word0;
3549
#endif
3550
}
3551
#else /* TARGET_ABI_BITS == 32 */
3552
static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
3553
{
3554
    return word0;
3555
}
3556
#endif /* TARGET_ABI_BITS != 32 */
3557

    
3558
#ifdef TARGET_NR_truncate64
3559
static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
3560
                                         abi_long arg2,
3561
                                         abi_long arg3,
3562
                                         abi_long arg4)
3563
{
3564
#ifdef TARGET_ARM
3565
    if (((CPUARMState *)cpu_env)->eabi)
3566
      {
3567
        arg2 = arg3;
3568
        arg3 = arg4;
3569
      }
3570
#endif
3571
    return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
3572
}
3573
#endif
3574

    
3575
#ifdef TARGET_NR_ftruncate64
3576
static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
3577
                                          abi_long arg2,
3578
                                          abi_long arg3,
3579
                                          abi_long arg4)
3580
{
3581
#ifdef TARGET_ARM
3582
    if (((CPUARMState *)cpu_env)->eabi)
3583
      {
3584
        arg2 = arg3;
3585
        arg3 = arg4;
3586
      }
3587
#endif
3588
    return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
3589
}
3590
#endif
3591

    
3592
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
3593
                                               abi_ulong target_addr)
3594
{
3595
    struct target_timespec *target_ts;
3596

    
3597
    if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
3598
        return -TARGET_EFAULT;
3599
    host_ts->tv_sec = tswapl(target_ts->tv_sec);
3600
    host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
3601
    unlock_user_struct(target_ts, target_addr, 0);
3602
    return 0;
3603
}
3604

    
3605
static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3606
                                               struct timespec *host_ts)
3607
{
3608
    struct target_timespec *target_ts;
3609

    
3610
    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
3611
        return -TARGET_EFAULT;
3612
    target_ts->tv_sec = tswapl(host_ts->tv_sec);
3613
    target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
3614
    unlock_user_struct(target_ts, target_addr, 1);
3615
    return 0;
3616
}
3617

    
3618
#if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
3619
static inline abi_long host_to_target_stat64(void *cpu_env,
3620
                                             abi_ulong target_addr,
3621
                                             struct stat *host_st)
3622
{
3623
#ifdef TARGET_ARM
3624
    if (((CPUARMState *)cpu_env)->eabi) {
3625
        struct target_eabi_stat64 *target_st;
3626

    
3627
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3628
            return -TARGET_EFAULT;
3629
        memset(target_st, 0, sizeof(struct target_eabi_stat64));
3630
        __put_user(host_st->st_dev, &target_st->st_dev);
3631
        __put_user(host_st->st_ino, &target_st->st_ino);
3632
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3633
        __put_user(host_st->st_ino, &target_st->__st_ino);
3634
#endif
3635
        __put_user(host_st->st_mode, &target_st->st_mode);
3636
        __put_user(host_st->st_nlink, &target_st->st_nlink);
3637
        __put_user(host_st->st_uid, &target_st->st_uid);
3638
        __put_user(host_st->st_gid, &target_st->st_gid);
3639
        __put_user(host_st->st_rdev, &target_st->st_rdev);
3640
        __put_user(host_st->st_size, &target_st->st_size);
3641
        __put_user(host_st->st_blksize, &target_st->st_blksize);
3642
        __put_user(host_st->st_blocks, &target_st->st_blocks);
3643
        __put_user(host_st->st_atime, &target_st->target_st_atime);
3644
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3645
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3646
        unlock_user_struct(target_st, target_addr, 1);
3647
    } else
3648
#endif
3649
    {
3650
#if TARGET_LONG_BITS == 64
3651
        struct target_stat *target_st;
3652
#else
3653
        struct target_stat64 *target_st;
3654
#endif
3655

    
3656
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3657
            return -TARGET_EFAULT;
3658
        memset(target_st, 0, sizeof(*target_st));
3659
        __put_user(host_st->st_dev, &target_st->st_dev);
3660
        __put_user(host_st->st_ino, &target_st->st_ino);
3661
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3662
        __put_user(host_st->st_ino, &target_st->__st_ino);
3663
#endif
3664
        __put_user(host_st->st_mode, &target_st->st_mode);
3665
        __put_user(host_st->st_nlink, &target_st->st_nlink);
3666
        __put_user(host_st->st_uid, &target_st->st_uid);
3667
        __put_user(host_st->st_gid, &target_st->st_gid);
3668
        __put_user(host_st->st_rdev, &target_st->st_rdev);
3669
        /* XXX: better use of kernel struct */
3670
        __put_user(host_st->st_size, &target_st->st_size);
3671
        __put_user(host_st->st_blksize, &target_st->st_blksize);
3672
        __put_user(host_st->st_blocks, &target_st->st_blocks);
3673
        __put_user(host_st->st_atime, &target_st->target_st_atime);
3674
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3675
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3676
        unlock_user_struct(target_st, target_addr, 1);
3677
    }
3678

    
3679
    return 0;
3680
}
3681
#endif
3682

    
3683
#if defined(USE_NPTL)
3684
/* ??? Using host futex calls even when target atomic operations
3685
   are not really atomic probably breaks things.  However implementing
3686
   futexes locally would make futexes shared between multiple processes
3687
   tricky.  However they're probably useless because guest atomic
3688
   operations won't work either.  */
3689
static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
3690
                    target_ulong uaddr2, int val3)
3691
{
3692
    struct timespec ts, *pts;
3693

    
3694
    /* ??? We assume FUTEX_* constants are the same on both host
3695
       and target.  */
3696
    switch (op) {
3697
    case FUTEX_WAIT:
3698
        if (timeout) {
3699
            pts = &ts;
3700
            target_to_host_timespec(pts, timeout);
3701
        } else {
3702
            pts = NULL;
3703
        }
3704
        return get_errno(sys_futex(g2h(uaddr), FUTEX_WAIT, tswap32(val),
3705
                         pts, NULL, 0));
3706
    case FUTEX_WAKE:
3707
        return get_errno(sys_futex(g2h(uaddr), FUTEX_WAKE, val, NULL, NULL, 0));
3708
    case FUTEX_FD:
3709
        return get_errno(sys_futex(g2h(uaddr), FUTEX_FD, val, NULL, NULL, 0));
3710
    case FUTEX_REQUEUE:
3711
        return get_errno(sys_futex(g2h(uaddr), FUTEX_REQUEUE, val,
3712
                         NULL, g2h(uaddr2), 0));
3713
    case FUTEX_CMP_REQUEUE:
3714
        return get_errno(sys_futex(g2h(uaddr), FUTEX_CMP_REQUEUE, val,
3715
                         NULL, g2h(uaddr2), tswap32(val3)));
3716
    default:
3717
        return -TARGET_ENOSYS;
3718
    }
3719
}
3720
#endif
3721

    
3722
/* Map host to target signal numbers for the wait family of syscalls.
3723
   Assume all other status bits are the same.  */
3724
static int host_to_target_waitstatus(int status)
3725
{
3726
    if (WIFSIGNALED(status)) {
3727
        return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f);
3728
    }
3729
    if (WIFSTOPPED(status)) {
3730
        return (host_to_target_signal(WSTOPSIG(status)) << 8)
3731
               | (status & 0xff);
3732
    }
3733
    return status;
3734
}
3735

    
3736
int get_osversion(void)
3737
{
3738
    static int osversion;
3739
    struct new_utsname buf;
3740
    const char *s;
3741
    int i, n, tmp;
3742
    if (osversion)
3743
        return osversion;
3744
    if (qemu_uname_release && *qemu_uname_release) {
3745
        s = qemu_uname_release;
3746
    } else {
3747
        if (sys_uname(&buf))
3748
            return 0;
3749
        s = buf.release;
3750
    }
3751
    tmp = 0;
3752
    for (i = 0; i < 3; i++) {
3753
        n = 0;
3754
        while (*s >= '0' && *s <= '9') {
3755
            n *= 10;
3756
            n += *s - '0';
3757
            s++;
3758
        }
3759
        tmp = (tmp << 8) + n;
3760
        if (*s == '.')
3761
            s++;
3762
    }
3763
    osversion = tmp;
3764
    return osversion;
3765
}
3766

    
3767
/* do_syscall() should always have a single exit point at the end so
3768
   that actions, such as logging of syscall results, can be performed.
3769
   All errnos that do_syscall() returns must be -TARGET_<errcode>. */
3770
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3771
                    abi_long arg2, abi_long arg3, abi_long arg4,
3772
                    abi_long arg5, abi_long arg6)
3773
{
3774
    abi_long ret;
3775
    struct stat st;
3776
    struct statfs stfs;
3777
    void *p;
3778

    
3779
#ifdef DEBUG
3780
    gemu_log("syscall %d", num);
3781
#endif
3782
    if(do_strace)
3783
        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
3784

    
3785
    switch(num) {
3786
    case TARGET_NR_exit:
3787
#ifdef USE_NPTL
3788
      /* In old applications this may be used to implement _exit(2).
3789
         However in threaded applictions it is used for thread termination,
3790
         and _exit_group is used for application termination.
3791
         Do thread termination if we have more then one thread.  */
3792
      /* FIXME: This probably breaks if a signal arrives.  We should probably
3793
         be disabling signals.  */
3794
      if (first_cpu->next_cpu) {
3795
          CPUState **lastp;
3796
          CPUState *p;
3797

    
3798
          cpu_list_lock();
3799
          lastp = &first_cpu;
3800
          p = first_cpu;
3801
          while (p && p != (CPUState *)cpu_env) {
3802
              lastp = &p->next_cpu;
3803
              p = p->next_cpu;
3804
          }
3805
          /* If we didn't find the CPU for this thread then something is
3806
             horribly wrong.  */
3807
          if (!p)
3808
              abort();
3809
          /* Remove the CPU from the list.  */
3810
          *lastp = p->next_cpu;
3811
          cpu_list_unlock();
3812
          TaskState *ts = ((CPUState *)cpu_env)->opaque;
3813
          if (ts->child_tidptr) {
3814
              put_user_u32(0, ts->child_tidptr);
3815
              sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
3816
                        NULL, NULL, 0);
3817
          }
3818
          /* TODO: Free CPU state.  */
3819
          pthread_exit(NULL);
3820
      }
3821
#endif
3822
#ifdef HAVE_GPROF
3823
        _mcleanup();
3824
#endif
3825
        gdb_exit(cpu_env, arg1);
3826
        _exit(arg1);
3827
        ret = 0; /* avoid warning */
3828
        break;
3829
    case TARGET_NR_read:
3830
        if (arg3 == 0)
3831
            ret = 0;
3832
        else {
3833
            if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
3834
                goto efault;
3835
            ret = get_errno(read(arg1, p, arg3));
3836
            unlock_user(p, arg2, ret);
3837
        }
3838
        break;
3839
    case TARGET_NR_write:
3840
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
3841
            goto efault;
3842
        ret = get_errno(write(arg1, p, arg3));
3843
        unlock_user(p, arg2, 0);
3844
        break;
3845
    case TARGET_NR_open:
3846
        if (!(p = lock_user_string(arg1)))
3847
            goto efault;
3848
        ret = get_errno(open(path(p),
3849
                             target_to_host_bitmask(arg2, fcntl_flags_tbl),
3850
                             arg3));
3851
        unlock_user(p, arg1, 0);
3852
        break;
3853
#if defined(TARGET_NR_openat) && defined(__NR_openat)
3854
    case TARGET_NR_openat:
3855
        if (!(p = lock_user_string(arg2)))
3856
            goto efault;
3857
        ret = get_errno(sys_openat(arg1,
3858
                                   path(p),
3859
                                   target_to_host_bitmask(arg3, fcntl_flags_tbl),
3860
                                   arg4));
3861
        unlock_user(p, arg2, 0);
3862
        break;
3863
#endif
3864
    case TARGET_NR_close:
3865
        ret = get_errno(close(arg1));
3866
        break;
3867
    case TARGET_NR_brk:
3868
        ret = do_brk(arg1);
3869
        break;
3870
    case TARGET_NR_fork:
3871
        ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
3872
        break;
3873
#ifdef TARGET_NR_waitpid
3874
    case TARGET_NR_waitpid:
3875
        {
3876
            int status;
3877
            ret = get_errno(waitpid(arg1, &status, arg3));
3878
            if (!is_error(ret) && arg2
3879
                && put_user_s32(host_to_target_waitstatus(status), arg2))
3880
                goto efault;
3881
        }
3882
        break;
3883
#endif
3884
#ifdef TARGET_NR_waitid
3885
    case TARGET_NR_waitid:
3886
        {
3887
            siginfo_t info;
3888
            info.si_pid = 0;
3889
            ret = get_errno(waitid(arg1, arg2, &info, arg4));
3890
            if (!is_error(ret) && arg3 && info.si_pid != 0) {
3891
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
3892
                    goto efault;
3893
                host_to_target_siginfo(p, &info);
3894
                unlock_user(p, arg3, sizeof(target_siginfo_t));
3895
            }
3896
        }
3897
        break;
3898
#endif
3899
#ifdef TARGET_NR_creat /* not on alpha */
3900
    case TARGET_NR_creat:
3901
        if (!(p = lock_user_string(arg1)))
3902
            goto efault;
3903
        ret = get_errno(creat(p, arg2));
3904
        unlock_user(p, arg1, 0);
3905
        break;
3906
#endif
3907
    case TARGET_NR_link:
3908
        {
3909
            void * p2;
3910
            p = lock_user_string(arg1);
3911
            p2 = lock_user_string(arg2);
3912
            if (!p || !p2)
3913
                ret = -TARGET_EFAULT;
3914
            else
3915
                ret = get_errno(link(p, p2));
3916
            unlock_user(p2, arg2, 0);
3917
            unlock_user(p, arg1, 0);
3918
        }
3919
        break;
3920
#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
3921
    case TARGET_NR_linkat:
3922
        {
3923
            void * p2 = NULL;
3924
            if (!arg2 || !arg4)
3925
                goto efault;
3926
            p  = lock_user_string(arg2);
3927
            p2 = lock_user_string(arg4);
3928
            if (!p || !p2)
3929
                ret = -TARGET_EFAULT;
3930
            else
3931
                ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
3932
            unlock_user(p, arg2, 0);
3933
            unlock_user(p2, arg4, 0);
3934
        }
3935
        break;
3936
#endif
3937
    case TARGET_NR_unlink:
3938
        if (!(p = lock_user_string(arg1)))
3939
            goto efault;
3940
        ret = get_errno(unlink(p));
3941
        unlock_user(p, arg1, 0);
3942
        break;
3943
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
3944
    case TARGET_NR_unlinkat:
3945
        if (!(p = lock_user_string(arg2)))
3946
            goto efault;
3947
        ret = get_errno(sys_unlinkat(arg1, p, arg3));
3948
        unlock_user(p, arg2, 0);
3949
        break;
3950
#endif
3951
    case TARGET_NR_execve:
3952
        {
3953
            char **argp, **envp;
3954
            int argc, envc;
3955
            abi_ulong gp;
3956
            abi_ulong guest_argp;
3957
            abi_ulong guest_envp;
3958
            abi_ulong addr;
3959
            char **q;
3960

    
3961
            argc = 0;
3962
            guest_argp = arg2;
3963
            for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
3964
                if (get_user_ual(addr, gp))
3965
                    goto efault;
3966
                if (!addr)
3967
                    break;
3968
                argc++;
3969
            }
3970
            envc = 0;
3971
            guest_envp = arg3;
3972
            for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
3973
                if (get_user_ual(addr, gp))
3974
                    goto efault;
3975
                if (!addr)
3976
                    break;
3977
                envc++;
3978
            }
3979

    
3980
            argp = alloca((argc + 1) * sizeof(void *));
3981
            envp = alloca((envc + 1) * sizeof(void *));
3982

    
3983
            for (gp = guest_argp, q = argp; gp;
3984
                  gp += sizeof(abi_ulong), q++) {
3985
                if (get_user_ual(addr, gp))
3986
                    goto execve_efault;
3987
                if (!addr)
3988
                    break;
3989
                if (!(*q = lock_user_string(addr)))
3990
                    goto execve_efault;
3991
            }
3992
            *q = NULL;
3993

    
3994
            for (gp = guest_envp, q = envp; gp;
3995
                  gp += sizeof(abi_ulong), q++) {
3996
                if (get_user_ual(addr, gp))
3997
                    goto execve_efault;
3998
                if (!addr)
3999
                    break;
4000
                if (!(*q = lock_user_string(addr)))
4001
                    goto execve_efault;
4002
            }
4003
            *q = NULL;
4004

    
4005
            if (!(p = lock_user_string(arg1)))
4006
                goto execve_efault;
4007
            ret = get_errno(execve(p, argp, envp));
4008
            unlock_user(p, arg1, 0);
4009

    
4010
            goto execve_end;
4011

    
4012
        execve_efault:
4013
            ret = -TARGET_EFAULT;
4014

    
4015
        execve_end:
4016
            for (gp = guest_argp, q = argp; *q;
4017
                  gp += sizeof(abi_ulong), q++) {
4018
                if (get_user_ual(addr, gp)
4019
                    || !addr)
4020
                    break;
4021
                unlock_user(*q, addr, 0);
4022
            }
4023
            for (gp = guest_envp, q = envp; *q;
4024
                  gp += sizeof(abi_ulong), q++) {
4025
                if (get_user_ual(addr, gp)
4026
                    || !addr)
4027
                    break;
4028
                unlock_user(*q, addr, 0);
4029
            }
4030
        }
4031
        break;
4032
    case TARGET_NR_chdir:
4033
        if (!(p = lock_user_string(arg1)))
4034
            goto efault;
4035
        ret = get_errno(chdir(p));
4036
        unlock_user(p, arg1, 0);
4037
        break;
4038
#ifdef TARGET_NR_time
4039
    case TARGET_NR_time:
4040
        {
4041
            time_t host_time;
4042
            ret = get_errno(time(&host_time));
4043
            if (!is_error(ret)
4044
                && arg1
4045
                && put_user_sal(host_time, arg1))
4046
                goto efault;
4047
        }
4048
        break;
4049
#endif
4050
    case TARGET_NR_mknod:
4051
        if (!(p = lock_user_string(arg1)))
4052
            goto efault;
4053
        ret = get_errno(mknod(p, arg2, arg3));
4054
        unlock_user(p, arg1, 0);
4055
        break;
4056
#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
4057
    case TARGET_NR_mknodat:
4058
        if (!(p = lock_user_string(arg2)))
4059
            goto efault;
4060
        ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
4061
        unlock_user(p, arg2, 0);
4062
        break;
4063
#endif
4064
    case TARGET_NR_chmod:
4065
        if (!(p = lock_user_string(arg1)))
4066
            goto efault;
4067
        ret = get_errno(chmod(p, arg2));
4068
        unlock_user(p, arg1, 0);
4069
        break;
4070
#ifdef TARGET_NR_break
4071
    case TARGET_NR_break:
4072
        goto unimplemented;
4073
#endif
4074
#ifdef TARGET_NR_oldstat
4075
    case TARGET_NR_oldstat:
4076
        goto unimplemented;
4077
#endif
4078
    case TARGET_NR_lseek:
4079
        ret = get_errno(lseek(arg1, arg2, arg3));
4080
        break;
4081
#ifdef TARGET_NR_getxpid
4082
    case TARGET_NR_getxpid:
4083
#else
4084
    case TARGET_NR_getpid:
4085
#endif
4086
        ret = get_errno(getpid());
4087
        break;
4088
    case TARGET_NR_mount:
4089
                {
4090
                        /* need to look at the data field */
4091
                        void *p2, *p3;
4092
                        p = lock_user_string(arg1);
4093
                        p2 = lock_user_string(arg2);
4094
                        p3 = lock_user_string(arg3);
4095
                        if (!p || !p2 || !p3)
4096
                            ret = -TARGET_EFAULT;
4097
                        else
4098
                            /* FIXME - arg5 should be locked, but it isn't clear how to
4099
                             * do that since it's not guaranteed to be a NULL-terminated
4100
                             * string.
4101
                             */
4102
                            ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
4103
                        unlock_user(p, arg1, 0);
4104
                        unlock_user(p2, arg2, 0);
4105
                        unlock_user(p3, arg3, 0);
4106
                        break;
4107
                }
4108
#ifdef TARGET_NR_umount
4109
    case TARGET_NR_umount:
4110
        if (!(p = lock_user_string(arg1)))
4111
            goto efault;
4112
        ret = get_errno(umount(p));
4113
        unlock_user(p, arg1, 0);
4114
        break;
4115
#endif
4116
#ifdef TARGET_NR_stime /* not on alpha */
4117
    case TARGET_NR_stime:
4118
        {
4119
            time_t host_time;
4120
            if (get_user_sal(host_time, arg1))
4121
                goto efault;
4122
            ret = get_errno(stime(&host_time));
4123
        }
4124
        break;
4125
#endif
4126
    case TARGET_NR_ptrace:
4127
        goto unimplemented;
4128
#ifdef TARGET_NR_alarm /* not on alpha */
4129
    case TARGET_NR_alarm:
4130
        ret = alarm(arg1);
4131
        break;
4132
#endif
4133
#ifdef TARGET_NR_oldfstat
4134
    case TARGET_NR_oldfstat:
4135
        goto unimplemented;
4136
#endif
4137
#ifdef TARGET_NR_pause /* not on alpha */
4138
    case TARGET_NR_pause:
4139
        ret = get_errno(pause());
4140
        break;
4141
#endif
4142
#ifdef TARGET_NR_utime
4143
    case TARGET_NR_utime:
4144
        {
4145
            struct utimbuf tbuf, *host_tbuf;
4146
            struct target_utimbuf *target_tbuf;
4147
            if (arg2) {
4148
                if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
4149
                    goto efault;
4150
                tbuf.actime = tswapl(target_tbuf->actime);
4151
                tbuf.modtime = tswapl(target_tbuf->modtime);
4152
                unlock_user_struct(target_tbuf, arg2, 0);
4153
                host_tbuf = &tbuf;
4154
            } else {
4155
                host_tbuf = NULL;
4156
            }
4157
            if (!(p = lock_user_string(arg1)))
4158
                goto efault;
4159
            ret = get_errno(utime(p, host_tbuf));
4160
            unlock_user(p, arg1, 0);
4161
        }
4162
        break;
4163
#endif
4164
    case TARGET_NR_utimes:
4165
        {
4166
            struct timeval *tvp, tv[2];
4167
            if (arg2) {
4168
                if (copy_from_user_timeval(&tv[0], arg2)
4169
                    || copy_from_user_timeval(&tv[1],
4170
                                              arg2 + sizeof(struct target_timeval)))
4171
                    goto efault;
4172
                tvp = tv;
4173
            } else {
4174
                tvp = NULL;
4175
            }
4176
            if (!(p = lock_user_string(arg1)))
4177
                goto efault;
4178
            ret = get_errno(utimes(p, tvp));
4179
            unlock_user(p, arg1, 0);
4180
        }
4181
        break;
4182
#if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
4183
    case TARGET_NR_futimesat:
4184
        {
4185
            struct timeval *tvp, tv[2];
4186
            if (arg3) {
4187
                if (copy_from_user_timeval(&tv[0], arg3)
4188
                    || copy_from_user_timeval(&tv[1],
4189
                                              arg3 + sizeof(struct target_timeval)))
4190
                    goto efault;
4191
                tvp = tv;
4192
            } else {
4193
                tvp = NULL;
4194
            }
4195
            if (!(p = lock_user_string(arg2)))
4196
                goto efault;
4197
            ret = get_errno(sys_futimesat(arg1, path(p), tvp));
4198
            unlock_user(p, arg2, 0);
4199
        }
4200
        break;
4201
#endif
4202
#ifdef TARGET_NR_stty
4203
    case TARGET_NR_stty:
4204
        goto unimplemented;
4205
#endif
4206
#ifdef TARGET_NR_gtty
4207
    case TARGET_NR_gtty:
4208
        goto unimplemented;
4209
#endif
4210
    case TARGET_NR_access:
4211
        if (!(p = lock_user_string(arg1)))
4212
            goto efault;
4213
        ret = get_errno(access(p, arg2));
4214
        unlock_user(p, arg1, 0);
4215
        break;
4216
#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
4217
    case TARGET_NR_faccessat:
4218
        if (!(p = lock_user_string(arg2)))
4219
            goto efault;
4220
        ret = get_errno(sys_faccessat(arg1, p, arg3));
4221
        unlock_user(p, arg2, 0);
4222
        break;
4223
#endif
4224
#ifdef TARGET_NR_nice /* not on alpha */
4225
    case TARGET_NR_nice:
4226
        ret = get_errno(nice(arg1));
4227
        break;
4228
#endif
4229
#ifdef TARGET_NR_ftime
4230
    case TARGET_NR_ftime:
4231
        goto unimplemented;
4232
#endif
4233
    case TARGET_NR_sync:
4234
        sync();
4235
        ret = 0;
4236
        break;
4237
    case TARGET_NR_kill:
4238
        ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
4239
        break;
4240
    case TARGET_NR_rename:
4241
        {
4242
            void *p2;
4243
            p = lock_user_string(arg1);
4244
            p2 = lock_user_string(arg2);
4245
            if (!p || !p2)
4246
                ret = -TARGET_EFAULT;
4247
            else
4248
                ret = get_errno(rename(p, p2));
4249
            unlock_user(p2, arg2, 0);
4250
            unlock_user(p, arg1, 0);
4251
        }
4252
        break;
4253
#if defined(TARGET_NR_renameat) && defined(__NR_renameat)
4254
    case TARGET_NR_renameat:
4255
        {
4256
            void *p2;
4257
            p  = lock_user_string(arg2);
4258
            p2 = lock_user_string(arg4);
4259
            if (!p || !p2)
4260
                ret = -TARGET_EFAULT;
4261
            else
4262
                ret = get_errno(sys_renameat(arg1, p, arg3, p2));
4263
            unlock_user(p2, arg4, 0);
4264
            unlock_user(p, arg2, 0);
4265
        }
4266
        break;
4267
#endif
4268
    case TARGET_NR_mkdir:
4269
        if (!(p = lock_user_string(arg1)))
4270
            goto efault;
4271
        ret = get_errno(mkdir(p, arg2));
4272
        unlock_user(p, arg1, 0);
4273
        break;
4274
#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
4275
    case TARGET_NR_mkdirat:
4276
        if (!(p = lock_user_string(arg2)))
4277
            goto efault;
4278
        ret = get_errno(sys_mkdirat(arg1, p, arg3));
4279
        unlock_user(p, arg2, 0);
4280
        break;
4281
#endif
4282
    case TARGET_NR_rmdir:
4283
        if (!(p = lock_user_string(arg1)))
4284
            goto efault;
4285
        ret = get_errno(rmdir(p));
4286
        unlock_user(p, arg1, 0);
4287
        break;
4288
    case TARGET_NR_dup:
4289
        ret = get_errno(dup(arg1));
4290
        break;
4291
    case TARGET_NR_pipe:
4292
        {
4293
            int host_pipe[2];
4294
            ret = get_errno(pipe(host_pipe));
4295
            if (!is_error(ret)) {
4296
#if defined(TARGET_MIPS)
4297
                CPUMIPSState *env = (CPUMIPSState*)cpu_env;
4298
                env->active_tc.gpr[3] = host_pipe[1];
4299
                ret = host_pipe[0];
4300
#elif defined(TARGET_SH4)
4301
                ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
4302
                ret = host_pipe[0];
4303
#else
4304
                if (put_user_s32(host_pipe[0], arg1)
4305
                    || put_user_s32(host_pipe[1], arg1 + sizeof(host_pipe[0])))
4306
                    goto efault;
4307
#endif
4308
            }
4309
        }
4310
        break;
4311
    case TARGET_NR_times:
4312
        {
4313
            struct target_tms *tmsp;
4314
            struct tms tms;
4315
            ret = get_errno(times(&tms));
4316
            if (arg1) {
4317
                tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
4318
                if (!tmsp)
4319
                    goto efault;
4320
                tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
4321
                tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
4322
                tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
4323
                tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime));
4324
            }
4325
            if (!is_error(ret))
4326
                ret = host_to_target_clock_t(ret);
4327
        }
4328
        break;
4329
#ifdef TARGET_NR_prof
4330
    case TARGET_NR_prof:
4331
        goto unimplemented;
4332
#endif
4333
#ifdef TARGET_NR_signal
4334
    case TARGET_NR_signal:
4335
        goto unimplemented;
4336
#endif
4337
    case TARGET_NR_acct:
4338
        if (arg1 == 0) {
4339
            ret = get_errno(acct(NULL));
4340
        } else {
4341
            if (!(p = lock_user_string(arg1)))
4342
                goto efault;
4343
            ret = get_errno(acct(path(p)));
4344
            unlock_user(p, arg1, 0);
4345
        }
4346
        break;
4347
#ifdef TARGET_NR_umount2 /* not on alpha */
4348
    case TARGET_NR_umount2:
4349
        if (!(p = lock_user_string(arg1)))
4350
            goto efault;
4351
        ret = get_errno(umount2(p, arg2));
4352
        unlock_user(p, arg1, 0);
4353
        break;
4354
#endif
4355
#ifdef TARGET_NR_lock
4356
    case TARGET_NR_lock:
4357
        goto unimplemented;
4358
#endif
4359
    case TARGET_NR_ioctl:
4360
        ret = do_ioctl(arg1, arg2, arg3);
4361
        break;
4362
    case TARGET_NR_fcntl:
4363
        ret = do_fcntl(arg1, arg2, arg3);
4364
        break;
4365
#ifdef TARGET_NR_mpx
4366
    case TARGET_NR_mpx:
4367
        goto unimplemented;
4368
#endif
4369
    case TARGET_NR_setpgid:
4370
        ret = get_errno(setpgid(arg1, arg2));
4371
        break;
4372
#ifdef TARGET_NR_ulimit
4373
    case TARGET_NR_ulimit:
4374
        goto unimplemented;
4375
#endif
4376
#ifdef TARGET_NR_oldolduname
4377
    case TARGET_NR_oldolduname:
4378
        goto unimplemented;
4379
#endif
4380
    case TARGET_NR_umask:
4381
        ret = get_errno(umask(arg1));
4382
        break;
4383
    case TARGET_NR_chroot:
4384
        if (!(p = lock_user_string(arg1)))
4385
            goto efault;
4386
        ret = get_errno(chroot(p));
4387
        unlock_user(p, arg1, 0);
4388
        break;
4389
    case TARGET_NR_ustat:
4390
        goto unimplemented;
4391
    case TARGET_NR_dup2:
4392
        ret = get_errno(dup2(arg1, arg2));
4393
        break;
4394
#ifdef TARGET_NR_getppid /* not on alpha */
4395
    case TARGET_NR_getppid:
4396
        ret = get_errno(getppid());
4397
        break;
4398
#endif
4399
    case TARGET_NR_getpgrp:
4400
        ret = get_errno(getpgrp());
4401
        break;
4402
    case TARGET_NR_setsid:
4403
        ret = get_errno(setsid());
4404
        break;
4405
#ifdef TARGET_NR_sigaction
4406
    case TARGET_NR_sigaction:
4407
        {
4408
#if !defined(TARGET_MIPS)
4409
            struct target_old_sigaction *old_act;
4410
            struct target_sigaction act, oact, *pact;
4411
            if (arg2) {
4412
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4413
                    goto efault;
4414
                act._sa_handler = old_act->_sa_handler;
4415
                target_siginitset(&act.sa_mask, old_act->sa_mask);
4416
                act.sa_flags = old_act->sa_flags;
4417
                act.sa_restorer = old_act->sa_restorer;
4418
                unlock_user_struct(old_act, arg2, 0);
4419
                pact = &act;
4420
            } else {
4421
                pact = NULL;
4422
            }
4423
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4424
            if (!is_error(ret) && arg3) {
4425
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4426
                    goto efault;
4427
                old_act->_sa_handler = oact._sa_handler;
4428
                old_act->sa_mask = oact.sa_mask.sig[0];
4429
                old_act->sa_flags = oact.sa_flags;
4430
                old_act->sa_restorer = oact.sa_restorer;
4431
                unlock_user_struct(old_act, arg3, 1);
4432
            }
4433
#else
4434
            struct target_sigaction act, oact, *pact, *old_act;
4435

    
4436
            if (arg2) {
4437
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4438
                    goto efault;
4439
                act._sa_handler = old_act->_sa_handler;
4440
                target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
4441
                act.sa_flags = old_act->sa_flags;
4442
                unlock_user_struct(old_act, arg2, 0);
4443
                pact = &act;
4444
            } else {
4445
                pact = NULL;
4446
            }
4447

    
4448
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4449

    
4450
            if (!is_error(ret) && arg3) {
4451
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4452
                    goto efault;
4453
                old_act->_sa_handler = oact._sa_handler;
4454
                old_act->sa_flags = oact.sa_flags;
4455
                old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
4456
                old_act->sa_mask.sig[1] = 0;
4457
                old_act->sa_mask.sig[2] = 0;
4458
                old_act->sa_mask.sig[3] = 0;
4459
                unlock_user_struct(old_act, arg3, 1);
4460
            }
4461
#endif
4462
        }
4463
        break;
4464
#endif
4465
    case TARGET_NR_rt_sigaction:
4466
        {
4467
            struct target_sigaction *act;
4468
            struct target_sigaction *oact;
4469

    
4470
            if (arg2) {
4471
                if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
4472
                    goto efault;
4473
            } else
4474
                act = NULL;
4475
            if (arg3) {
4476
                if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
4477
                    ret = -TARGET_EFAULT;
4478
                    goto rt_sigaction_fail;
4479
                }
4480
            } else
4481
                oact = NULL;
4482
            ret = get_errno(do_sigaction(arg1, act, oact));
4483
        rt_sigaction_fail:
4484
            if (act)
4485
                unlock_user_struct(act, arg2, 0);
4486
            if (oact)
4487
                unlock_user_struct(oact, arg3, 1);
4488
        }
4489
        break;
4490
#ifdef TARGET_NR_sgetmask /* not on alpha */
4491
    case TARGET_NR_sgetmask:
4492
        {
4493
            sigset_t cur_set;
4494
            abi_ulong target_set;
4495
            sigprocmask(0, NULL, &cur_set);
4496
            host_to_target_old_sigset(&target_set, &cur_set);
4497
            ret = target_set;
4498
        }
4499
        break;
4500
#endif
4501
#ifdef TARGET_NR_ssetmask /* not on alpha */
4502
    case TARGET_NR_ssetmask:
4503
        {
4504
            sigset_t set, oset, cur_set;
4505
            abi_ulong target_set = arg1;
4506
            sigprocmask(0, NULL, &cur_set);
4507
            target_to_host_old_sigset(&set, &target_set);
4508
            sigorset(&set, &set, &cur_set);
4509
            sigprocmask(SIG_SETMASK, &set, &oset);
4510
            host_to_target_old_sigset(&target_set, &oset);
4511
            ret = target_set;
4512
        }
4513
        break;
4514
#endif
4515
#ifdef TARGET_NR_sigprocmask
4516
    case TARGET_NR_sigprocmask:
4517
        {
4518
            int how = arg1;
4519
            sigset_t set, oldset, *set_ptr;
4520

    
4521
            if (arg2) {
4522
                switch(how) {
4523
                case TARGET_SIG_BLOCK:
4524
                    how = SIG_BLOCK;
4525
                    break;
4526
                case TARGET_SIG_UNBLOCK:
4527
                    how = SIG_UNBLOCK;
4528
                    break;
4529
                case TARGET_SIG_SETMASK:
4530
                    how = SIG_SETMASK;
4531
                    break;
4532
                default:
4533
                    ret = -TARGET_EINVAL;
4534
                    goto fail;
4535
                }
4536
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4537
                    goto efault;
4538
                target_to_host_old_sigset(&set, p);
4539
                unlock_user(p, arg2, 0);
4540
                set_ptr = &set;
4541
            } else {
4542
                how = 0;
4543
                set_ptr = NULL;
4544
            }
4545
            ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
4546
            if (!is_error(ret) && arg3) {
4547
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4548
                    goto efault;
4549
                host_to_target_old_sigset(p, &oldset);
4550
                unlock_user(p, arg3, sizeof(target_sigset_t));
4551
            }
4552
        }
4553
        break;
4554
#endif
4555
    case TARGET_NR_rt_sigprocmask:
4556
        {
4557
            int how = arg1;
4558
            sigset_t set, oldset, *set_ptr;
4559

    
4560
            if (arg2) {
4561
                switch(how) {
4562
                case TARGET_SIG_BLOCK:
4563
                    how = SIG_BLOCK;
4564
                    break;
4565
                case TARGET_SIG_UNBLOCK:
4566
                    how = SIG_UNBLOCK;
4567
                    break;
4568
                case TARGET_SIG_SETMASK:
4569
                    how = SIG_SETMASK;
4570
                    break;
4571
                default:
4572
                    ret = -TARGET_EINVAL;
4573
                    goto fail;
4574
                }
4575
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4576
                    goto efault;
4577
                target_to_host_sigset(&set, p);
4578
                unlock_user(p, arg2, 0);
4579
                set_ptr = &set;
4580
            } else {
4581
                how = 0;
4582
                set_ptr = NULL;
4583
            }
4584
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
4585
            if (!is_error(ret) && arg3) {
4586
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4587
                    goto efault;
4588
                host_to_target_sigset(p, &oldset);
4589
                unlock_user(p, arg3, sizeof(target_sigset_t));
4590
            }
4591
        }
4592
        break;
4593
#ifdef TARGET_NR_sigpending
4594
    case TARGET_NR_sigpending:
4595
        {
4596
            sigset_t set;
4597
            ret = get_errno(sigpending(&set));
4598
            if (!is_error(ret)) {
4599
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4600
                    goto efault;
4601
                host_to_target_old_sigset(p, &set);
4602
                unlock_user(p, arg1, sizeof(target_sigset_t));
4603
            }
4604
        }
4605
        break;
4606
#endif
4607
    case TARGET_NR_rt_sigpending:
4608
        {
4609
            sigset_t set;
4610
            ret = get_errno(sigpending(&set));
4611
            if (!is_error(ret)) {
4612
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4613
                    goto efault;
4614
                host_to_target_sigset(p, &set);
4615
                unlock_user(p, arg1, sizeof(target_sigset_t));
4616
            }
4617
        }
4618
        break;
4619
#ifdef TARGET_NR_sigsuspend
4620
    case TARGET_NR_sigsuspend:
4621
        {
4622
            sigset_t set;
4623
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4624
                goto efault;
4625
            target_to_host_old_sigset(&set, p);
4626
            unlock_user(p, arg1, 0);
4627
            ret = get_errno(sigsuspend(&set));
4628
        }
4629
        break;
4630
#endif
4631
    case TARGET_NR_rt_sigsuspend:
4632
        {
4633
            sigset_t set;
4634
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4635
                goto efault;
4636
            target_to_host_sigset(&set, p);
4637
            unlock_user(p, arg1, 0);
4638
            ret = get_errno(sigsuspend(&set));
4639
        }
4640
        break;
4641
    case TARGET_NR_rt_sigtimedwait:
4642
        {
4643
            sigset_t set;
4644
            struct timespec uts, *puts;
4645
            siginfo_t uinfo;
4646

    
4647
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4648
                goto efault;
4649
            target_to_host_sigset(&set, p);
4650
            unlock_user(p, arg1, 0);
4651
            if (arg3) {
4652
                puts = &uts;
4653
                target_to_host_timespec(puts, arg3);
4654
            } else {
4655
                puts = NULL;
4656
            }
4657
            ret = get_errno(sigtimedwait(&set, &uinfo, puts));
4658
            if (!is_error(ret) && arg2) {
4659
                if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
4660
                    goto efault;
4661
                host_to_target_siginfo(p, &uinfo);
4662
                unlock_user(p, arg2, sizeof(target_siginfo_t));
4663
            }
4664
        }
4665
        break;
4666
    case TARGET_NR_rt_sigqueueinfo:
4667
        {
4668
            siginfo_t uinfo;
4669
            if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
4670
                goto efault;
4671
            target_to_host_siginfo(&uinfo, p);
4672
            unlock_user(p, arg1, 0);
4673
            ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
4674
        }
4675
        break;
4676
#ifdef TARGET_NR_sigreturn
4677
    case TARGET_NR_sigreturn:
4678
        /* NOTE: ret is eax, so not transcoding must be done */
4679
        ret = do_sigreturn(cpu_env);
4680
        break;
4681
#endif
4682
    case TARGET_NR_rt_sigreturn:
4683
        /* NOTE: ret is eax, so not transcoding must be done */
4684
        ret = do_rt_sigreturn(cpu_env);
4685
        break;
4686
    case TARGET_NR_sethostname:
4687
        if (!(p = lock_user_string(arg1)))
4688
            goto efault;
4689
        ret = get_errno(sethostname(p, arg2));
4690
        unlock_user(p, arg1, 0);
4691
        break;
4692
    case TARGET_NR_setrlimit:
4693
        {
4694
            /* XXX: convert resource ? */
4695
            int resource = arg1;
4696
            struct target_rlimit *target_rlim;
4697
            struct rlimit rlim;
4698
            if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
4699
                goto efault;
4700
            rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4701
            rlim.rlim_max = tswapl(target_rlim->rlim_max);
4702
            unlock_user_struct(target_rlim, arg2, 0);
4703
            ret = get_errno(setrlimit(resource, &rlim));
4704
        }
4705
        break;
4706
    case TARGET_NR_getrlimit:
4707
        {
4708
            /* XXX: convert resource ? */
4709
            int resource = arg1;
4710
            struct target_rlimit *target_rlim;
4711
            struct rlimit rlim;
4712

    
4713
            ret = get_errno(getrlimit(resource, &rlim));
4714
            if (!is_error(ret)) {
4715
                if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
4716
                    goto efault;
4717
                rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4718
                rlim.rlim_max = tswapl(target_rlim->rlim_max);
4719
                unlock_user_struct(target_rlim, arg2, 1);
4720
            }
4721
        }
4722
        break;
4723
    case TARGET_NR_getrusage:
4724
        {
4725
            struct rusage rusage;
4726
            ret = get_errno(getrusage(arg1, &rusage));
4727
            if (!is_error(ret)) {
4728
                host_to_target_rusage(arg2, &rusage);
4729
            }
4730
        }
4731
        break;
4732
    case TARGET_NR_gettimeofday:
4733
        {
4734
            struct timeval tv;
4735
            ret = get_errno(gettimeofday(&tv, NULL));
4736
            if (!is_error(ret)) {
4737
                if (copy_to_user_timeval(arg1, &tv))
4738
                    goto efault;
4739
            }
4740
        }
4741
        break;
4742
    case TARGET_NR_settimeofday:
4743
        {
4744
            struct timeval tv;
4745
            if (copy_from_user_timeval(&tv, arg1))
4746
                goto efault;
4747
            ret = get_errno(settimeofday(&tv, NULL));
4748
        }
4749
        break;
4750
#ifdef TARGET_NR_select
4751
    case TARGET_NR_select:
4752
        {
4753
            struct target_sel_arg_struct *sel;
4754
            abi_ulong inp, outp, exp, tvp;
4755
            long nsel;
4756

    
4757
            if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
4758
                goto efault;
4759
            nsel = tswapl(sel->n);
4760
            inp = tswapl(sel->inp);
4761
            outp = tswapl(sel->outp);
4762
            exp = tswapl(sel->exp);
4763
            tvp = tswapl(sel->tvp);
4764
            unlock_user_struct(sel, arg1, 0);
4765
            ret = do_select(nsel, inp, outp, exp, tvp);
4766
        }
4767
        break;
4768
#endif
4769
    case TARGET_NR_symlink:
4770
        {
4771
            void *p2;
4772
            p = lock_user_string(arg1);
4773
            p2 = lock_user_string(arg2);
4774
            if (!p || !p2)
4775
                ret = -TARGET_EFAULT;
4776
            else
4777
                ret = get_errno(symlink(p, p2));
4778
            unlock_user(p2, arg2, 0);
4779
            unlock_user(p, arg1, 0);
4780
        }
4781
        break;
4782
#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
4783
    case TARGET_NR_symlinkat:
4784
        {
4785
            void *p2;
4786
            p  = lock_user_string(arg1);
4787
            p2 = lock_user_string(arg3);
4788
            if (!p || !p2)
4789
                ret = -TARGET_EFAULT;
4790
            else
4791
                ret = get_errno(sys_symlinkat(p, arg2, p2));
4792
            unlock_user(p2, arg3, 0);
4793
            unlock_user(p, arg1, 0);
4794
        }
4795
        break;
4796
#endif
4797
#ifdef TARGET_NR_oldlstat
4798
    case TARGET_NR_oldlstat:
4799
        goto unimplemented;
4800
#endif
4801
    case TARGET_NR_readlink:
4802
        {
4803
            void *p2, *temp;
4804
            p = lock_user_string(arg1);
4805
            p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
4806
            if (!p || !p2)
4807
                ret = -TARGET_EFAULT;
4808
            else {
4809
                if (strncmp((const char *)p, "/proc/self/exe", 14) == 0) {
4810
                    char real[PATH_MAX];
4811
                    temp = realpath(exec_path,real);
4812
                    ret = (temp==NULL) ? get_errno(-1) : strlen(real) ;
4813
                    snprintf((char *)p2, arg3, "%s", real);
4814
                    }
4815
                else
4816
                    ret = get_errno(readlink(path(p), p2, arg3));
4817
            }
4818
            unlock_user(p2, arg2, ret);
4819
            unlock_user(p, arg1, 0);
4820
        }
4821
        break;
4822
#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
4823
    case TARGET_NR_readlinkat:
4824
        {
4825
            void *p2;
4826
            p  = lock_user_string(arg2);
4827
            p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
4828
            if (!p || !p2)
4829
                ret = -TARGET_EFAULT;
4830
            else
4831
                ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
4832
            unlock_user(p2, arg3, ret);
4833
            unlock_user(p, arg2, 0);
4834
        }
4835
        break;
4836
#endif
4837
#ifdef TARGET_NR_uselib
4838
    case TARGET_NR_uselib:
4839
        goto unimplemented;
4840
#endif
4841
#ifdef TARGET_NR_swapon
4842
    case TARGET_NR_swapon:
4843
        if (!(p = lock_user_string(arg1)))
4844
            goto efault;
4845
        ret = get_errno(swapon(p, arg2));
4846
        unlock_user(p, arg1, 0);
4847
        break;
4848
#endif
4849
    case TARGET_NR_reboot:
4850
        goto unimplemented;
4851
#ifdef TARGET_NR_readdir
4852
    case TARGET_NR_readdir:
4853
        goto unimplemented;
4854
#endif
4855
#ifdef TARGET_NR_mmap
4856
    case TARGET_NR_mmap:
4857
#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS)
4858
        {
4859
            abi_ulong *v;
4860
            abi_ulong v1, v2, v3, v4, v5, v6;
4861
            if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
4862
                goto efault;
4863
            v1 = tswapl(v[0]);
4864
            v2 = tswapl(v[1]);
4865
            v3 = tswapl(v[2]);
4866
            v4 = tswapl(v[3]);
4867
            v5 = tswapl(v[4]);
4868
            v6 = tswapl(v[5]);
4869
            unlock_user(v, arg1, 0);
4870
            ret = get_errno(target_mmap(v1, v2, v3,
4871
                                        target_to_host_bitmask(v4, mmap_flags_tbl),
4872
                                        v5, v6));
4873
        }
4874
#else
4875
        ret = get_errno(target_mmap(arg1, arg2, arg3,
4876
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
4877
                                    arg5,
4878
                                    arg6));
4879
#endif
4880
        break;
4881
#endif
4882
#ifdef TARGET_NR_mmap2
4883
    case TARGET_NR_mmap2:
4884
#ifndef MMAP_SHIFT
4885
#define MMAP_SHIFT 12
4886
#endif
4887
        ret = get_errno(target_mmap(arg1, arg2, arg3,
4888
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
4889
                                    arg5,
4890
                                    arg6 << MMAP_SHIFT));
4891
        break;
4892
#endif
4893
    case TARGET_NR_munmap:
4894
        ret = get_errno(target_munmap(arg1, arg2));
4895
        break;
4896
    case TARGET_NR_mprotect:
4897
        ret = get_errno(target_mprotect(arg1, arg2, arg3));
4898
        break;
4899
#ifdef TARGET_NR_mremap
4900
    case TARGET_NR_mremap:
4901
        ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
4902
        break;
4903
#endif
4904
        /* ??? msync/mlock/munlock are broken for softmmu.  */
4905
#ifdef TARGET_NR_msync
4906
    case TARGET_NR_msync:
4907
        ret = get_errno(msync(g2h(arg1), arg2, arg3));
4908
        break;
4909
#endif
4910
#ifdef TARGET_NR_mlock
4911
    case TARGET_NR_mlock:
4912
        ret = get_errno(mlock(g2h(arg1), arg2));
4913
        break;
4914
#endif
4915
#ifdef TARGET_NR_munlock
4916
    case TARGET_NR_munlock:
4917
        ret = get_errno(munlock(g2h(arg1), arg2));
4918
        break;
4919
#endif
4920
#ifdef TARGET_NR_mlockall
4921
    case TARGET_NR_mlockall:
4922
        ret = get_errno(mlockall(arg1));
4923
        break;
4924
#endif
4925
#ifdef TARGET_NR_munlockall
4926
    case TARGET_NR_munlockall:
4927
        ret = get_errno(munlockall());
4928
        break;
4929
#endif
4930
    case TARGET_NR_truncate:
4931
        if (!(p = lock_user_string(arg1)))
4932
            goto efault;
4933
        ret = get_errno(truncate(p, arg2));
4934
        unlock_user(p, arg1, 0);
4935
        break;
4936
    case TARGET_NR_ftruncate:
4937
        ret = get_errno(ftruncate(arg1, arg2));
4938
        break;
4939
    case TARGET_NR_fchmod:
4940
        ret = get_errno(fchmod(arg1, arg2));
4941
        break;
4942
#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
4943
    case TARGET_NR_fchmodat:
4944
        if (!(p = lock_user_string(arg2)))
4945
            goto efault;
4946
        ret = get_errno(sys_fchmodat(arg1, p, arg3));
4947
        unlock_user(p, arg2, 0);
4948
        break;
4949
#endif
4950
    case TARGET_NR_getpriority:
4951
        /* libc does special remapping of the return value of
4952
         * sys_getpriority() so it's just easiest to call
4953
         * sys_getpriority() directly rather than through libc. */
4954
        ret = sys_getpriority(arg1, arg2);
4955
        break;
4956
    case TARGET_NR_setpriority:
4957
        ret = get_errno(setpriority(arg1, arg2, arg3));
4958
        break;
4959
#ifdef TARGET_NR_profil
4960
    case TARGET_NR_profil:
4961
        goto unimplemented;
4962
#endif
4963
    case TARGET_NR_statfs:
4964
        if (!(p = lock_user_string(arg1)))
4965
            goto efault;
4966
        ret = get_errno(statfs(path(p), &stfs));
4967
        unlock_user(p, arg1, 0);
4968
    convert_statfs:
4969
        if (!is_error(ret)) {
4970
            struct target_statfs *target_stfs;
4971

    
4972
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
4973
                goto efault;
4974
            __put_user(stfs.f_type, &target_stfs->f_type);
4975
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4976
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4977
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4978
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4979
            __put_user(stfs.f_files, &target_stfs->f_files);
4980
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4981
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4982
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4983
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4984
            unlock_user_struct(target_stfs, arg2, 1);
4985
        }
4986
        break;
4987
    case TARGET_NR_fstatfs:
4988
        ret = get_errno(fstatfs(arg1, &stfs));
4989
        goto convert_statfs;
4990
#ifdef TARGET_NR_statfs64
4991
    case TARGET_NR_statfs64:
4992
        if (!(p = lock_user_string(arg1)))
4993
            goto efault;
4994
        ret = get_errno(statfs(path(p), &stfs));
4995
        unlock_user(p, arg1, 0);
4996
    convert_statfs64:
4997
        if (!is_error(ret)) {
4998
            struct target_statfs64 *target_stfs;
4999

    
5000
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
5001
                goto efault;
5002
            __put_user(stfs.f_type, &target_stfs->f_type);
5003
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
5004
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
5005
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
5006
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
5007
            __put_user(stfs.f_files, &target_stfs->f_files);
5008
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
5009
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
5010
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
5011
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
5012
            unlock_user_struct(target_stfs, arg3, 1);
5013
        }
5014
        break;
5015
    case TARGET_NR_fstatfs64:
5016
        ret = get_errno(fstatfs(arg1, &stfs));
5017
        goto convert_statfs64;
5018
#endif
5019
#ifdef TARGET_NR_ioperm
5020
    case TARGET_NR_ioperm:
5021
        goto unimplemented;
5022
#endif
5023
#ifdef TARGET_NR_socketcall
5024
    case TARGET_NR_socketcall:
5025
        ret = do_socketcall(arg1, arg2);
5026
        break;
5027
#endif
5028
#ifdef TARGET_NR_accept
5029
    case TARGET_NR_accept:
5030
        ret = do_accept(arg1, arg2, arg3);
5031
        break;
5032
#endif
5033
#ifdef TARGET_NR_bind
5034
    case TARGET_NR_bind:
5035
        ret = do_bind(arg1, arg2, arg3);
5036
        break;
5037
#endif
5038
#ifdef TARGET_NR_connect
5039
    case TARGET_NR_connect:
5040
        ret = do_connect(arg1, arg2, arg3);
5041
        break;
5042
#endif
5043
#ifdef TARGET_NR_getpeername
5044
    case TARGET_NR_getpeername:
5045
        ret = do_getpeername(arg1, arg2, arg3);
5046
        break;
5047
#endif
5048
#ifdef TARGET_NR_getsockname
5049
    case TARGET_NR_getsockname:
5050
        ret = do_getsockname(arg1, arg2, arg3);
5051
        break;
5052
#endif
5053
#ifdef TARGET_NR_getsockopt
5054
    case TARGET_NR_getsockopt:
5055
        ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
5056
        break;
5057
#endif
5058
#ifdef TARGET_NR_listen
5059
    case TARGET_NR_listen:
5060
        ret = get_errno(listen(arg1, arg2));
5061
        break;
5062
#endif
5063
#ifdef TARGET_NR_recv
5064
    case TARGET_NR_recv:
5065
        ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
5066
        break;
5067
#endif
5068
#ifdef TARGET_NR_recvfrom
5069
    case TARGET_NR_recvfrom:
5070
        ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
5071
        break;
5072
#endif
5073
#ifdef TARGET_NR_recvmsg
5074
    case TARGET_NR_recvmsg:
5075
        ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
5076
        break;
5077
#endif
5078
#ifdef TARGET_NR_send
5079
    case TARGET_NR_send:
5080
        ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
5081
        break;
5082
#endif
5083
#ifdef TARGET_NR_sendmsg
5084
    case TARGET_NR_sendmsg:
5085
        ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
5086
        break;
5087
#endif
5088
#ifdef TARGET_NR_sendto
5089
    case TARGET_NR_sendto:
5090
        ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
5091
        break;
5092
#endif
5093
#ifdef TARGET_NR_shutdown
5094
    case TARGET_NR_shutdown:
5095
        ret = get_errno(shutdown(arg1, arg2));
5096
        break;
5097
#endif
5098
#ifdef TARGET_NR_socket
5099
    case TARGET_NR_socket:
5100
        ret = do_socket(arg1, arg2, arg3);
5101
        break;
5102
#endif
5103
#ifdef TARGET_NR_socketpair
5104
    case TARGET_NR_socketpair:
5105
        ret = do_socketpair(arg1, arg2, arg3, arg4);
5106
        break;
5107
#endif
5108
#ifdef TARGET_NR_setsockopt
5109
    case TARGET_NR_setsockopt:
5110
        ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
5111
        break;
5112
#endif
5113

    
5114
    case TARGET_NR_syslog:
5115
        if (!(p = lock_user_string(arg2)))
5116
            goto efault;
5117
        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
5118
        unlock_user(p, arg2, 0);
5119
        break;
5120

    
5121
    case TARGET_NR_setitimer:
5122
        {
5123
            struct itimerval value, ovalue, *pvalue;
5124

    
5125
            if (arg2) {
5126
                pvalue = &value;
5127
                if (copy_from_user_timeval(&pvalue->it_interval, arg2)
5128
                    || copy_from_user_timeval(&pvalue->it_value,
5129
                                              arg2 + sizeof(struct target_timeval)))
5130
                    goto efault;
5131
            } else {
5132
                pvalue = NULL;
5133
            }
5134
            ret = get_errno(setitimer(arg1, pvalue, &ovalue));
5135
            if (!is_error(ret) && arg3) {
5136
                if (copy_to_user_timeval(arg3,
5137
                                         &ovalue.it_interval)
5138
                    || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
5139
                                            &ovalue.it_value))
5140
                    goto efault;
5141
            }
5142
        }
5143
        break;
5144
    case TARGET_NR_getitimer:
5145
        {
5146
            struct itimerval value;
5147

    
5148
            ret = get_errno(getitimer(arg1, &value));
5149
            if (!is_error(ret) && arg2) {
5150
                if (copy_to_user_timeval(arg2,
5151
                                         &value.it_interval)
5152
                    || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
5153
                                            &value.it_value))
5154
                    goto efault;
5155
            }
5156
        }
5157
        break;
5158
    case TARGET_NR_stat:
5159
        if (!(p = lock_user_string(arg1)))
5160
            goto efault;
5161
        ret = get_errno(stat(path(p), &st));
5162
        unlock_user(p, arg1, 0);
5163
        goto do_stat;
5164
    case TARGET_NR_lstat:
5165
        if (!(p = lock_user_string(arg1)))
5166
            goto efault;
5167
        ret = get_errno(lstat(path(p), &st));
5168
        unlock_user(p, arg1, 0);
5169
        goto do_stat;
5170
    case TARGET_NR_fstat:
5171
        {
5172
            ret = get_errno(fstat(arg1, &st));
5173
        do_stat:
5174
            if (!is_error(ret)) {
5175
                struct target_stat *target_st;
5176

    
5177
                if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
5178
                    goto efault;
5179
                __put_user(st.st_dev, &target_st->st_dev);
5180
                __put_user(st.st_ino, &target_st->st_ino);
5181
                __put_user(st.st_mode, &target_st->st_mode);
5182
                __put_user(st.st_uid, &target_st->st_uid);
5183
                __put_user(st.st_gid, &target_st->st_gid);
5184
                __put_user(st.st_nlink, &target_st->st_nlink);
5185
                __put_user(st.st_rdev, &target_st->st_rdev);
5186
                __put_user(st.st_size, &target_st->st_size);
5187
                __put_user(st.st_blksize, &target_st->st_blksize);
5188
                __put_user(st.st_blocks, &target_st->st_blocks);
5189
                __put_user(st.st_atime, &target_st->target_st_atime);
5190
                __put_user(st.st_mtime, &target_st->target_st_mtime);
5191
                __put_user(st.st_ctime, &target_st->target_st_ctime);
5192
                unlock_user_struct(target_st, arg2, 1);
5193
            }
5194
        }
5195
        break;
5196
#ifdef TARGET_NR_olduname
5197
    case TARGET_NR_olduname:
5198
        goto unimplemented;
5199
#endif
5200
#ifdef TARGET_NR_iopl
5201
    case TARGET_NR_iopl:
5202
        goto unimplemented;
5203
#endif
5204
    case TARGET_NR_vhangup:
5205
        ret = get_errno(vhangup());
5206
        break;
5207
#ifdef TARGET_NR_idle
5208
    case TARGET_NR_idle:
5209
        goto unimplemented;
5210
#endif
5211
#ifdef TARGET_NR_syscall
5212
    case TARGET_NR_syscall:
5213
            ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
5214
            break;
5215
#endif
5216
    case TARGET_NR_wait4:
5217
        {
5218
            int status;
5219
            abi_long status_ptr = arg2;
5220
            struct rusage rusage, *rusage_ptr;
5221
            abi_ulong target_rusage = arg4;
5222
            if (target_rusage)
5223
                rusage_ptr = &rusage;
5224
            else
5225
                rusage_ptr = NULL;
5226
            ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
5227
            if (!is_error(ret)) {
5228
                if (status_ptr) {
5229
                    status = host_to_target_waitstatus(status);
5230
                    if (put_user_s32(status, status_ptr))
5231
                        goto efault;
5232
                }
5233
                if (target_rusage)
5234
                    host_to_target_rusage(target_rusage, &rusage);
5235
            }
5236
        }
5237
        break;
5238
#ifdef TARGET_NR_swapoff
5239
    case TARGET_NR_swapoff:
5240
        if (!(p = lock_user_string(arg1)))
5241
            goto efault;
5242
        ret = get_errno(swapoff(p));
5243
        unlock_user(p, arg1, 0);
5244
        break;
5245
#endif
5246
    case TARGET_NR_sysinfo:
5247
        {
5248
            struct target_sysinfo *target_value;
5249
            struct sysinfo value;
5250
            ret = get_errno(sysinfo(&value));
5251
            if (!is_error(ret) && arg1)
5252
            {
5253
                if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
5254
                    goto efault;
5255
                __put_user(value.uptime, &target_value->uptime);
5256
                __put_user(value.loads[0], &target_value->loads[0]);
5257
                __put_user(value.loads[1], &target_value->loads[1]);
5258
                __put_user(value.loads[2], &target_value->loads[2]);
5259
                __put_user(value.totalram, &target_value->totalram);
5260
                __put_user(value.freeram, &target_value->freeram);
5261
                __put_user(value.sharedram, &target_value->sharedram);
5262
                __put_user(value.bufferram, &target_value->bufferram);
5263
                __put_user(value.totalswap, &target_value->totalswap);
5264
                __put_user(value.freeswap, &target_value->freeswap);
5265
                __put_user(value.procs, &target_value->procs);
5266
                __put_user(value.totalhigh, &target_value->totalhigh);
5267
                __put_user(value.freehigh, &target_value->freehigh);
5268
                __put_user(value.mem_unit, &target_value->mem_unit);
5269
                unlock_user_struct(target_value, arg1, 1);
5270
            }
5271
        }
5272
        break;
5273
#ifdef TARGET_NR_ipc
5274
    case TARGET_NR_ipc:
5275
        ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
5276
        break;
5277
#endif
5278
#ifdef TARGET_NR_semget
5279
    case TARGET_NR_semget:
5280
        ret = get_errno(semget(arg1, arg2, arg3));
5281
        break;
5282
#endif
5283
#ifdef TARGET_NR_semop
5284
    case TARGET_NR_semop:
5285
        ret = get_errno(do_semop(arg1, arg2, arg3));
5286
        break;
5287
#endif
5288
#ifdef TARGET_NR_semctl
5289
    case TARGET_NR_semctl:
5290
        ret = do_semctl(arg1, arg2, arg3, (union target_semun)(abi_ulong)arg4);
5291
        break;
5292
#endif
5293
#ifdef TARGET_NR_msgctl
5294
    case TARGET_NR_msgctl:
5295
        ret = do_msgctl(arg1, arg2, arg3);
5296
        break;
5297
#endif
5298
#ifdef TARGET_NR_msgget
5299
    case TARGET_NR_msgget:
5300
        ret = get_errno(msgget(arg1, arg2));
5301
        break;
5302
#endif
5303
#ifdef TARGET_NR_msgrcv
5304
    case TARGET_NR_msgrcv:
5305
        ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
5306
        break;
5307
#endif
5308
#ifdef TARGET_NR_msgsnd
5309
    case TARGET_NR_msgsnd:
5310
        ret = do_msgsnd(arg1, arg2, arg3, arg4);
5311
        break;
5312
#endif
5313
    case TARGET_NR_fsync:
5314
        ret = get_errno(fsync(arg1));
5315
        break;
5316
    case TARGET_NR_clone:
5317
#if defined(TARGET_SH4)
5318
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
5319
#elif defined(TARGET_CRIS)
5320
        ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg4, arg5));
5321
#else
5322
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
5323
#endif
5324
        break;
5325
#ifdef __NR_exit_group
5326
        /* new thread calls */
5327
    case TARGET_NR_exit_group:
5328
#ifdef HAVE_GPROF
5329
        _mcleanup();
5330
#endif
5331
        gdb_exit(cpu_env, arg1);
5332
        ret = get_errno(exit_group(arg1));
5333
        break;
5334
#endif
5335
    case TARGET_NR_setdomainname:
5336
        if (!(p = lock_user_string(arg1)))
5337
            goto efault;
5338
        ret = get_errno(setdomainname(p, arg2));
5339
        unlock_user(p, arg1, 0);
5340
        break;
5341
    case TARGET_NR_uname:
5342
        /* no need to transcode because we use the linux syscall */
5343
        {
5344
            struct new_utsname * buf;
5345

    
5346
            if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
5347
                goto efault;
5348
            ret = get_errno(sys_uname(buf));
5349
            if (!is_error(ret)) {
5350
                /* Overrite the native machine name with whatever is being
5351
                   emulated. */
5352
                strcpy (buf->machine, UNAME_MACHINE);
5353
                /* Allow the user to override the reported release.  */
5354
                if (qemu_uname_release && *qemu_uname_release)
5355
                  strcpy (buf->release, qemu_uname_release);
5356
            }
5357
            unlock_user_struct(buf, arg1, 1);
5358
        }
5359
        break;
5360
#ifdef TARGET_I386
5361
    case TARGET_NR_modify_ldt:
5362
        ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
5363
        break;
5364
#if !defined(TARGET_X86_64)
5365
    case TARGET_NR_vm86old:
5366
        goto unimplemented;
5367
    case TARGET_NR_vm86:
5368
        ret = do_vm86(cpu_env, arg1, arg2);
5369
        break;
5370
#endif
5371
#endif
5372
    case TARGET_NR_adjtimex:
5373
        goto unimplemented;
5374
#ifdef TARGET_NR_create_module
5375
    case TARGET_NR_create_module:
5376
#endif
5377
    case TARGET_NR_init_module:
5378
    case TARGET_NR_delete_module:
5379
#ifdef TARGET_NR_get_kernel_syms
5380
    case TARGET_NR_get_kernel_syms:
5381
#endif
5382
        goto unimplemented;
5383
    case TARGET_NR_quotactl:
5384
        goto unimplemented;
5385
    case TARGET_NR_getpgid:
5386
        ret = get_errno(getpgid(arg1));
5387
        break;
5388
    case TARGET_NR_fchdir:
5389
        ret = get_errno(fchdir(arg1));
5390
        break;
5391
#ifdef TARGET_NR_bdflush /* not on x86_64 */
5392
    case TARGET_NR_bdflush:
5393
        goto unimplemented;
5394
#endif
5395
#ifdef TARGET_NR_sysfs
5396
    case TARGET_NR_sysfs:
5397
        goto unimplemented;
5398
#endif
5399
    case TARGET_NR_personality:
5400
        ret = get_errno(personality(arg1));
5401
        break;
5402
#ifdef TARGET_NR_afs_syscall
5403
    case TARGET_NR_afs_syscall:
5404
        goto unimplemented;
5405
#endif
5406
#ifdef TARGET_NR__llseek /* Not on alpha */
5407
    case TARGET_NR__llseek:
5408
        {
5409
#if defined (__x86_64__)
5410
            ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
5411
            if (put_user_s64(ret, arg4))
5412
                goto efault;
5413
#else
5414
            int64_t res;
5415
            ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
5416
            if (put_user_s64(res, arg4))
5417
                goto efault;
5418
#endif
5419
        }
5420
        break;
5421
#endif
5422
    case TARGET_NR_getdents:
5423
#if TARGET_ABI_BITS != 32
5424
        goto unimplemented;
5425
#elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
5426
        {
5427
            struct target_dirent *target_dirp;
5428
            struct linux_dirent *dirp;
5429
            abi_long count = arg3;
5430

    
5431
            dirp = malloc(count);
5432
            if (!dirp) {
5433
                ret = -TARGET_ENOMEM;
5434
                goto fail;
5435
            }
5436

    
5437
            ret = get_errno(sys_getdents(arg1, dirp, count));
5438
            if (!is_error(ret)) {
5439
                struct linux_dirent *de;
5440
                struct target_dirent *tde;
5441
                int len = ret;
5442
                int reclen, treclen;
5443
                int count1, tnamelen;
5444

    
5445
                count1 = 0;
5446
                de = dirp;
5447
                if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5448
                    goto efault;
5449
                tde = target_dirp;
5450
                while (len > 0) {
5451
                    reclen = de->d_reclen;
5452
                    treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
5453
                    tde->d_reclen = tswap16(treclen);
5454
                    tde->d_ino = tswapl(de->d_ino);
5455
                    tde->d_off = tswapl(de->d_off);
5456
                    tnamelen = treclen - (2 * sizeof(abi_long) + 2);
5457
                    if (tnamelen > 256)
5458
                        tnamelen = 256;
5459
                    /* XXX: may not be correct */
5460
                    pstrcpy(tde->d_name, tnamelen, de->d_name);
5461
                    de = (struct linux_dirent *)((char *)de + reclen);
5462
                    len -= reclen;
5463
                    tde = (struct target_dirent *)((char *)tde + treclen);
5464
                    count1 += treclen;
5465
                }
5466
                ret = count1;
5467
                unlock_user(target_dirp, arg2, ret);
5468
            }
5469
            free(dirp);
5470
        }
5471
#else
5472
        {
5473
            struct linux_dirent *dirp;
5474
            abi_long count = arg3;
5475

    
5476
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5477
                goto efault;
5478
            ret = get_errno(sys_getdents(arg1, dirp, count));
5479
            if (!is_error(ret)) {
5480
                struct linux_dirent *de;
5481
                int len = ret;
5482
                int reclen;
5483
                de = dirp;
5484
                while (len > 0) {
5485
                    reclen = de->d_reclen;
5486
                    if (reclen > len)
5487
                        break;
5488
                    de->d_reclen = tswap16(reclen);
5489
                    tswapls(&de->d_ino);
5490
                    tswapls(&de->d_off);
5491
                    de = (struct linux_dirent *)((char *)de + reclen);
5492
                    len -= reclen;
5493
                }
5494
            }
5495
            unlock_user(dirp, arg2, ret);
5496
        }
5497
#endif
5498
        break;
5499
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
5500
    case TARGET_NR_getdents64:
5501
        {
5502
            struct linux_dirent64 *dirp;
5503
            abi_long count = arg3;
5504
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5505
                goto efault;
5506
            ret = get_errno(sys_getdents64(arg1, dirp, count));
5507
            if (!is_error(ret)) {
5508
                struct linux_dirent64 *de;
5509
                int len = ret;
5510
                int reclen;
5511
                de = dirp;
5512
                while (len > 0) {
5513
                    reclen = de->d_reclen;
5514
                    if (reclen > len)
5515
                        break;
5516
                    de->d_reclen = tswap16(reclen);
5517
                    tswap64s((uint64_t *)&de->d_ino);
5518
                    tswap64s((uint64_t *)&de->d_off);
5519
                    de = (struct linux_dirent64 *)((char *)de + reclen);
5520
                    len -= reclen;
5521
                }
5522
            }
5523
            unlock_user(dirp, arg2, ret);
5524
        }
5525
        break;
5526
#endif /* TARGET_NR_getdents64 */
5527
#ifdef TARGET_NR__newselect
5528
    case TARGET_NR__newselect:
5529
        ret = do_select(arg1, arg2, arg3, arg4, arg5);
5530
        break;
5531
#endif
5532
#ifdef TARGET_NR_poll
5533
    case TARGET_NR_poll:
5534
        {
5535
            struct target_pollfd *target_pfd;
5536
            unsigned int nfds = arg2;
5537
            int timeout = arg3;
5538
            struct pollfd *pfd;
5539
            unsigned int i;
5540

    
5541
            target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
5542
            if (!target_pfd)
5543
                goto efault;
5544
            pfd = alloca(sizeof(struct pollfd) * nfds);
5545
            for(i = 0; i < nfds; i++) {
5546
                pfd[i].fd = tswap32(target_pfd[i].fd);
5547
                pfd[i].events = tswap16(target_pfd[i].events);
5548
            }
5549
            ret = get_errno(poll(pfd, nfds, timeout));
5550
            if (!is_error(ret)) {
5551
                for(i = 0; i < nfds; i++) {
5552
                    target_pfd[i].revents = tswap16(pfd[i].revents);
5553
                }
5554
                ret += nfds * (sizeof(struct target_pollfd)
5555
                               - sizeof(struct pollfd));
5556
            }
5557
            unlock_user(target_pfd, arg1, ret);
5558
        }
5559
        break;
5560
#endif
5561
    case TARGET_NR_flock:
5562
        /* NOTE: the flock constant seems to be the same for every
5563
           Linux platform */
5564
        ret = get_errno(flock(arg1, arg2));
5565
        break;
5566
    case TARGET_NR_readv:
5567
        {
5568
            int count = arg3;
5569
            struct iovec *vec;
5570

    
5571
            vec = alloca(count * sizeof(struct iovec));
5572
            if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
5573
                goto efault;
5574
            ret = get_errno(readv(arg1, vec, count));
5575
            unlock_iovec(vec, arg2, count, 1);
5576
        }
5577
        break;
5578
    case TARGET_NR_writev:
5579
        {
5580
            int count = arg3;
5581
            struct iovec *vec;
5582

    
5583
            vec = alloca(count * sizeof(struct iovec));
5584
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
5585
                goto efault;
5586
            ret = get_errno(writev(arg1, vec, count));
5587
            unlock_iovec(vec, arg2, count, 0);
5588
        }
5589
        break;
5590
    case TARGET_NR_getsid:
5591
        ret = get_errno(getsid(arg1));
5592
        break;
5593
#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
5594
    case TARGET_NR_fdatasync:
5595
        ret = get_errno(fdatasync(arg1));
5596
        break;
5597
#endif
5598
    case TARGET_NR__sysctl:
5599
        /* We don't implement this, but ENOTDIR is always a safe
5600
           return value. */
5601
        ret = -TARGET_ENOTDIR;
5602
        break;
5603
    case TARGET_NR_sched_setparam:
5604
        {
5605
            struct sched_param *target_schp;
5606
            struct sched_param schp;
5607

    
5608
            if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
5609
                goto efault;
5610
            schp.sched_priority = tswap32(target_schp->sched_priority);
5611
            unlock_user_struct(target_schp, arg2, 0);
5612
            ret = get_errno(sched_setparam(arg1, &schp));
5613
        }
5614
        break;
5615
    case TARGET_NR_sched_getparam:
5616
        {
5617
            struct sched_param *target_schp;
5618
            struct sched_param schp;
5619
            ret = get_errno(sched_getparam(arg1, &schp));
5620
            if (!is_error(ret)) {
5621
                if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
5622
                    goto efault;
5623
                target_schp->sched_priority = tswap32(schp.sched_priority);
5624
                unlock_user_struct(target_schp, arg2, 1);
5625
            }
5626
        }
5627
        break;
5628
    case TARGET_NR_sched_setscheduler:
5629
        {
5630
            struct sched_param *target_schp;
5631
            struct sched_param schp;
5632
            if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
5633
                goto efault;
5634
            schp.sched_priority = tswap32(target_schp->sched_priority);
5635
            unlock_user_struct(target_schp, arg3, 0);
5636
            ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
5637
        }
5638
        break;
5639
    case TARGET_NR_sched_getscheduler:
5640
        ret = get_errno(sched_getscheduler(arg1));
5641
        break;
5642
    case TARGET_NR_sched_yield:
5643
        ret = get_errno(sched_yield());
5644
        break;
5645
    case TARGET_NR_sched_get_priority_max:
5646
        ret = get_errno(sched_get_priority_max(arg1));
5647
        break;
5648
    case TARGET_NR_sched_get_priority_min:
5649
        ret = get_errno(sched_get_priority_min(arg1));
5650
        break;
5651
    case TARGET_NR_sched_rr_get_interval:
5652
        {
5653
            struct timespec ts;
5654
            ret = get_errno(sched_rr_get_interval(arg1, &ts));
5655
            if (!is_error(ret)) {
5656
                host_to_target_timespec(arg2, &ts);
5657
            }
5658
        }
5659
        break;
5660
    case TARGET_NR_nanosleep:
5661
        {
5662
            struct timespec req, rem;
5663
            target_to_host_timespec(&req, arg1);
5664
            ret = get_errno(nanosleep(&req, &rem));
5665
            if (is_error(ret) && arg2) {
5666
                host_to_target_timespec(arg2, &rem);
5667
            }
5668
        }
5669
        break;
5670
#ifdef TARGET_NR_query_module
5671
    case TARGET_NR_query_module:
5672
        goto unimplemented;
5673
#endif
5674
#ifdef TARGET_NR_nfsservctl
5675
    case TARGET_NR_nfsservctl:
5676
        goto unimplemented;
5677
#endif
5678
    case TARGET_NR_prctl:
5679
        switch (arg1)
5680
            {
5681
            case PR_GET_PDEATHSIG:
5682
                {
5683
                    int deathsig;
5684
                    ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
5685
                    if (!is_error(ret) && arg2
5686
                        && put_user_ual(deathsig, arg2))
5687
                        goto efault;
5688
                }
5689
                break;
5690
            default:
5691
                ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
5692
                break;
5693
            }
5694
        break;
5695
#ifdef TARGET_NR_arch_prctl
5696
    case TARGET_NR_arch_prctl:
5697
#if defined(TARGET_I386) && !defined(TARGET_ABI32)
5698
        ret = do_arch_prctl(cpu_env, arg1, arg2);
5699
        break;
5700
#else
5701
        goto unimplemented;
5702
#endif
5703
#endif
5704
#ifdef TARGET_NR_pread
5705
    case TARGET_NR_pread:
5706
#ifdef TARGET_ARM
5707
        if (((CPUARMState *)cpu_env)->eabi)
5708
            arg4 = arg5;
5709
#endif
5710
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5711
            goto efault;
5712
        ret = get_errno(pread(arg1, p, arg3, arg4));
5713
        unlock_user(p, arg2, ret);
5714
        break;
5715
    case TARGET_NR_pwrite:
5716
#ifdef TARGET_ARM
5717
        if (((CPUARMState *)cpu_env)->eabi)
5718
            arg4 = arg5;
5719
#endif
5720
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5721
            goto efault;
5722
        ret = get_errno(pwrite(arg1, p, arg3, arg4));
5723
        unlock_user(p, arg2, 0);
5724
        break;
5725
#endif
5726
#ifdef TARGET_NR_pread64
5727
    case TARGET_NR_pread64:
5728
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5729
            goto efault;
5730
        ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
5731
        unlock_user(p, arg2, ret);
5732
        break;
5733
    case TARGET_NR_pwrite64:
5734
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5735
            goto efault;
5736
        ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
5737
        unlock_user(p, arg2, 0);
5738
        break;
5739
#endif
5740
    case TARGET_NR_getcwd:
5741
        if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
5742
            goto efault;
5743
        ret = get_errno(sys_getcwd1(p, arg2));
5744
        unlock_user(p, arg1, ret);
5745
        break;
5746
    case TARGET_NR_capget:
5747
        goto unimplemented;
5748
    case TARGET_NR_capset:
5749
        goto unimplemented;
5750
    case TARGET_NR_sigaltstack:
5751
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
5752
    defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA)
5753
        ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env));
5754
        break;
5755
#else
5756
        goto unimplemented;
5757
#endif
5758
    case TARGET_NR_sendfile:
5759
        goto unimplemented;
5760
#ifdef TARGET_NR_getpmsg
5761
    case TARGET_NR_getpmsg:
5762
        goto unimplemented;
5763
#endif
5764
#ifdef TARGET_NR_putpmsg
5765
    case TARGET_NR_putpmsg:
5766
        goto unimplemented;
5767
#endif
5768
#ifdef TARGET_NR_vfork
5769
    case TARGET_NR_vfork:
5770
        ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
5771
                        0, 0, 0, 0));
5772
        break;
5773
#endif
5774
#ifdef TARGET_NR_ugetrlimit
5775
    case TARGET_NR_ugetrlimit:
5776
    {
5777
        struct rlimit rlim;
5778
        ret = get_errno(getrlimit(arg1, &rlim));
5779
        if (!is_error(ret)) {
5780
            struct target_rlimit *target_rlim;
5781
            if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
5782
                goto efault;
5783
            target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
5784
            target_rlim->rlim_max = tswapl(rlim.rlim_max);
5785
            unlock_user_struct(target_rlim, arg2, 1);
5786
        }
5787
        break;
5788
    }
5789
#endif
5790
#ifdef TARGET_NR_truncate64
5791
    case TARGET_NR_truncate64:
5792
        if (!(p = lock_user_string(arg1)))
5793
            goto efault;
5794
        ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
5795
        unlock_user(p, arg1, 0);
5796
        break;
5797
#endif
5798
#ifdef TARGET_NR_ftruncate64
5799
    case TARGET_NR_ftruncate64:
5800
        ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
5801
        break;
5802
#endif
5803
#ifdef TARGET_NR_stat64
5804
    case TARGET_NR_stat64:
5805
        if (!(p = lock_user_string(arg1)))
5806
            goto efault;
5807
        ret = get_errno(stat(path(p), &st));
5808
        unlock_user(p, arg1, 0);
5809
        if (!is_error(ret))
5810
            ret = host_to_target_stat64(cpu_env, arg2, &st);
5811
        break;
5812
#endif
5813
#ifdef TARGET_NR_lstat64
5814
    case TARGET_NR_lstat64:
5815
        if (!(p = lock_user_string(arg1)))
5816
            goto efault;
5817
        ret = get_errno(lstat(path(p), &st));
5818
        unlock_user(p, arg1, 0);
5819
        if (!is_error(ret))
5820
            ret = host_to_target_stat64(cpu_env, arg2, &st);
5821
        break;
5822
#endif
5823
#ifdef TARGET_NR_fstat64
5824
    case TARGET_NR_fstat64:
5825
        ret = get_errno(fstat(arg1, &st));
5826
        if (!is_error(ret))
5827
            ret = host_to_target_stat64(cpu_env, arg2, &st);
5828
        break;
5829
#endif
5830
#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
5831
        (defined(__NR_fstatat64) || defined(__NR_newfstatat))
5832
#ifdef TARGET_NR_fstatat64
5833
    case TARGET_NR_fstatat64:
5834
#endif
5835
#ifdef TARGET_NR_newfstatat
5836
    case TARGET_NR_newfstatat:
5837
#endif
5838
        if (!(p = lock_user_string(arg2)))
5839
            goto efault;
5840
#ifdef __NR_fstatat64
5841
        ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
5842
#else
5843
        ret = get_errno(sys_newfstatat(arg1, path(p), &st, arg4));
5844
#endif
5845
        if (!is_error(ret))
5846
            ret = host_to_target_stat64(cpu_env, arg3, &st);
5847
        break;
5848
#endif
5849
#ifdef USE_UID16
5850
    case TARGET_NR_lchown:
5851
        if (!(p = lock_user_string(arg1)))
5852
            goto efault;
5853
        ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
5854
        unlock_user(p, arg1, 0);
5855
        break;
5856
    case TARGET_NR_getuid:
5857
        ret = get_errno(high2lowuid(getuid()));
5858
        break;
5859
    case TARGET_NR_getgid:
5860
        ret = get_errno(high2lowgid(getgid()));
5861
        break;
5862
    case TARGET_NR_geteuid:
5863
        ret = get_errno(high2lowuid(geteuid()));
5864
        break;
5865
    case TARGET_NR_getegid:
5866
        ret = get_errno(high2lowgid(getegid()));
5867
        break;
5868
    case TARGET_NR_setreuid:
5869
        ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
5870
        break;
5871
    case TARGET_NR_setregid:
5872
        ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
5873
        break;
5874
    case TARGET_NR_getgroups:
5875
        {
5876
            int gidsetsize = arg1;
5877
            uint16_t *target_grouplist;
5878
            gid_t *grouplist;
5879
            int i;
5880

    
5881
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5882
            ret = get_errno(getgroups(gidsetsize, grouplist));
5883
            if (gidsetsize == 0)
5884
                break;
5885
            if (!is_error(ret)) {
5886
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
5887
                if (!target_grouplist)
5888
                    goto efault;
5889
                for(i = 0;i < ret; i++)
5890
                    target_grouplist[i] = tswap16(grouplist[i]);
5891
                unlock_user(target_grouplist, arg2, gidsetsize * 2);
5892
            }
5893
        }
5894
        break;
5895
    case TARGET_NR_setgroups:
5896
        {
5897
            int gidsetsize = arg1;
5898
            uint16_t *target_grouplist;
5899
            gid_t *grouplist;
5900
            int i;
5901

    
5902
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5903
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
5904
            if (!target_grouplist) {
5905
                ret = -TARGET_EFAULT;
5906
                goto fail;
5907
            }
5908
            for(i = 0;i < gidsetsize; i++)
5909
                grouplist[i] = tswap16(target_grouplist[i]);
5910
            unlock_user(target_grouplist, arg2, 0);
5911
            ret = get_errno(setgroups(gidsetsize, grouplist));
5912
        }
5913
        break;
5914
    case TARGET_NR_fchown:
5915
        ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
5916
        break;
5917
#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
5918
    case TARGET_NR_fchownat:
5919
        if (!(p = lock_user_string(arg2))) 
5920
            goto efault;
5921
        ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
5922
        unlock_user(p, arg2, 0);
5923
        break;
5924
#endif
5925
#ifdef TARGET_NR_setresuid
5926
    case TARGET_NR_setresuid:
5927
        ret = get_errno(setresuid(low2highuid(arg1),
5928
                                  low2highuid(arg2),
5929
                                  low2highuid(arg3)));
5930
        break;
5931
#endif
5932
#ifdef TARGET_NR_getresuid
5933
    case TARGET_NR_getresuid:
5934
        {
5935
            uid_t ruid, euid, suid;
5936
            ret = get_errno(getresuid(&ruid, &euid, &suid));
5937
            if (!is_error(ret)) {
5938
                if (put_user_u16(high2lowuid(ruid), arg1)
5939
                    || put_user_u16(high2lowuid(euid), arg2)
5940
                    || put_user_u16(high2lowuid(suid), arg3))
5941
                    goto efault;
5942
            }
5943
        }
5944
        break;
5945
#endif
5946
#ifdef TARGET_NR_getresgid
5947
    case TARGET_NR_setresgid:
5948
        ret = get_errno(setresgid(low2highgid(arg1),
5949
                                  low2highgid(arg2),
5950
                                  low2highgid(arg3)));
5951
        break;
5952
#endif
5953
#ifdef TARGET_NR_getresgid
5954
    case TARGET_NR_getresgid:
5955
        {
5956
            gid_t rgid, egid, sgid;
5957
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
5958
            if (!is_error(ret)) {
5959
                if (put_user_u16(high2lowgid(rgid), arg1)
5960
                    || put_user_u16(high2lowgid(egid), arg2)
5961
                    || put_user_u16(high2lowgid(sgid), arg3))
5962
                    goto efault;
5963
            }
5964
        }
5965
        break;
5966
#endif
5967
    case TARGET_NR_chown:
5968
        if (!(p = lock_user_string(arg1)))
5969
            goto efault;
5970
        ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
5971
        unlock_user(p, arg1, 0);
5972
        break;
5973
    case TARGET_NR_setuid:
5974
        ret = get_errno(setuid(low2highuid(arg1)));
5975
        break;
5976
    case TARGET_NR_setgid:
5977
        ret = get_errno(setgid(low2highgid(arg1)));
5978
        break;
5979
    case TARGET_NR_setfsuid:
5980
        ret = get_errno(setfsuid(arg1));
5981
        break;
5982
    case TARGET_NR_setfsgid:
5983
        ret = get_errno(setfsgid(arg1));
5984
        break;
5985
#endif /* USE_UID16 */
5986

    
5987
#ifdef TARGET_NR_lchown32
5988
    case TARGET_NR_lchown32:
5989
        if (!(p = lock_user_string(arg1)))
5990
            goto efault;
5991
        ret = get_errno(lchown(p, arg2, arg3));
5992
        unlock_user(p, arg1, 0);
5993
        break;
5994
#endif
5995
#ifdef TARGET_NR_getuid32
5996
    case TARGET_NR_getuid32:
5997
        ret = get_errno(getuid());
5998
        break;
5999
#endif
6000

    
6001
#if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
6002
   /* Alpha specific */
6003
    case TARGET_NR_getxuid:
6004
         {
6005
            uid_t euid;
6006
            euid=geteuid();
6007
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
6008
         }
6009
        ret = get_errno(getuid());
6010
        break;
6011
#endif
6012
#if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
6013
   /* Alpha specific */
6014
    case TARGET_NR_getxgid:
6015
         {
6016
            uid_t egid;
6017
            egid=getegid();
6018
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
6019
         }
6020
        ret = get_errno(getgid());
6021
        break;
6022
#endif
6023

    
6024
#ifdef TARGET_NR_getgid32
6025
    case TARGET_NR_getgid32:
6026
        ret = get_errno(getgid());
6027
        break;
6028
#endif
6029
#ifdef TARGET_NR_geteuid32
6030
    case TARGET_NR_geteuid32:
6031
        ret = get_errno(geteuid());
6032
        break;
6033
#endif
6034
#ifdef TARGET_NR_getegid32
6035
    case TARGET_NR_getegid32:
6036
        ret = get_errno(getegid());
6037
        break;
6038
#endif
6039
#ifdef TARGET_NR_setreuid32
6040
    case TARGET_NR_setreuid32:
6041
        ret = get_errno(setreuid(arg1, arg2));
6042
        break;
6043
#endif
6044
#ifdef TARGET_NR_setregid32
6045
    case TARGET_NR_setregid32:
6046
        ret = get_errno(setregid(arg1, arg2));
6047
        break;
6048
#endif
6049
#ifdef TARGET_NR_getgroups32
6050
    case TARGET_NR_getgroups32:
6051
        {
6052
            int gidsetsize = arg1;
6053
            uint32_t *target_grouplist;
6054
            gid_t *grouplist;
6055
            int i;
6056

    
6057
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6058
            ret = get_errno(getgroups(gidsetsize, grouplist));
6059
            if (gidsetsize == 0)
6060
                break;
6061
            if (!is_error(ret)) {
6062
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
6063
                if (!target_grouplist) {
6064
                    ret = -TARGET_EFAULT;
6065
                    goto fail;
6066
                }
6067
                for(i = 0;i < ret; i++)
6068
                    target_grouplist[i] = tswap32(grouplist[i]);
6069
                unlock_user(target_grouplist, arg2, gidsetsize * 4);
6070
            }
6071
        }
6072
        break;
6073
#endif
6074
#ifdef TARGET_NR_setgroups32
6075
    case TARGET_NR_setgroups32:
6076
        {
6077
            int gidsetsize = arg1;
6078
            uint32_t *target_grouplist;
6079
            gid_t *grouplist;
6080
            int i;
6081

    
6082
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6083
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
6084
            if (!target_grouplist) {
6085
                ret = -TARGET_EFAULT;
6086
                goto fail;
6087
            }
6088
            for(i = 0;i < gidsetsize; i++)
6089
                grouplist[i] = tswap32(target_grouplist[i]);
6090
            unlock_user(target_grouplist, arg2, 0);
6091
            ret = get_errno(setgroups(gidsetsize, grouplist));
6092
        }
6093
        break;
6094
#endif
6095
#ifdef TARGET_NR_fchown32
6096
    case TARGET_NR_fchown32:
6097
        ret = get_errno(fchown(arg1, arg2, arg3));
6098
        break;
6099
#endif
6100
#ifdef TARGET_NR_setresuid32
6101
    case TARGET_NR_setresuid32:
6102
        ret = get_errno(setresuid(arg1, arg2, arg3));
6103
        break;
6104
#endif
6105
#ifdef TARGET_NR_getresuid32
6106
    case TARGET_NR_getresuid32:
6107
        {
6108
            uid_t ruid, euid, suid;
6109
            ret = get_errno(getresuid(&ruid, &euid, &suid));
6110
            if (!is_error(ret)) {
6111
                if (put_user_u32(ruid, arg1)
6112
                    || put_user_u32(euid, arg2)
6113
                    || put_user_u32(suid, arg3))
6114
                    goto efault;
6115
            }
6116
        }
6117
        break;
6118
#endif
6119
#ifdef TARGET_NR_setresgid32
6120
    case TARGET_NR_setresgid32:
6121
        ret = get_errno(setresgid(arg1, arg2, arg3));
6122
        break;
6123
#endif
6124
#ifdef TARGET_NR_getresgid32
6125
    case TARGET_NR_getresgid32:
6126
        {
6127
            gid_t rgid, egid, sgid;
6128
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
6129
            if (!is_error(ret)) {
6130
                if (put_user_u32(rgid, arg1)
6131
                    || put_user_u32(egid, arg2)
6132
                    || put_user_u32(sgid, arg3))
6133
                    goto efault;
6134
            }
6135
        }
6136
        break;
6137
#endif
6138
#ifdef TARGET_NR_chown32
6139
    case TARGET_NR_chown32:
6140
        if (!(p = lock_user_string(arg1)))
6141
            goto efault;
6142
        ret = get_errno(chown(p, arg2, arg3));
6143
        unlock_user(p, arg1, 0);
6144
        break;
6145
#endif
6146
#ifdef TARGET_NR_setuid32
6147
    case TARGET_NR_setuid32:
6148
        ret = get_errno(setuid(arg1));
6149
        break;
6150
#endif
6151
#ifdef TARGET_NR_setgid32
6152
    case TARGET_NR_setgid32:
6153
        ret = get_errno(setgid(arg1));
6154
        break;
6155
#endif
6156
#ifdef TARGET_NR_setfsuid32
6157
    case TARGET_NR_setfsuid32:
6158
        ret = get_errno(setfsuid(arg1));
6159
        break;
6160
#endif
6161
#ifdef TARGET_NR_setfsgid32
6162
    case TARGET_NR_setfsgid32:
6163
        ret = get_errno(setfsgid(arg1));
6164
        break;
6165
#endif
6166

    
6167
    case TARGET_NR_pivot_root:
6168
        goto unimplemented;
6169
#ifdef TARGET_NR_mincore
6170
    case TARGET_NR_mincore:
6171
        {
6172
            void *a;
6173
            ret = -TARGET_EFAULT;
6174
            if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
6175
                goto efault;
6176
            if (!(p = lock_user_string(arg3)))
6177
                goto mincore_fail;
6178
            ret = get_errno(mincore(a, arg2, p));
6179
            unlock_user(p, arg3, ret);
6180
            mincore_fail:
6181
            unlock_user(a, arg1, 0);
6182
        }
6183
        break;
6184
#endif
6185
#ifdef TARGET_NR_arm_fadvise64_64
6186
    case TARGET_NR_arm_fadvise64_64:
6187
        {
6188
                /*
6189
                 * arm_fadvise64_64 looks like fadvise64_64 but
6190
                 * with different argument order
6191
                 */
6192
                abi_long temp;
6193
                temp = arg3;
6194
                arg3 = arg4;
6195
                arg4 = temp;
6196
        }
6197
#endif
6198
#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64)
6199
#ifdef TARGET_NR_fadvise64_64
6200
    case TARGET_NR_fadvise64_64:
6201
#endif
6202
        /* This is a hint, so ignoring and returning success is ok.  */
6203
        ret = get_errno(0);
6204
        break;
6205
#endif
6206
#ifdef TARGET_NR_madvise
6207
    case TARGET_NR_madvise:
6208
        /* A straight passthrough may not be safe because qemu sometimes
6209
           turns private flie-backed mappings into anonymous mappings.
6210
           This will break MADV_DONTNEED.
6211
           This is a hint, so ignoring and returning success is ok.  */
6212
        ret = get_errno(0);
6213
        break;
6214
#endif
6215
#if TARGET_ABI_BITS == 32
6216
    case TARGET_NR_fcntl64:
6217
    {
6218
        int cmd;
6219
        struct flock64 fl;
6220
        struct target_flock64 *target_fl;
6221
#ifdef TARGET_ARM
6222
        struct target_eabi_flock64 *target_efl;
6223
#endif
6224

    
6225
        switch(arg2){
6226
        case TARGET_F_GETLK64:
6227
            cmd = F_GETLK64;
6228
            break;
6229
        case TARGET_F_SETLK64:
6230
            cmd = F_SETLK64;
6231
            break;
6232
        case TARGET_F_SETLKW64:
6233
            cmd = F_SETLK64;
6234
            break;
6235
        default:
6236
            cmd = arg2;
6237
            break;
6238
        }
6239

    
6240
        switch(arg2) {
6241
        case TARGET_F_GETLK64:
6242
#ifdef TARGET_ARM
6243
            if (((CPUARMState *)cpu_env)->eabi) {
6244
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
6245
                    goto efault;
6246
                fl.l_type = tswap16(target_efl->l_type);
6247
                fl.l_whence = tswap16(target_efl->l_whence);
6248
                fl.l_start = tswap64(target_efl->l_start);
6249
                fl.l_len = tswap64(target_efl->l_len);
6250
                fl.l_pid = tswapl(target_efl->l_pid);
6251
                unlock_user_struct(target_efl, arg3, 0);
6252
            } else
6253
#endif
6254
            {
6255
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
6256
                    goto efault;
6257
                fl.l_type = tswap16(target_fl->l_type);
6258
                fl.l_whence = tswap16(target_fl->l_whence);
6259
                fl.l_start = tswap64(target_fl->l_start);
6260
                fl.l_len = tswap64(target_fl->l_len);
6261
                fl.l_pid = tswapl(target_fl->l_pid);
6262
                unlock_user_struct(target_fl, arg3, 0);
6263
            }
6264
            ret = get_errno(fcntl(arg1, cmd, &fl));
6265
            if (ret == 0) {
6266
#ifdef TARGET_ARM
6267
                if (((CPUARMState *)cpu_env)->eabi) {
6268
                    if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) 
6269
                        goto efault;
6270
                    target_efl->l_type = tswap16(fl.l_type);
6271
                    target_efl->l_whence = tswap16(fl.l_whence);
6272
                    target_efl->l_start = tswap64(fl.l_start);
6273
                    target_efl->l_len = tswap64(fl.l_len);
6274
                    target_efl->l_pid = tswapl(fl.l_pid);
6275
                    unlock_user_struct(target_efl, arg3, 1);
6276
                } else
6277
#endif
6278
                {
6279
                    if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) 
6280
                        goto efault;
6281
                    target_fl->l_type = tswap16(fl.l_type);
6282
                    target_fl->l_whence = tswap16(fl.l_whence);
6283
                    target_fl->l_start = tswap64(fl.l_start);
6284
                    target_fl->l_len = tswap64(fl.l_len);
6285
                    target_fl->l_pid = tswapl(fl.l_pid);
6286
                    unlock_user_struct(target_fl, arg3, 1);
6287
                }
6288
            }
6289
            break;
6290

    
6291
        case TARGET_F_SETLK64:
6292
        case TARGET_F_SETLKW64:
6293
#ifdef TARGET_ARM
6294
            if (((CPUARMState *)cpu_env)->eabi) {
6295
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
6296
                    goto efault;
6297
                fl.l_type = tswap16(target_efl->l_type);
6298
                fl.l_whence = tswap16(target_efl->l_whence);
6299
                fl.l_start = tswap64(target_efl->l_start);
6300
                fl.l_len = tswap64(target_efl->l_len);
6301
                fl.l_pid = tswapl(target_efl->l_pid);
6302
                unlock_user_struct(target_efl, arg3, 0);
6303
            } else
6304
#endif
6305
            {
6306
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
6307
                    goto efault;
6308
                fl.l_type = tswap16(target_fl->l_type);
6309
                fl.l_whence = tswap16(target_fl->l_whence);
6310
                fl.l_start = tswap64(target_fl->l_start);
6311
                fl.l_len = tswap64(target_fl->l_len);
6312
                fl.l_pid = tswapl(target_fl->l_pid);
6313
                unlock_user_struct(target_fl, arg3, 0);
6314
            }
6315
            ret = get_errno(fcntl(arg1, cmd, &fl));
6316
            break;
6317
        default:
6318
            ret = do_fcntl(arg1, cmd, arg3);
6319
            break;
6320
        }
6321
        break;
6322
    }
6323
#endif
6324
#ifdef TARGET_NR_cacheflush
6325
    case TARGET_NR_cacheflush:
6326
        /* self-modifying code is handled automatically, so nothing needed */
6327
        ret = 0;
6328
        break;
6329
#endif
6330
#ifdef TARGET_NR_security
6331
    case TARGET_NR_security:
6332
        goto unimplemented;
6333
#endif
6334
#ifdef TARGET_NR_getpagesize
6335
    case TARGET_NR_getpagesize:
6336
        ret = TARGET_PAGE_SIZE;
6337
        break;
6338
#endif
6339
    case TARGET_NR_gettid:
6340
        ret = get_errno(gettid());
6341
        break;
6342
#ifdef TARGET_NR_readahead
6343
    case TARGET_NR_readahead:
6344
#if TARGET_ABI_BITS == 32
6345
#ifdef TARGET_ARM
6346
        if (((CPUARMState *)cpu_env)->eabi)
6347
        {
6348
            arg2 = arg3;
6349
            arg3 = arg4;
6350
            arg4 = arg5;
6351
        }
6352
#endif
6353
        ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
6354
#else
6355
        ret = get_errno(readahead(arg1, arg2, arg3));
6356
#endif
6357
        break;
6358
#endif
6359
#ifdef TARGET_NR_setxattr
6360
    case TARGET_NR_setxattr:
6361
    case TARGET_NR_lsetxattr:
6362
    case TARGET_NR_fsetxattr:
6363
    case TARGET_NR_getxattr:
6364
    case TARGET_NR_lgetxattr:
6365
    case TARGET_NR_fgetxattr:
6366
    case TARGET_NR_listxattr:
6367
    case TARGET_NR_llistxattr:
6368
    case TARGET_NR_flistxattr:
6369
    case TARGET_NR_removexattr:
6370
    case TARGET_NR_lremovexattr:
6371
    case TARGET_NR_fremovexattr:
6372
        goto unimplemented_nowarn;
6373
#endif
6374
#ifdef TARGET_NR_set_thread_area
6375
    case TARGET_NR_set_thread_area:
6376
#if defined(TARGET_MIPS)
6377
      ((CPUMIPSState *) cpu_env)->tls_value = arg1;
6378
      ret = 0;
6379
      break;
6380
#elif defined(TARGET_CRIS)
6381
      if (arg1 & 0xff)
6382
          ret = -TARGET_EINVAL;
6383
      else {
6384
          ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
6385
          ret = 0;
6386
      }
6387
      break;
6388
#elif defined(TARGET_I386) && defined(TARGET_ABI32)
6389
      ret = do_set_thread_area(cpu_env, arg1);
6390
      break;
6391
#else
6392
      goto unimplemented_nowarn;
6393
#endif
6394
#endif
6395
#ifdef TARGET_NR_get_thread_area
6396
    case TARGET_NR_get_thread_area:
6397
#if defined(TARGET_I386) && defined(TARGET_ABI32)
6398
        ret = do_get_thread_area(cpu_env, arg1);
6399
#else
6400
        goto unimplemented_nowarn;
6401
#endif
6402
#endif
6403
#ifdef TARGET_NR_getdomainname
6404
    case TARGET_NR_getdomainname:
6405
        goto unimplemented_nowarn;
6406
#endif
6407

    
6408
#ifdef TARGET_NR_clock_gettime
6409
    case TARGET_NR_clock_gettime:
6410
    {
6411
        struct timespec ts;
6412
        ret = get_errno(clock_gettime(arg1, &ts));
6413
        if (!is_error(ret)) {
6414
            host_to_target_timespec(arg2, &ts);
6415
        }
6416
        break;
6417
    }
6418
#endif
6419
#ifdef TARGET_NR_clock_getres
6420
    case TARGET_NR_clock_getres:
6421
    {
6422
        struct timespec ts;
6423
        ret = get_errno(clock_getres(arg1, &ts));
6424
        if (!is_error(ret)) {
6425
            host_to_target_timespec(arg2, &ts);
6426
        }
6427
        break;
6428
    }
6429
#endif
6430
#ifdef TARGET_NR_clock_nanosleep
6431
    case TARGET_NR_clock_nanosleep:
6432
    {
6433
        struct timespec ts;
6434
        target_to_host_timespec(&ts, arg3);
6435
        ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
6436
        if (arg4)
6437
            host_to_target_timespec(arg4, &ts);
6438
        break;
6439
    }
6440
#endif
6441

    
6442
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
6443
    case TARGET_NR_set_tid_address:
6444
        ret = get_errno(set_tid_address((int *)g2h(arg1)));
6445
        break;
6446
#endif
6447

    
6448
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
6449
    case TARGET_NR_tkill:
6450
        ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
6451
        break;
6452
#endif
6453

    
6454
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
6455
    case TARGET_NR_tgkill:
6456
        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
6457
                        target_to_host_signal(arg3)));
6458
        break;
6459
#endif
6460

    
6461
#ifdef TARGET_NR_set_robust_list
6462
    case TARGET_NR_set_robust_list:
6463
        goto unimplemented_nowarn;
6464
#endif
6465

    
6466
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
6467
    case TARGET_NR_utimensat:
6468
        {
6469
            struct timespec ts[2];
6470
            target_to_host_timespec(ts, arg3);
6471
            target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
6472
            if (!arg2)
6473
                ret = get_errno(sys_utimensat(arg1, NULL, ts, arg4));
6474
            else {
6475
                if (!(p = lock_user_string(arg2))) {
6476
                    ret = -TARGET_EFAULT;
6477
                    goto fail;
6478
                }
6479
                ret = get_errno(sys_utimensat(arg1, path(p), ts, arg4));
6480
                unlock_user(p, arg2, 0);
6481
            }
6482
        }
6483
        break;
6484
#endif
6485
#if defined(USE_NPTL)
6486
    case TARGET_NR_futex:
6487
        ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
6488
        break;
6489
#endif
6490
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
6491
    case TARGET_NR_inotify_init:
6492
        ret = get_errno(sys_inotify_init());
6493
        break;
6494
#endif
6495
#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
6496
    case TARGET_NR_inotify_add_watch:
6497
        p = lock_user_string(arg2);
6498
        ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
6499
        unlock_user(p, arg2, 0);
6500
        break;
6501
#endif
6502
#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
6503
    case TARGET_NR_inotify_rm_watch:
6504
        ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
6505
        break;
6506
#endif
6507

    
6508
#ifdef TARGET_NR_mq_open
6509
    case TARGET_NR_mq_open:
6510
        {
6511
            struct mq_attr posix_mq_attr;
6512

    
6513
            p = lock_user_string(arg1 - 1);
6514
            if (arg4 != 0)
6515
                copy_from_user_mq_attr (&posix_mq_attr, arg4);
6516
            ret = get_errno(mq_open(p, arg2, arg3, &posix_mq_attr));
6517
            unlock_user (p, arg1, 0);
6518
        }
6519
        break;
6520

    
6521
    case TARGET_NR_mq_unlink:
6522
        p = lock_user_string(arg1 - 1);
6523
        ret = get_errno(mq_unlink(p));
6524
        unlock_user (p, arg1, 0);
6525
        break;
6526

    
6527
    case TARGET_NR_mq_timedsend:
6528
        {
6529
            struct timespec ts;
6530

    
6531
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
6532
            if (arg5 != 0) {
6533
                target_to_host_timespec(&ts, arg5);
6534
                ret = get_errno(mq_timedsend(arg1, p, arg3, arg4, &ts));
6535
                host_to_target_timespec(arg5, &ts);
6536
            }
6537
            else
6538
                ret = get_errno(mq_send(arg1, p, arg3, arg4));
6539
            unlock_user (p, arg2, arg3);
6540
        }
6541
        break;
6542

    
6543
    case TARGET_NR_mq_timedreceive:
6544
        {
6545
            struct timespec ts;
6546
            unsigned int prio;
6547

    
6548
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
6549
            if (arg5 != 0) {
6550
                target_to_host_timespec(&ts, arg5);
6551
                ret = get_errno(mq_timedreceive(arg1, p, arg3, &prio, &ts));
6552
                host_to_target_timespec(arg5, &ts);
6553
            }
6554
            else
6555
                ret = get_errno(mq_receive(arg1, p, arg3, &prio));
6556
            unlock_user (p, arg2, arg3);
6557
            if (arg4 != 0)
6558
                put_user_u32(prio, arg4);
6559
        }
6560
        break;
6561

    
6562
    /* Not implemented for now... */
6563
/*     case TARGET_NR_mq_notify: */
6564
/*         break; */
6565

    
6566
    case TARGET_NR_mq_getsetattr:
6567
        {
6568
            struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
6569
            ret = 0;
6570
            if (arg3 != 0) {
6571
                ret = mq_getattr(arg1, &posix_mq_attr_out);
6572
                copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
6573
            }
6574
            if (arg2 != 0) {
6575
                copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
6576
                ret |= mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_attr_out);
6577
            }
6578

    
6579
        }
6580
        break;
6581
#endif
6582

    
6583
    default:
6584
    unimplemented:
6585
        gemu_log("qemu: Unsupported syscall: %d\n", num);
6586
#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
6587
    unimplemented_nowarn:
6588
#endif
6589
        ret = -TARGET_ENOSYS;
6590
        break;
6591
    }
6592
fail:
6593
#ifdef DEBUG
6594
    gemu_log(" = %ld\n", ret);
6595
#endif
6596
    if(do_strace)
6597
        print_syscall_ret(num, ret);
6598
    return ret;
6599
efault:
6600
    ret = -TARGET_EFAULT;
6601
    goto fail;
6602
}